动画

135 阅读4分钟

先看几个例子

较少动画

丰富的动画

动画的优势

  1. 提升用户体验:动画能让用户在浏览网页时有更好的体验,例如加载动画能让用户在等待内容加载的过程中不觉得无聊,交互动画能让用户明确自己的操作反馈。

  2. 提升网站设计感:一个静态的网页和一个动态的网页相比,后者显得更有设计感、更有活力,能让用户对网站有更好的印象。

  3. 引导用户注意力:动画能有效地引导用户的注意力,让用户更关注我们希望他们关注的内容。

  4. 提供流畅的过渡效果:动画能让页面间的过渡更加自然、流畅,而不是突兀的跳转,例如界面的切换

  5. 创造丰富的交互体验:通过动画,可以创造出更丰富、更多样化的交互操作,提升用户的参与度和互动性。

  6. 在故事讲述和品牌塑造方面有独特效果:通过动画,可以更生动、有趣地传达信息,帮助品牌故事的表达和品牌形象的塑造。

动画的劣势

  1. 加载时间增长:在网页中添加动画会增加web页面的负载,这意味着网页的加载时间会变长,这可能会影响用户的体验,特别是在网络连接较差或者设备硬件较旧的情况下。

  2. 分散注意力:过多或者过于花哨的动画可能会分散用户的注意力,使其无法专注于内容或者找到他们在网页上的需要的信息。

  3. 兼容性问题:虽然现在的浏览器对于动画支持已经越来越好,但还是有一些老旧的或者特定的浏览器可能无法准确地展示动画效果。

  4. 可访问性问题:对于一些有视力障碍或认知障碍的用户来说,动画可能会让他们更难以理解和使用网页。

  5. 增加开发和维护成本:动画的设计、开发和维护往往需要更多的时间和资源。

  6. 因为动画特性及其错综复杂的效果,这可能引起网站的测试和调试变得更复杂。因为必须确保动画在各种浏览器和设备上都能正确运行。

总结

总的来说,虽然动画可以让网站显得更加生动有趣,但也需要考虑其可能带来的问题,以确保在动画和用户体验之间找到一个平衡点

那在我们日常开发中如何平衡?

thinking.png

在前端中的动画

GIF

<img src="./images/sample.gif">

gif.gif

SVG

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
  <circle cx="12" cy="2" r="0" fill="currentColor">
    <animate attributeName="r" begin="0" calcMode="spline" dur="1s" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" repeatCount="indefinite" values="0;2;0;0"/>
  </circle>
  <circle cx="12" cy="2" r="0" fill="currentColor" transform="rotate(45 12 12)">
    <animate attributeName="r" begin="0.125s" calcMode="spline" dur="1s" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" repeatCount="indefinite" values="0;2;0;0"/>
  </circle>
  <circle cx="12" cy="2" r="0" fill="currentColor" transform="rotate(90 12 12)">
    <animate attributeName="r" begin="0.25s" calcMode="spline" dur="1s" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" repeatCount="indefinite" values="0;2;0;0"/>
  </circle>
  <circle cx="12" cy="2" r="0" fill="currentColor" transform="rotate(135 12 12)">
    <animate attributeName="r" begin="0.375s" calcMode="spline" dur="1s" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" repeatCount="indefinite" values="0;2;0;0"/>
  </circle>
  <circle cx="12" cy="2" r="0" fill="currentColor" transform="rotate(180 12 12)">
    <animate attributeName="r" begin="0.5s" calcMode="spline" dur="1s" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" repeatCount="indefinite" values="0;2;0;0"/>
  </circle>
  ...
</svg>

效果

JS

let id: number | null = null
const myMove = () => {
 const elem = document.getElementById("myAnimation");
 let pos = 0;
 const frame = () => {
  if (pos == 350) {
   id && clearInterval(id);
  } else {
   pos++;
   elem && (elem.style.left = pos + 'px');
  }
 }
 id && clearInterval(id);
 id = setInterval(frame, 10);
}

效果

JS + Canvas

<canvas id="clock" width="400" height="400"></canvas>

<script>
  // ...
  setInterval(() => {
    ctx.save();
    ctx.clearRect(0, 0, 2 * r, 2 * r);
    drawclock();

    let date = new Date();
    let hour = date.getHours();
    if (hour - 12 > 0) {
      hour -= 12;
    }
    let minute = date.getMinutes();
    let seconds = date.getSeconds();

    drawHour(hour, minute);
    drawMinute(minute);
    drawSecond(seconds);
    ctx.restore();
  }, 1000);
