重学前端
程劭非(winter)
前手机淘宝前端负责人
105348 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 57 讲
开篇词+学习路线+架构图 (3讲)
重学前端
15
15
1.0x
00:00/00:00
登录|注册

CSS动画与交互:为什么动画要用贝塞尔曲线这么奇怪的东西?

transition-delay
transition-timing-function
transition-duration
transition-property
100%
75%
50%
0%
animation-direction
animation-iteration-count
animation-delay
animation-timing-function
animation-duration
animation-name
纯粹用JavaScript实现transition函数
贝塞尔曲线的实现原理和拟合技巧
CSS动画的实现原理
模拟抛物线运动的小球
generateCubicBezier函数
JavaScript实现的三次贝塞尔曲线
贝塞尔曲线的参数t
三次贝塞尔插值算法
贝塞尔曲线的定义
transition与animation组合
transition
@keyframes
animation属性和transition属性
总结
贝塞尔曲线拟合
三次贝塞尔曲线
为什么动画要用贝塞尔曲线这么奇怪的东西?
CSS动画与交互

该思维导图由 AI 生成,仅供参考

你好,我是 winter,今天我们来学习一下 CSS 的动画和交互。
在 CSS 属性中,有这么一类属性,它负责的不是静态的展现,而是根据用户行为产生交互。这就是今天我们要讲的属性。
首先我们先从属性来讲起。CSS 中跟动画相关的属性有两个:animation 和 transition。

animation 属性和 transition 属性

