50 Projects 50 Days - Rotating Navigation Animation 学习记录

本文记录了50 Days 50 Projects 中的旋转导航动画实现过程。通过HTML、CSS和JavaScript,实现了一个点击按钮后,内容区和按钮圆盘绕左上角旋转,同时导航栏在左侧显示和隐藏的效果。关键点包括CSS的旋转中心设定、角度计算以及JavaScript的交互逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目地址

Rotating Navigation Animation

展示效果

Rotating Navigation Animation
在这里插入图片描述

实现思路

结构主要分为两部分,绕左上角旋转的部分:包括按钮圆盘和内容区,以及左下角移出的导航栏部分。

整个界面只在左上角圆盘的按钮点击时发生改变,而且这种改变只有两种状态:旋转内容和转盘并显示导航栏、内容和转盘归位并隐藏导航栏。因此可以考虑添加一个class属性的方式实现效果,而这个class属性会分别作用在几个需要改变的元素上。

  1. 点击按钮后旋转,圆盘和内容都绕左上角作为原点进行旋转,可以考虑将两部分放到一个父盒子里,通过添加show-nav属性改变样式
  2. 圆盘和内容旋转的角度略有不同,圆盘要转动90度,而内容转动只有20度,所以整体应该是选择20度,而圆盘再额外旋转70度
  3. 导航栏在设计好布局后,先全部移动到页面左侧隐藏区域,在需要显示时再移动回来

实现细节

HTML结构

案例中用到了一些按钮的图标,这些图标来自于font-awesome库中,这里直接在head中声明cdn地址进行引用,在页面加载时会自动载入图标样式。

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
    integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog=="
    crossorigin="anonymous" />
  <link rel="stylesheet" href="style.css" />
  <title>Rotating Navigation</title>
</head>

按钮圆盘和正文内容放到一个container里面,原案例中圆盘外面还包了一层fixed的circle-container,然后在里面使用relative定位的circle来给按钮定位提供参考位置,不过实际上也可以不需要这样做,因为absolute定位参考的父元素位置只要是非static定位就行。不过遵循子绝父相的原则也确实是一种良好习惯。

正文文字直接用乱数假文来测试排版。

导航栏常规用列表进行排布。

<div class="container">
    <div class="circle">
      <button id="close"><i class="fas fa-times"></i></button>
      <button id="open"><i class="fas fa-bars"></i></button>
    </div>
    <div class="content">
      <h1>Amazing Article</h1>
      <small>Florin Pop</small>
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quia in ratione dolores cupiditate, maxime
        aliquid impedit dolorem nam dolor omnis atque fuga labore modi veritatis porro laborum minus, illo, maiores
        recusandae cumque ipsa quos. Tenetur, consequuntur mollitia labore pariatur sunt quia harum aut. Eum maxime
        dolorem provident natus veritatis molestiae cumque quod voluptates ab non, tempore cupiditate? Voluptatem,
        molestias culpa. Corrupti, laudantium iure aliquam rerum sint nam quas dolor dignissimos in error placeat quae
        temporibus minus optio eum soluta cupiditate! Cupiditate saepe voluptates laudantium. Ducimus consequuntur
        perferendis consequatur nobis exercitationem molestias fugiat commodi omnis. Asperiores quia tenetur nemo ipsa.
      </p>
      <h3>My Dog</h3>
      <img
        src="https://images.unsplash.com/photo-1507146426996-ef05306b995a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2100&q=80"
        alt="doggy" />
      <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sit libero deleniti rerum quo, incidunt vel
        consequatur culpa ullam. Magnam facere earum unde harum. Ea culpa veritatis magnam at aliquid. Perferendis totam
        placeat molestias illo laudantium? Minus id minima doloribus dolorum fugit deserunt qui vero voluptas, ut quia
        cum amet temporibus veniam ad ea ab perspiciatis, enim accusamus asperiores explicabo provident. Voluptates
        sint, neque fuga cum illum, tempore autem maxime similique laborum odio, magnam esse. Aperiam?</p>
    </div>
  </div>
  <nav>
    <ul>
      <li><i class="fas fa-home"></i><a href="#"> Home</a></li>
      <li><i class="fas fa-user-alt"></i><a href="#">About</a></li>
      <li><i class="fas fa-envelope"></i><a href="#">Contact</a></li>
    </ul>
  </nav>

