奇舞-javaScript 基础动画-笔记
2018-02-23 16:49
309 查看
一些动画的实现思路
先看一些实现思路
圆周运动
椭圆运动
一些复杂动画
css圆周运动
JS圆周运动
JS椭圆运动
复杂一些的动画
动画是关于事件的函数
一个反例
直线运动
<
18e5b
li>匀速运动
匀加速运动
匀减速运动
平面上的直线运动
匀速运动
匀加速直线运动
匀减速度直线运动
平面上的简单运动
斜线运动
曲线运动
圆周运动
斜线运动
圆锥曲线运动
正弦线运动
椭圆运动
圆的参数方程
连续的运动
动画的简易封装
周期和折线运动
动画队列
改良动画队列
连贯动画
弹跳和滚动
连续平滑动
对动画模型进行抽象
圆周运动
折线运动
连续的运动
弹跳的小球
改进弹跳的小球
设置阻力系数:
T’ = 0.7T
S’ = 0.49S
滚动的小球
小球被惯性甩出
摩擦力
小球加速运动100px ,匀速运动100px, 减速运动50px 后停下
动画与贝塞尔曲线
构造贝塞尔曲线
使用贝塞尔曲线实现动画
贝塞尔曲线的css3动画
cubic-bezier easing
https://github.com/gre/bezier-easing
http://cubic-bezier.com/
http://easings.net/zh-cn
贝塞尔曲线动画
贝塞尔曲线 CSS3 动画
3D动画
翻转
逐帧动画
翻转动画
逐帧动画
Web Animations API
W3C Editor’s Draft
Polyfill
总结
本课通过例子学习了实现动画的基本原理和思路
动画是关于时间的函数
动画的数学计算
动画的封装和组合动画
贝塞尔曲线
3D和序列帧动画
先看一些实现思路
圆周运动
椭圆运动
一些复杂动画
css圆周运动
//html <div id="ball"></div> //css #ball { position: absolute; width: 20px; height: 20px; background: green; border-radius: 50%; top: 100px; left: 200px; transform-origin: 10px 110px; transform: rotate(0deg); animation: roll 2s linear infinite; } @keyframes roll { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
JS圆周运动
//html <div id="ball"></div> //css #ball { position: absolute; width: 20px; height: 20px; background: green; border-radius: 50%; top: 100px; left: 200px; transform-origin: 10px 110px; } //js function startCircle(el) { let startTime = Date.now(), cycle = 2000; requestAnimationFrame(function update() { let currentTime = Date.now(); let p = (currentTime - startTime) / cycle; ball.style.transform = `rotate(${360 * p}deg)`; requestAnimationFrame(update); }) } startCircle();
JS椭圆运动
//html <div id="ball"></div> //css #ball { position: absolute; width: 20px; height: 20px; background: green; border-radius: 50%; top: 200px; left: 200px; transform: translate(0, -100px); } //js function startCircle(el) { let startTime = Date.now(), cycle = 4000, a = 160, b = 80; requestAnimationFrame(function update() { let currentTime = Date.now(), p = (currentTime - startTime) / cycle, [x, y] = [a * Math.cos(Math.PI * 2 * p), b * Math.sin(Math.PI * 2 * p)]; ball.style.transform = `translate(${x}px, ${y}px)`; requestAnimationFrame(update) }) } startCircle();
复杂一些的动画
//html <button id="playBtn">play</button> <div class="wall"></div> <div class="ball" id="ball1"></div> <div class="ball ball--hidden" id="ball2"></div> //css .wall { position: absolute; height: 100%; width: 100px; padding: 0; margin: 0; margin-left: 300px; background-color: black; } .ball { position: absolute; width: 20px; height: 20px; border-radius: 50%; background-color: green; } .ball--hidden{ /*display: none;*/ } //js function drop(ball, from, to, onupdate, duration =2000) { let startTime = Date.now(), [x0, y0] = from, [x1, y1] = to; requestAnimationFrame(function update() { let currentTime = Date.now(), p = (currentTime - startTime) / duration; p = Math.min(p, 1.0); let x = x0 + (x1 - x0) * p, y = y0 + (y1 - y0) * p * p; onupdate(ball, x, y); ball.style.left = x + 'px'; ball.style.top = y + 'px'; if (p < 1) { requestAnimationFrame(update) } }) } playBtn.onclick = function () { drop(ball1, [50, 50], [400, 600], function (ball, x, y) { if (x < 290) { ball.className = 'ball'; } if (x>= 290) { ball.className = 'ball ball--hidden'; } }) drop(ball2, [530, 50], [180, 600] ,function (ball, x, y) { if (x < 290 ) { ball.className = 'ball'; } if (x >= 290) { ball.className = 'ball ball--hidden'; } }) }
动画是关于事件的函数
一个反例
//html <div id="block"></div> //css #block { position: absolute; left: 200px; top: 200px; width: 100px; height: 100px; background-color: #0c8; line-height: 100px; text-align: center; } //js var deg = 0; block.addEventListener('click', function() { var self = this; requestAnimationFrame(function change() { self.style.transform = 'rotate(' + (deg++) + 'deg)'; requestAnimationFrame(change); }); });
直线运动
<
18e5b
li>匀速运动
匀加速运动
匀减速运动
平面上的直线运动
匀速运动
//html <h2>匀速直线运动,滑块在2秒内移动200px</h2> <div id="block">click me</div> //css #block { position: absolute; left: 200px; top: 200px; width: 100px; height: 100px; background: #0c8; line-height: 100px; text-align: center; } //js block.addEventListener('click', function () { var self = this, startTime = Date.now(); distance = 200, duration = 2000; requestAnimationFrame(function step() { var p = Math.min(1.0, (Date.now() - startTime)/ duration); self.style.transform = 'translateX('+ (distance * p)+'px)'; if (p < 1.0) { requestAnimationFrame(step) } }) })
匀加速直线运动
block.addEventListener('click', function(){ var self = this, startTime = Date.now(), distance = 200, duration = 2000; requestAnimationFrame(function step(){ var p = Math.min(1.0, (Date.now() - startTime) / duration); self.style.transform = 'translateX(' + (distance * p * p) +'px)'; if(p < 1.0) requestAnimationFrame(step); }); });
匀减速度直线运动
block.addEventListener('click', function(){ var self = this, startTime = Date.now(), distance = 200, duration = 2000; requestAnimationFrame(function step(){ var p = Math.min(1.0, (Date.now() - startTime) / duration); self.style.transform = 'translateX(' + (distance * p * (2-p)) +'px)'; if(p < 1.0) requestAnimationFrame(step); }); });
平面上的简单运动
斜线运动
曲线运动
圆周运动
斜线运动
block.addEventListener('click', function(){ var self = this, startTime = Date.now(), distance = 200, T = 2000; requestAnimationFrame(function step(){ var p = Math.min(1.0, (Date.now() - startTime) / T); var tx = distance * p; var ty = tx; self.style.transform = 'translate(' + tx + 'px' + ',' + ty +'px)'; if(p < 1.0) requestAnimationFrame(step); }); });
圆锥曲线运动
block.addEventListener('click', function() { var self = this, startTime = Date.now(), disX = 200, disY = 200, duration = 500 * Math.sqrt(2 * disY / 98); // 假设10px 是1米 disY= 20 米 requestAnimationFrame(function step() { var p = Math.min(1.0, (Date.now() - startTime) / duration); var tx = disX * p; var ty = disY * p * p; self.style.transform = 'translate(' +tx + 'px' + ',' + ty + 'px)'; if (p < 1.0) requestAnimationFrame(step); }) })
正弦线运动
block.addEventListener('click', function() { var self = this, startTime = Date.now(), distance = 100, duration = 2000; requestAnimationFrame(function step() { var p = Math.min(1.0, (Date.now() - startTime) / duration); var ty = distance * Math.sin(2 * Math.PI * p); var tx = 2 * distance * p; self.style.transform = 'translate(' + tx + 'px,' + ty + 'px)'; if (p < 1.0) { requestAnimationFrame(step); } }) })
椭圆运动
block.addEventListener('click', function() { var self = this, startTime = Date.now(), a = 150, b = 100, duration = 2000; requestAnimationFrame(function step() { var p = Math.min(1.0, (Date.now() - startTime) / duration); var tx = a * Math.sin(2 * Math.PI * p); var ty = b * Math.cos(2 * Math.PI * p); self.style.transform = 'translate(' + tx + 'px,' + ty + 'px)'; if (p < 1.0) { requestAnimationFrame(step); } }) })
圆的参数方程
连续的运动
动画的简易封装
周期和折线运动
动画队列
改良动画队列
连贯动画
弹跳和滚动
连续平滑动
对动画模型进行抽象
圆周运动
//html <h2>圆周循环运动</h2> <div id="block">click</div> //css #block { position: absolute; left: 150px; top: 200px; width: 50px; height: 50px; border-radius: 50%; background: #0c8; line-height: 50px; text-align: center; transform: translateY(-100px); } //js <script src="https://s4.ssl.qhres.com/!2fb39e02/animator-0.1.0.min.js"></script> let animator = new Animator(2000, function(p) { let tx = -100 * Math.sin(2 * Math.PI * p), ty = -100 * Math.cos(2 * Math.PI * p); block.style.transform = 'translate(' + tx + 'px,' + ty + 'px)'; }); block.addEventListener('click', async function(evt) { let i = 0; while(1) { await animator.animate() block.style.background = ['red', 'green', 'blue'][i++ % 3] } })
折线运动
//html <h2>折线运动</h2> <div id="block">click</div> //css #block { position: absolute; left: 150px; top: 100px; width: 50px; height: 50px; border-radius: 50%; background: #0c8; line-height: 50px; text-align: center; } //js var a1 = new Animator(500, function(p) { var tx = 100 * p; block.style.transform = 'translateX(' + tx + 'px)' }); var a2 = new Animator(1000, function(p) { var ty = 100 * p; block.style.transform = 'translate(100px, ' + ty + 'px)'; }) block.addEventListener('click', async function() { await a1.animate() await a2.animate() })
连续的运动
//html <h2>连续的运动</h2> <div id="block">click</div> //css #block { position: absolute; left: 150px; top: 100px; width: 50px; height: 50px; border-radius: 50%; background: #0c8; line-height: 50px; text-align: center; } //js var a1 = new Animator(500, function(p) { var tx = 100 * p; block.style.transform = 'translateX(' + tx + 'px)' }); var a2 = new Animator(1000, function(p) { var ty = 100 * p; block.style.transform = 'translate(100px, ' + ty + 'px)'; }) var a3 = new Animator(1000, function(p){ var tx = 100 * (1-p); block.style.transform = 'translate(' + tx + 'px, 100px)'; }); var a4 = new Animator(1000, function(p){ var ty = 100 * (1-p); block.style.transform = 'translateY(' + ty + 'px)'; }); block.addEventListener('click', async function() { await a1.animate() await a2.animate() await a3.animate() await a4.animate() })
弹跳的小球
//html <h2>弹跳的小球</h2> <div id="block">click</div> //css #block { position: absolute; left: 150px; top: 100px; width: 50px; height: 50px; border-radius: 50%; background-color: #0c8; line-height: 50px; text-align: center; } //js var a1 = new Animator(1414, function(p) { var ty = 200 * p * p; block.style.transform = 'translateY(' + ty + 'px)' }) var a2 = new Animator(1414, function (p) { var ty = 200 - 200 * p * (2-p); block.style.transform = 'translateY('+ ty +'px)'; }) block.addEventListener('click', async function () { while(1) { await a1.animate() await a2.animate(); } })
改进弹跳的小球
设置阻力系数:
T’ = 0.7T
S’ = 0.49S
//html <h2>弹跳小球</h2> <div id="block">click</div> //css #block{ position:absolute; left: 150px; top: 300px; width: 50px; height: 50px; border-radius: 50%; background: #0c8; line-height: 50px; text-align: center; transform: translateY(-200px); } //js <script src="https://s4.ssl.qhres.com/!2fb39e02/animator-0.1.0.min.js"></script> block.addEventListener('click', async function() { var T = 1414, loss = 0.7; var a1 = new Animator(T, function(p) { var s = this.duration * 200 / T; var ty = s * (p * p -1); console.log(this.duration); block.style.transform = 'translateY(' + ty + 'px)' }) var a2 = new Animator(T, function(p) { var s = this.duration * 200 / T; var ty = -s * p * (2 - p); block.style.transform = 'translateY(' + ty + 'px)' }) while(a2.duration > 0.001) { await a1.animate(); a2.duration *= 0.7; await a2.animate(); a1.duration *= 0.7 } })
滚动的小球
//html <h2>弹跳小球</h2> <div id="block">click</div> //css #block{ position:absolute; left: 50px; top: 100px; width: 50px; height: 50px; border-radius: 50%; background: #0c8; line-height: 50px; text-align: center; } //js <script src="https://s4.ssl.qhres.com/!2fb39e02/animator-0.1.0.min.js"></script> <script type="text/javascript"> var a1 = new Animator(4000, function(p) { var rotation = 720 * p, x = 50 + 314 * p; block.style.transform = 'rotate(' + 720 * p + 'deg)' block.style.left = x + 'px'; }) block.addEventListener('click', async function () { await a1.animate(); }) </script>
小球被惯性甩出
//html <h2>甩出小球</h2> <div id="block">click</div> //css #block { position: absolute; left: 100px; top: 100px; width: 50px; height: 50px; border-radius: 50%; background: #0c8; line-height: 50px; text-align: center; } //js <script src="https://s4.ssl.qhres.com/!2fb39e02/animator-0.1.0.min.js"></script> <script type="text/javascript"> var a1 = new Animator(2800, function(p) { var x = -100 * Math.sin(2.8 * Math.PI * p); var y = 100 - 100 * Math.cos(2.8 * Math.PI * p); block.style.transform = 'translate(' + x + 'px,' + y + 'px)'; }) var a2 = new Animator(5000, function(p) { var x = -100 * Math.sin(2.8 * Math.PI) - 100 * Math.cos(2.8 * Math.PI) * Math.PI * 5 * p; var y = 100 - 100 * Math.cos(2.8 * Math.PI) + 100 * Math.sin(2.8 * Math.PI) * Math.PI * 5 * p; console.log(y) block.style.transform = 'translate(' + x + 'px,' + y + 'px)' // block.style.transform = 'translate(' + x + 'px,' + y + 'px)'; }); block.addEventListener('click', async function() { await a1.animate() await a2.animate() })
摩擦力
小球加速运动100px ,匀速运动100px, 减速运动50px 后停下
//html <h2>摩擦力</h2> <div id="block">click</div> //css #block { position: absolute; left: 100px; top: 100px; width: 50px; height: 50px; border-radius: 50%; background: #0c8; line-height: 50px; text-align: center; } //js <script src="https://s4.ssl.qhres.com/!2fb39e02/animator-0.1.0.min.js"></script> <script type="text/javascript"> var a1 = new Animator(1000, function(p) { var x = 100 * p * p block.style.transform = 'translateX(' + x + 'px)'; }); var a2 = new Animator(500, function(p) { var x = 100 + 100 * p; block.style.transform = 'translateX('+ x + 'px)'; }); var a3 = new Animator(500, function(p) { var x = 200 + 50 * p * (2 - p); block.style.transform = 'translateX(' + x + 'px)' }) block.addEventListener('click', async function() { await a1.animate(); await a2.animate(); await a3.animate(); }) </script>
动画与贝塞尔曲线
构造贝塞尔曲线
使用贝塞尔曲线实现动画
贝塞尔曲线的css3动画
cubic-bezier easing
https://github.com/gre/bezier-easing
http://cubic-bezier.com/
http://easings.net/zh-cn
贝塞尔曲线动画
//html <h2>贝塞尔曲线</h2> <div id="block">click</div> //css #block { position: absolute; left: 100px; top: 100px; width: 50px; height: 50px; border-radius: 50%; background: #0c8; line-height: 50px; text-align: center; } //js var easing = BezierEasing(0.86, 0, 0.07, 1); //easeInOutQuint var a1 = new Animator(2000, function(ep, p) { var x = 200 * ep; block.style.transform = 'translateX(' + x + 'px)'; }, easing); block.addEventListener('click', async function() { await a1.animate(); }); //贝塞尔曲线动画2 var easing = BezierEasing(0.68, -0.55, 0.265, 1.55); //easeInOutBack var a1 = new Animator(2000, function(ep,p){ var x = 200 * ep; block.style.transform = 'translateX(' + x + 'px)'; }, easing); block.addEventListener('click', async function(){ await a1.animate(); }); //贝塞尔曲线动画3 var easing = BezierEasing(0.68, -0.55, 0.265, 1.55); //easeInOutBack var a1 = new Animator(2000, function(ep,p){ var x = 200 * p; var y = -200 * ep; block.style.transform = `translate(${x}px, ${y}px)`; }, easing); block.addEventListener('click', async function(){ await a1.animate(); });
贝塞尔曲线 CSS3 动画
//html <h2>贝塞尔曲线</h2> <div id="block">click</div> //css #block { position: absolute; left: 100px; top: 100px; width: 50px; height: 50px; border-radius: 50%; background: #0c8; line-height: 50px; text-align: center; transition: transform 2s cubic-bezier(0.68, -0.55, 0.265, 1.55); } //js <script type="text/javascript"> block.addEventListener('click', function() { block.className = 'moved'; }); </script>
3D动画
翻转
逐帧动画
翻转动画
//html <h2>翻转动画</h2> <div id="block">click</div> //css #block { position: absolute; left: 100px; top: 400px; width: 50px; height: 50px; border-radius: 50%; background: #0c8; line-height: 50px; text-align: center; } //js <script src="https://s.ssl.qhimg.com/!bfe40c57/bezier-easing.min.js"></script> <script src="https://s4.ssl.qhres.com/!2fb39e02/animator-0.1.0.min.js"></script> <script type="text/javascript"> var easing = BezierEasing(0.68, -0.55, 0.265, 1.55); var a1 = new Animator(2000, function(ep, p) { var y = -200 * ep; var x = 200 * p; var r = 360 * ep; block.style.transform = 'translate(' + x + 'px,' +y + 'px) rotateY(' + r + 'deg)'; }, easing) block.addEventListener('click', async function() { await a1.animate(); })
逐帧动画
//html <div id="bird" class="sprite bird bird1"></div> //css .sprite { display: inline-block; overflow: hidden; background-repeat: no-repeat; background-image: url(https://p1.ssl.qhimg.com/d/inn/0f86ff2a/8PQEganHkhynPxk-CUyDcJEk.png); } .bird { width: 86px; height: 60px; } .bird0 { background-position: -178px -2px } .bird1 { background-position: -90px -2px } .bird2 { background-position: -2px -2px } //js <script type="text/javascript"> var i = 0; setInterval(function () { bird.className = 'sprite bird ' + 'bird' + ((i++)%3) }, 1000/10); </script>
Web Animations API
W3C Editor’s Draft
Polyfill
//html <div id="block">click</div> <div id="bird" class="sprite"></div> //css #block { text-align: center; color: #aaa; line-height: 50px; position: absolute; width: 50px; height: 50px; left: 100px; top: 100px; background-color: #077; } #bird { position: absolute; left: 100px; top: 100px; zoom: 0.5; display: inline-block; overflow: hidden; width: 86px; height: 60px; background: url(https://p1.ssl.qhimg.com/d/inn/0f86ff2a/8PQEganHkhynPxk-CUyDcJEk.png) no-repeat -178px -2px; } //js block.addEventListener('click', e => { block.animate([{ offset: 0, transform: 'rotate(0deg)' }, { offset: 1, transform: 'rotate(360deg)' } ], { duration: 3000, direction: 'normal', fill: 'both', iterations: Infinity }); function backgroundPosition(x, y) { return `url(https://p1.ssl.qhimg.com/d/inn/0f86ff2a/8PQEganHkhynPxk-CUyDcJEk.png) no-repeat ${x}px ${y}px`; } bird.animate([{ offset: 0, background: backgroundPosition(-178, -2) }, { offset: 0.33, background: backgroundPosition(-178, -2) }, { offset: 1, background: backgroundPosition(-2, -2) } ], { duration: 500, direction: 'normal', fill: 'both', iterations: Infinity, easing: 'steps(3, start)' }); });
总结
本课通过例子学习了实现动画的基本原理和思路
动画是关于时间的函数
动画的数学计算
动画的封装和组合动画
贝塞尔曲线
3D和序列帧动画
相关文章推荐
- 【JavaScript动画基础】学习笔记(一)-- 旋转箭头
- javascript基础笔记之(六)js数组
- javascript基础知识精华笔记汇总
- 【Visual C++】游戏开发笔记之十一 基础动画显示(四) 排序贴图
- javascript学习笔记 (一)-函数基础
- javascript笔记---算法基础学习
- JavaScript学习笔记——对象基础
- 【Android学习笔记】属性动画基础学习笔记
- javascript 基础笔记 变量、作用域、内存问题
- 黑马程序员-javascript基础知识学习笔记
- javascript基础笔记(十七)之js的bom对象
- (清华大学HTML+CSS+JavaScript入门到精通学习笔记)第二章 HTML基础
- 【Visual C++】游戏开发笔记之七——基础动画显示(一)定时器的使用
- javascript基础语法学习笔记
- 奇舞javaScript概览 -笔记
- JavaScript 学习笔记之基础中的基础
- Javascript学习笔记一:基础
- css和javascript的一些笔记(二) js基础知识
- 【Visual C++】游戏开发笔记之七——基础动画显示(一)定时器的使用
- 【Visual C++】游戏开发笔记之八――基础动画显示(二)游戏循环的使用