参阅哔哩哔哩pink老师课程
1. 动画函数封装
1.1 动画完成原理
中心原理:通过定时器setInterval()
不断移动盒子方位。 完成进程:
- 获得盒子当时方位
- 让盒子在当时方位加上 1 个移动间隔
- 运用定时器不断重复这个操作
- 加一个结束定时器的条件
- 留意此元素需求增加定位(
position: absolute
),才干运用element.style.left
1.2 动画函数简单封装
留意函数需求传递 2 个参数,动画目标 和 移动到的间隔
<script>
// 简单动画函数封装 animate 动画
// obj 方针目标 target 方针方位
function animate(obj, target) {
var time = setInterval(function () {
if (obj.offsetLeft >= target) {
// 中止动画 实质是中止定时器
clearInterval(time);
}
obj.style.left = obj.offsetLeft + 5 + 'px';
}, 30)
}
var div = document.querySelector('div');
// 调用函数
animate(div, 400);
</script>
1.3 动画函数给不同元素记载不同定时器
假如多个元素都运用这个动画函数,每次都要var
声明定时器。咱们能够给不同的元素运用不同的定时器(自己专门用自己的定时器)。
中心原理:运用 JS 是一门动态语言,能够很便利的给当时目标增加特点。
举例:
// 封装动画函数
function animate(obj, target) {
// 给不同节点目标 obj 设置定时器
obj.timer = setInterval(function () {
if (obj.offsetLeft <= target) {
obj.style.left = obj.offsetLeft + 1 + 'px';
} else {
// 清除目标自己的定时器
clearInterval(obj.timer);
}
}, 30);
}
当咱们不断的点击按钮,这个元素的速度会越来越快,由于敞开了太多的定时器
处理bug的办法:让咱们只要一个定时器履行
1.4 缓动作用原理
之前讲的是匀速动画:
盒子当时方位 = 盒子当时方位 + 固定值盒子当时方位=盒子当时方位+固定值
缓动动画便是让元素运动速度有所改变,最常见的是让速度渐渐停下来
匀速动画 便是 盒子是当时的方位 + 固定的值 10; 缓动动画便是 盒子当时的方位 + 改变的值
思路:
- 让盒子每次移动的间隔渐渐变小,速度就会渐渐落下来。
- 中心算法:
每次移动的间隔步长 = (方针值 – 现在的方位) / 10
- 中止的条件是:让当时盒子方位等于方针方位就中止定时器
- 留意步长值需求取整(
Math.ceil
/Math.floor
)
示例:
function animate(obj, target) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
// 缓冲动画中心算法
let step = Math.ceil((target - obj.offsetLeft) / 10);
if (obj.offsetLeft === target) {
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 30);
}
1.5 动画函数多个方针值之间移动
能够让动画函数从800
移动到500
。
当咱们点击按钮时分,判别步长是正值还是负值:
- 假如是正值,则步长往大了取整(
Math.ceil()
) - 假如是负值,则步长向小了取整(
Math.floor()
)
示例:
function animate(obj, target) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
// 缓冲动画中心算法
let step = target - obj.offsetLeft;
// 左右移动步值正负处理
step = step >= 0 ? Math.ceil(step / 10) : Math.floor(step / 10);
if (obj.offsetLeft === target) {
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 30);
}
1.6 动画函数增加回调函数
-
回调函数原理:函数能够作为一个参数。将这个函数作为参数传到另一个函数里边,当那个函数履行完之后, 再履行传进去的这个函数,这个进程就叫做回调(
callback
) 。(动画履行完后再履行) - 回调函数写的方位:定时器结束的方位。
示例:
1.7 动画函数封装到独自JS文件里边
由于今后常常运用这个动画函数,能够独自封装到一个JS文件里边,运用的时分引用这个JS文件即可。
- 独自新建一个 JS 文件。
- HTML文件引入 JS 文件。
示例:
2. 常见网页特效事例
2.1 事例1: 轮播图
项目源码地址:hacker-c.github.io/PinYouGou-S…
轮播图也称为焦点图,是网页中比较常见的网页特效。
功用需求:
- 鼠标通过轮播图模块,左右按钮显现,脱离躲藏左右按钮。
- 点击右侧按钮一次,图片往左播映一张,以此类推,左边按钮同理。
- 图片播映的一同,下面小圆圈模块跟从一同改变。
- 点击小圆圈,能够播映相应图片。
- 鼠标不通过轮播图,轮播图也会自动播映图片。
- 鼠标通过,轮播图模块,自动播映中止。
思路剖析点击翻开
2.1.1 总体剖析
- 由于 js 较多,咱们独自新建 js 文件夹,再新建 js 文件,引入页面中。
- 此刻需求增加
load
事情。 - 鼠标通过轮播图模块,左右按钮显现,脱离躲藏左右按钮。
- 显现躲藏
display
按钮。
2.1.2 动态生成小圆圈
- 中心思路:小圆圈的个数要跟图片张数共同
- 所以首先先得到
ul
里边图片的张数(图片放入li
里边,所以便是li
的个数) - 运用循环动态生成小圆圈(这个小圆圈要放入
ol
里边) -
创立节点
createElement('li')
-
插入节点
ol.appendChild(li)
- 第一个小圆圈需求增加
current
类
2.1.3 小圆圈的排他思想
- 点击当时小圆圈,就增加
current
类 - 其余的小圆圈就移除这个
current
类 - 留意:咱们在方才生成小圆圈的一同,就能够直接绑定这个点击事情了。
2.1.4 点击小圆圈翻滚图片
- 此刻用到
animate
动画函数,将 js 文件引入(留意,由于 index.js 依靠 animate.js 所以,animate.js 要写到index.js 上面) - 运用动画函数的前提,该元素必须有定位
- 留意是
ul
移动而不是小li
- 翻滚图片的中心算法:点击某个小圆圈,就让图片翻滚小圆圈的索引号乘以图片的宽度做为
ul
移动间隔 - 此刻需求知道小圆圈的索引号,咱们能够在生成小圆圈的时分,给它设置一个自定义特点,点击的时分获取这个自定 义特点即可。
2.1.5 右侧按钮功用
点击右侧按钮一次,就让图片翻滚一张。
- 声明一个变量
num
,点击一次,自增 1,让这个变量乘以图片宽度,便是ul 的翻滚间隔。 - 图片无缝翻滚原理
- 把
ul
第一个li
仿制一份,放到ul
的最后面 - 当图片翻滚到克隆的最后一张图片时,让
ul
快速的、不做动画的跳到最左边:left
为0 - 一同
num
赋值为0,能够重新开端翻滚图片了
2.1.6 克隆第一张图片
- 克隆
ul
第一个li.cloneNode()
加true
深克隆仿制里边的子节点(false
:浅克隆) - 增加到
ul
最后面appendChild
2.1.7 点击右侧按钮,小圆圈跟从改变
- 最简单的做法是再声明一个变量
circle
,每次点击自增1,留意,左边按钮也需求这个变量,因而要声明全局变量。 - 但是图片有5张,咱们小圆圈只要4个少一个,必须加一个判别条件
- 假如
circle == 4
就重新复原为 0
2.1.8 自动播映功用
- 增加一个定时器
- 自动播映轮播图,实际就类似于点击了右侧按钮
- 此刻咱们运用手动调用右侧按钮点击事情
arrow_r.click()
- 鼠标通过
focus
就中止定时器 - 鼠标脱离
focus
就敞开定时器
2.1.9 节流阀
-
功用:防止轮播图按钮接连点击形成播映过快。
-
原理:当上一个函数动画内容履行结束,再去履行下一个函数动画,让事情无法接连触发。
-
思路:运用回调函数,增加一个变量来操控,锁住函数和解锁函数。
- 开端设置一个变量:
var flag = true;
-
if(flag) {flag = false; do something}
:封闭水龙头 - 运用回调函数动画履行结束:
flag = true
翻开水龙头
- 开端设置一个变量:
2.2 事例2:回来顶部
2.2.1 window.scroll
翻滚窗口至文档中的特定方位:
window.scroll(x, y)
留意:里边的x
和y
不跟单位,直接写数字。
2.2.2 带有动画的回来顶部
- 此刻能够继续运用咱们封装的动画函数
- 只需求把所有的
left
相关的值改为跟页面笔直翻滚间隔相关就能够了 - 页面翻滚了多少,能够通过
window.pageYOffset
得到 - 最后是页面翻滚,运用
window.scroll(x, y)
2.2.3 修改后的缓存动画函数
function animate(obj, target, callback) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
// 缓冲动画中心算法
let step = target - window.pageYOffset;
step = step >= 0 ? Math.ceil(step / 10) : Math.floor(step / 10);
if (window.pageYOffset === target) {
clearInterval(obj.timer);
callback && callback();
}
window.scroll(0, window.pageYOffset + step);
}, 30);
}
调用:
animate(window, 0);
2.3 事例3:筋斗云
2.3.1 作用
- 鼠标通过某个小
li
,筋斗云跟这到当时小li
方位 - 鼠标脱离这个小
li
,筋斗云复原为原来的方位 - 鼠标点击了某个小
li
,筋斗云就会留在点击这个小li
的方位
2.3.2 完成
- 运用动画函数做动画作用
- 原先筋斗云的开始方位是
0
- 鼠标通过某个小
li
,把当时小li
的offsetLeft
方位做为方针值即可 - 鼠标脱离某个小
li
,就把方针值设为0
- 假如点击了某个小
li
,就把li
当时的方位存储起来,做为筋斗云的开始方位
中心代码:
var current = 0;
for (var i = 0; i < lis.length; i++) {
// (1) 鼠标通过把当时小li 的方位做为方针值
lis[i].addEventListener('mouseenter', function() {
animate(cloud, this.offsetLeft);
});
// (2) 鼠标脱离就回到开始的方位
lis[i].addEventListener('mouseleave', function() {
animate(cloud, current);
});
// (3) 当咱们鼠标点击,就把当时方位做为方针值
lis[i].addEventListener('click', function() {
current = this.offsetLeft;
});
}