</script>

效果

Canvas + WebGL

/*********
 * made by Matthias Hurrle (@atzedent)
 */
const canvas = window.canvas
const gl = canvas.getContext("webgl2")
// ...
function loop(now) {
    draw(now)
    requestAnimationFrame(loop)
}

function init() {
    setup()
    resize()
    loop(0)
}

来源->codepen

效果

CSS

// ...
@keyframes snow {
    0% {transform: translateY(-20vh);}
    100% {transform: translateY(100vh);}
}
@keyframes snow-man {
    0%,
    100% {
      transform: translateX(0%);
      transform-origin: 50% 50%;
    }
    15% {transform: translateX(-30px) rotate(-6deg);}
    30% {transform: translateX(15px) rotate(6deg);}
    45% {transform: translateX(-15px) rotate(-3.6deg);}
    60% {transform: translateX(9px) rotate(2.4deg);}
    75% { transform: translateX(-6px) rotate(-1.2deg);}
}

来源-codepen

效果

动画库

CSS动画

与动画密切相关的两个属性:

  1. transition
  2. animate

transition

个人认为是实现动画成本最低、最快速的一种方式

语法:

transition: transition-property transition-duration transition-timing-function transition-delay

按钮

transition: all 400ms cubic-bezier(0.4, 0, 0.2, 1);

transition-timing-function

linear(匀速): cubic-bezier(0.0, 0.0, 1.0, 1.0)

linear

  • linear(0, 0.25, 1)
  • linear(0, 0.25 75%, 1)
  • linear(0, 0.25 25% 75%, 1)

linear.png

linear1.png

效果

linear

还可以更多

linear(0, 0.218 2.1%, 0.862 6.5%, 1.114, 1.296 10.7%, 1.346, 1.37 12.9%, 1.373, 1.364 14.5%, 1.315 16.2%, 1.032 21.8%, 0.941 24%, 0.891 25.9%, 0.877, 0.869 27.8%, 0.87, 0.882 30.7%, 0.907 32.4%, 0.981 36.4%, 1.012 38.3%, 1.036,1.046 42.7% 44.1%, 1.042 45.7%, 0.996 53.3%, 0.988, 0.984 57.5%, 0.985 60.7%,1.001 68.1%, 1.006 72.2%, 0.998 86.7%, 1)

效果

目前还存在兼容性问题,不建议直接上生产

transition-timing-function

ease(默认值,逐渐加速,快要结束的时候减速的过渡效果)

ease-in(先慢后快)、ease-out(先快后慢)、ease-in-out(先慢后快再减速)

ease、ease-in、ease-out、ease-in-out

  • ease: cubic-bezier(0.25, 0.1, 0.25, 1.0)
  • ease-in: cubic-bezier(0.42, 0, 1.0, 1.0)
  • ease-out: cubic-bezier(0, 0, 0.58, 1.0)
  • ease-in-out: cubic-bezier(0.42, 0, 0.58, 1.0)

ease与ease-in-out两者差不多,差异是一开始的加速度

ease.png

贝塞尔曲线

可以参考

总结
  • linear: 一次贝塞尔
  • ease-in、ease-out: 两次贝塞尔
  • ease、ease-in-out: 三次贝塞尔

steps

  • step-start: 等同于steps(1, step-start),动画开始时发生跳转
  • step-end: 等同于steps(1, step-end),动画结束时发生跳转
  • steps(5, jump-none):分5步进行,不跳最后一步
  • steps(5, jump-both):分6步进行,跳最后一步

更多

可以在浏览器中直接调试或者查看

timeFunc.png

animation

animation: name duration timing-function delay iteration-count direction fill-mode play-state timeline

  • timing-function: 与transition-timing-function一致
  • iteration-count: 循环次数,允许小数
  • play-state: 动画暂停或者继续,paused、running
  • timeline: 兼容性存在问题,暂时不展开介绍

animation-name

@keyframes
@keyframes slidein {
  from {
    transform: translateX(0%);
  }

  to {
    transform: translateX(100%);
  }
}
@keyframes identifier {
  0% {
    top: 0;
    left: 0;
  }
  30% {
    top: 50px;
  }
  68%,
  72% {
    left: 50px;
  }
  100% {
    top: 100px;
    left: 100%;
  }
}

fill-mode

完结

ending.png