irpas技术客

JavaScript(API)缓动动画封装详解_个人:www.chaichaisocute.top

网络投稿 2904

目录

前言

实现过程分析

(1)如何重复调用?

(2)如何实现缓动效果?(缓动动画核心算法)

(3)为什么移动不到指定位置?(给的目标距离是500px,移动到496.4就停下了)

(4)如何让目标元素真正移动起来?

(5)为什么会鬼畜或者越点越快?

案例测试:

最终封装代码:


前言

缓动动画原理:移动的像素慢慢减少,让效果看起来更柔和更美观,通过定时器加回调函数,实现动画效果以及更多具体功能,非常好用。


实现过程分析

(1)如何重复调用?

????????答:封装一个函数,用一次调用一次

代码分析:

function animate(obj, target, callback) { //详细实现步骤 };

animate :(动画函数)

obj(动画对象):给谁添加动画效果

target(目标值):移动到什么距离

callback(回调函数):同时要执行什么功能

(2)如何实现缓动效果?(缓动动画核心算法)

? ? ? ? 答:移动距离 =(目标值 - 现在盒子位置)/ 10,移动距离会慢慢变小,直至停下,就实现了缓动原理

?代码分析:

var step = (target - obj.offsetLeft) / 10;

step(移动距离): 元素要移动的距离

target(目标值):移动到什么距离

obj.offsetLeft(盒子现在的位置):盒子现在距离左侧的距离

(3)为什么移动不到指定位置?(给的目标距离是500px,移动到496.4就停下了)

? ? ? ? 答:因为需要取整,正数往上取整,负数向下取整

?代码分析:

step = step > 0 ? Math.ceil(step) : Math.floor(step);

如果setp要移动的距离是正数,就向上取整,如果是负数,就向下取整,采取三元表达式以优化代码,提升整体质量?

(4)如何让目标元素真正移动起来?

? ? ? ? 答:添加定时器,并将实时移动距离(步长)赋值给元素

代码分析:

var timer = setInterval(function () { //详细实现代码 }, 15); //添加定时器 obj.style.left = obj.offsetLeft + step + 'px'; //步长

1.给定时器添加名字是为了好清除定时器,时间设置为15(实际开发常用15)

2.元素的左侧的值 = 元素离左侧的距离 + 移动距离 + 'px' (记得一定要加px单位),实现原理就是不断将最新的值赋值给元素,实现动起来的效果

(5)为什么会鬼畜或者越点越快?

? ? ? ? 答:因为定时器重复添加,需要每次调用时清除定时器

代码分析:

clearInterval(timer);

?两个地方需要清除,第一是刚调用缓动动画函数时,避免鬼畜和破速,第二是判断元素到达指定位置没有,如果到达了就停止定时器


案例测试: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .sliderbar { /* width: 240px; */ /* height: 40px; */ /* 父盒子定位根据实际要求来 */ position: absolute; right: 0; top: 100px; text-align: center; line-height: 40px; /* display: block; */ width: 40px; height: 40px; cursor: pointer; } .sp { position: relative; color: #fff; } .con { /* 设置了绝对定位就在父盒子里飘起来 */ position: absolute; left: 0; top: 0; width: 200px; height: 40px; background-color: pink; z-index: -1; color: #fff; } </style> <script src="./animate.js"></script> </head> <body> <div class="sliderbar"> <span class="sp">←</span> <div class="con">问题反馈</div> </div> <script> var sliderbar = document.querySelector('.sliderbar'); // var sp = document.querySelector('.sp'); var con = document.querySelector('.con'); sliderbar.addEventListener('mouseenter', function() { //animate(obj, target, callback); animate(con, -160, function() { sliderbar.children[0].innerHTML = '→'; }); }) sliderbar.addEventListener('mouseleave', function() { //animate(obj, target, callback); animate(con, 0, function() { sliderbar.children[0].innerHTML = '←'; }); }) </script> </body> </html>

整体思路:通过给盒子添加鼠标事件来调用动画函数,最终实现效果

运行效果:?

?

?


缓动动画函数最终封装代码(animate.js):

? ? function animate(obj, target, callback) {

? ? ? ? //调用函数就清除一次定时器,避免问题发生

? ? ? ? clearInterval(obj.timer)

? ? ? ? //添加定时器

? ? ? ? obj.timer = setInterval(function () {

? ? ? ? ? ? //步长值写到计时器里面 ?改为整数(往上取整)

? ? ? ? ? ? var step = (target - obj.offsetLeft) / 10;

? ? ? ? ? ? //整数往大了取,负数往小了取

? ? ? ? ? ? step = step > 0 ? Math.ceil(step) : Math.floor(step);

? ? ? ? ? ? if (obj.offsetLeft == target) {

? ? ? ? ? ? ? ? //如果已经到达指定位置就停止定时器

? ? ? ? ? ? ? ? clearInterval(obj.timer);

? ? ? ? ? ? ? ? //回调函数写到定时器结束之后

? ? ? ? ? ? ? ? callback && callback();

? ? ? ? ? ? }

? ? ? ? ? ? ? ? //把每次加一步长值改变为慢慢变小的值

? ? ? ? ? ? ? ? obj.style.left = obj.offsetLeft + step + 'px';

? ? ? ? }, 15);

? ? }


生命不息,学习不止,键盘敲烂,月薪过万?!加油,代码人


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。