我们先来看下 animation 的示例,通过示例来了解一下 animation 属性的基本用法:
@keyframes mykf
{
from {background: red;}
to {background: yellow;}
}
div
{
animation:mykf 5s infinite;
}
这里展示了 animation 的基本用法,实际上 animation 分成六个部分:
animation-name 动画的名称,这是一个 keyframes 类型的值(我们在第 9 讲“CSS 语法:除了属性和选择器,你还需要知道这些带 @的规则”讲到过,keyframes 产生一种数据,用于定义动画关键帧);
animation-duration 动画的时长;
animation-timing-function 动画的时间曲线;
animation-delay 动画开始前的延迟;
animation-iteration-count 动画的播放次数;
animation-direction 动画的方向。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了CSS动画与交互属性的重要性,以及为何动画需要使用贝塞尔曲线。首先介绍了animation和transition属性的基本用法,以及它们的组成部分。随后详细介绍了动画的时间曲线,特别是三次贝塞尔曲线的应用。作者通过JavaScript代码展示了如何实现与CSS动画相似的效果,以及如何利用贝塞尔曲线来拟合抛物线运动。整体而言,本文通过介绍CSS动画和交互属性的基本用法,以及贝塞尔曲线的原理和应用,为读者提供了有益的参考和指导。文章内容深入浅出,适合技术爱好者快速了解动画与交互属性的重要性,以及贝塞尔曲线在实现流畅动画效果中的作用。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《重学前端》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(7)

  • 最新
  • 精选
  • 阿成
    const tweenFns = { linear: (from, to, t, d) => from + (to - from) * (t / d) } /** * only support "linear" timing-function * duration unit is "ms" * @param {HTMLElement} el * @param {({prop: String, value: String, duration: Number})[]} list */ function transitionTo(el, list) { let startTime let oldStyle = new Map() let newStyle = new Map() for (let prop of list) { oldStyle.set(prop.name, window.getComputedStyle(el)[prop.name]) } for (let prop of list) { el.style[prop.name] = prop.value } for (let prop of list) { newStyle.set(prop.name, window.getComputedStyle(el)[prop.name]) } for (let prop of list) { el.style[prop.name] = oldStyle.get(prop.name) } requestAnimationFrame(run) function run(time) { if (startTime == null) startTime = time let t = time - startTime let done = true for (let prop of list) { if (t >= prop.duration) { el.style[prop.name] = newStyle.get(prop.name) continue } done = false let oldPropValue = oldStyle.get(prop.name) let newPropValue = newStyle.get(prop.name) if (prop.name === 'transform') { if (oldPropValue === 'none') oldPropValue = 'matrix(1, 0, 0, 1, 0, 0)' if (newPropValue === 'none') newPropValue = 'matrix(1, 0, 0, 1, 0, 0)' } el.style[prop.name] = generateNewStyle(oldPropValue, newPropValue, t, prop.duration, tweenFns.linear) } if (!done) requestAnimationFrame(run) } } function generateNewStyle(from, to, t, duration, tweenFn) { let fromExp = /[\d.-]+/g let toExp = /[\d.-]+/g let fromMatch let toMatch let result = '' let lastIndex = 0 while (fromMatch = fromExp.exec(from)) { result += from.slice(lastIndex, fromMatch.index) toMatch = toExp.exec(to) result += tweenFn(+fromMatch[0], +toMatch[0], t, duration) lastIndex = fromExp.lastIndex } result += from.slice(lastIndex) return result }
    2019-04-20
    1
    26
  • 阿成
    跟CSS的transition比,JS更加偏向指令式,而CSS更加偏向声明式,当然,这本身也是两门语言自身的特点,CSS用法简单直观,JS则在控制方面有更大的灵活性。 上面我只实现了 linear timing function(其他的函数实现网上大把大把的...),具体用法如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> #ball { width: 100px; height: 100px; background: blue; } </style> </head> <body> <div id="ball"></div> <script src="transition.js"></script> <script> transitionTo(document.getElementById('ball'), [ {name: 'transform', duration: 1000, value: 'translate(400px, 200px) rotate(40deg)'}, {name: 'backgroundColor', duration: 1000, value: 'red'}, {name: 'width', duration: 1000, value: '200px'}, {name: 'height', duration: 1000, value: '200px'} ]) </script> </body> </html>
    2019-04-20
    3
    21
  • 许童童
    这个课后练习有点难啊。希望老师可以带着大家过一遍。
    2019-04-20
    7
  • Marvin
    // 利用老师提供的贝塞尔曲线函数 function timing_function(easing) { let resolve; if (easing === 'linear') resolve = generate(0, 0, 1, 1); else if (easing === 'ease') resolve = generate(0.25, 0.1, 0.25, 1); else if (easing === 'ease-in') resolve = generate(0.42, 0, 1, 1); else if (easing === 'ease-out') resolve = generate(0, 0, 0.58, 1); else if (easing === 'ease-in-out') resolve = generate(0.42, 0, 0.58, 1); else if (easing.indexOf('cubic-bezier') === 0) { let arr = easing.match(/(?<=\()(.*)(?=\))/)[0].split(","); arr.map(item => { return Number(item); }) resolve = generate(...arr); } else { resolve = generate(0, 0, 1, 1); } return resolve; } function transition(el, target_value, transition_property, transition_duration, transition_timing_function, transition_delay) { let start = 0; let bezier = timing_function(transition_timing_function); let scale = 1 / transition_duration; let targetArr = target_value.match(/(\d*)(.*)/); console.log(targetArr); function step(timestamp) { if (!start) start = timestamp; let progress = timestamp - start; let y = bezier(scale * progress); // y轴的比例 el.style[transition_property] = (Number(targetArr[1]) * y) + targetArr[2]; if (progress <= transition_duration)requestAnimationFrame(step); } setTimeout(() => { requestAnimationFrame(step) }, transition_delay); } let ball = document.getElementsByClassName("ball")[0]; transition(ball, "50px", "font-size", 2000, "liner", 1000);
    2020-08-03
    2
  • 剑客不能说
    一脸懵逼状态看完的~
    2019-09-27
    1
    2
  • Marvin
    不是非常严谨的实现,但是差不多了。可以设置各种属性和时间曲线。 只支持数值+单位的形式例如:left: 200px 或者 font-size: 20px; https://github.com/OleileiA/TransitionJs/blob/master/transition.html
    2020-08-03
  • zlxag
    交互没有?
    2020-06-09
收起评论
显示
设置
留言
7
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部