CSS样式

container

容器样式定义盒子内容为全屏显示(去除滚动条),以及旋转变换的原点为左上角
容器带上show-nav的class后整体逆时针旋转20度

.container{
  background-color: #fafafa;
  padding: 50px;
  height: 100vh;
  transform-origin: left top;
  transition: transform 0.5s linear;
}

转盘

首先设置尺寸来实现圆盘的外观,转盘本身的位置应该是脱离container的文档流,固定在左上角,通过设置偏移来控制在页面中只显示右下角部分。
但是设置偏移量会导致body整体向下移动,顶部会有100px的空区,这会导致之后旋转的原点下移,最终的效果就不一致了。此时设置padding值可以将整个body撑开(这里其实还没完全搞清楚)

.circle{
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background-color: #ff7979;
  position: fixed;
  left: -100px;
  top: -100px;
  transition: transform 0.5s linear;
}

转盘上两个按钮设置为转盘半径大小,并通过设置偏移让两个按钮恰好显示在右下角圆弧的正中间。同时也定义旋转原点同样是左上角。

.circle button{
  height: 100px;
  background: transparent;
  border: 0;
  font-size: 26px;
  color: #fff;
  position: absolute;
  left: 50%;
  top: 50%;
  cursor: pointer;
  transform-origin: left top;
}

然后是对两个按钮的位置进行一些微调,关闭按钮逆时针旋转90度隐藏到页面左边。

.circle #open{
  left: 60%;
}

.circle #close{
  transform: rotate(90deg);
  top: 60%; 
}

最后当容器有show-nav的class后,转盘在跟随容器旋转20度的基础上,再旋转70度。

.container.show-nav .circle {
  transform: rotate(-70deg);
}

内容区

首先内容整体需要做一些宽度限制,或者至少图片应该做一些宽度限制。
这里需要注意的是

.content {
  max-width: 1000px;
  background-color: #fafafa;
  margin: 50px auto;
}

.content img {
  width: 100%;
}

.content h1 {
  margin: 0;
}

.content small {
  color: #555;
  font-style: italic;
}

.content p {
  color: #333;
  line-height: 1.5;
}

导航栏

导航栏部分固定位置在左下角,去除无序列表的默认样式。

表格的三项根据从上往下依次向右偏移一定距离,在隐藏时也对应需要向左移动更多的距离,当兄弟节点容器有show-nav的class后,将所有列表项的移动距离清零来达到导航栏出现的效果。

.container.show-nav + nav li {
  transform: translate(0);
}

nav {
  position: fixed;
  bottom: 40px;
  left: 0px;
  z-index: 1000;
}

nav ul {
  list-style: none;
  padding-left: 30px;
}

nav ul li {
  color: #fff;
  margin: 30px 0;
  transform: translateX(-100%);
  transition: transform 0.4s ease-in;
}

nav ul li i {
  font-size: 20px;
  margin-right: 10px;
}

nav ul li + li {
  margin-left: 15px;
  transform: translateX(-150%);
}

nav ul li + li + li {
  margin-left: 30px;
  transform: translateX(-200%);
}

nav a {
  text-decoration: none;
  color:#fff;
  transition: all 0.5s;
}

nav a:hover {
  color:#ff7979;
  font-weight: bold;
}

JavaScript逻辑

脚本逻辑非常简单,就是给两个按钮绑定 向container元素添加/删除 show-nav 的class即可。

const container = document.querySelector('.container');
const open = document.getElementById('open');
const close = document.getElementById('close');

open.addEventListener('click', () => container.classList.add('show-nav'));
close.addEventListener('click', () => container.classList.remove('show-nav'));

总结

  1. 分析结构,需要旋转的部分放一块,只需要添加一个class即可完成所有交互效果的变换。
  2. 旋转中心为左上角,圆盘和内容角度不相同。
  3. 圆盘定位脱离container文档流,设置偏移后注意body上方的空位会影响旋转变换效果,通过设置padding值消除。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值