文档章节

javascript匀速动画和缓冲动画

zfx2016
 zfx2016
发布于 2016/10/19 11:42
字数 998
阅读 2
收藏 0

关于网页中的动画,在css3中我们已经可以使用一些属性快速的做出来,但是有时候为了浏览器的兼容性我们还是需要使用js来制作网页中的动画。

使用js做动画最重要的一个函数就是setInterval函数,这里不再赘述,不懂可以直接百度用法。本文主要讲动画的原理已经在制作过程中的要点。

老规矩,先上代码,能直接看懂的可以节省时间。


html部分:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>move</title>
    <link rel="stylesheet" href="move1.css">
</head>
<body>
    <input type="button" value="匀速移动" id="move1">
    <input type="button" value="渐变移动" id="move2">
    <div id="box1" class="box"></div>
    <div id="box2" class="box"></div>
    <script type="text/javascript" src="move1.js"></script>
</body>
</html>


css部分:

*{
    margin: 0px;
    padding: 0px;
}
.box{
    width: 100px;
    height: 100px;
    background-color: green;
    position: relative;
    margin-top: 10px;
}

js部分:

/**
 * Created by siri on 2016/9/10.
 */
window.onload=function () {
    var btn1 = document.getElementById('move1');
    var btn2 = document.getElementById('move2');
    var box1 = document.getElementById('box1');
    var box2 = document.getElementById('box2');
    btn1.onclick = function () {
        animate1(box1,500);
    }
    btn2.onclick = function () {
        animate2(box2,500);
    }
    //匀速动画
    function animate1(ele,target){
        //要用定时器,先清除定时器
        //一个盒子只能有一个定时器,这样儿的话,不会和其他盒子出现定时器冲突
        //而定时器本身讲成为盒子的一个属性
        clearInterval(ele.timer);
        //我们要求盒子既能向前又能向后,那么我们的步长就得有正有负
        //目标值如果大于当前值取正,目标值如果小于当前值取负
        var speed = target>ele.offsetLeft?3:-3;
        ele.timer = setInterval(function () {
            //在执行之前就获取当前值和目标值之差
            var val = target - ele.offsetLeft;
            ele.style.left = ele.offsetLeft + speed + "px";
            //目标值和当前值只差如果小于步长,那么就不能再前进了
            //因为步长有正有负,所有转换成绝对值来比较
            console.log(val);
            if(Math.abs(val)<=Math.abs(speed)){
                ele.style.left = target + "px";
                clearInterval(ele.timer);

            }
        },30);
    }

    //缓动动画封装
    function animate2(ele,target) {
        clearInterval(ele.timer); //清楚历史定时器
        ele.timer = setInterval(function () {
            //获取步长 确定移动方向(正负值) 步长应该是越来越小的,缓动的算法。
            var step = (target-ele.offsetLeft)/10;
            //对步长进行二次加工(大于0向上取整,小于0项下取整)
            step = step>0?Math.ceil(step):Math.floor(step);
            //动画原理: 目标位置 = 当前位置 + 步长
            console.log(step);
            ele.style.left = ele.offsetLeft + step + "px";
            //检测缓动动画有没有停止
            if(Math.abs(target-ele.offsetLeft)<=Math.abs(step)){
                ele.style.left = target + "px"; //直接移动指定位置
                clearInterval(ele.timer);
            }
        },30);
    }


}

html和css基本就是为了我们的js部分搭框架,不讲太多, 要注意的是,一定要对全局的margin和padding清零,否则的话他在计算的时候初始的margin和padding会影响计算,从而导致有时候运动不停止的情况。


javascript部分代码的解析在源码中已经很详细了,下面主要讲解原理。

匀速运动:

通过setInterval函数我们控制每多少毫秒运动的距离,然后在快要到达指定位置的时候,判断步长(每多少毫秒运动的距离)和此时和目标位置的距离,如果步长大于此时和目标位置的距离,则直接定位到目标位置,这样做是为了避免步长和总距离不是整数倍关系而产生最后到达位置和目标位置有差值的错误。

缓冲运动:

缓冲运动的基本函数是和匀速运动一样的,只是缓冲运动的步长我们是通过和目标位置的距离来确定的,这样我们的步长是不断变小的,从而实现缓冲运动的效果。在确定步长的时候我们使用Math.ceil和Math.floor对步长值进行取整是为了避免出现小数,因为如果出现小数后面最后到达的位置肯定是和目标位置有误差的。

注意事项:在每次移动开始前一定要使用clearInterval清除定时器。


© 著作权归作者所有

zfx2016
粉丝 1
博文 22
码字总数 14027
作品 0
广州
前端工程师
私信 提问
大话 JavaScript 动画

背景 138.2亿年前,世界上没有时间和空间,或许世界都不存在,在一个似有似无的点上,汇集了所有的物质,它孕育着无限的能量与可能性。 宇宙大爆炸 巨大的内力已无法被抑制,瞬间爆发,它爆炸...

明非
2018/10/06
0
0
JavaScript是如何工作的: CSS 和 JS 动画底层原理及如何优化它们的性能

摘要: 理解浏览器渲染。 原文:JavaScript是如何工作的: CSS 和 JS 动画底层原理及如何优化它们的性能 作者:前端小智 Fundebug经授权转载,版权归原作者所有。 这是专门探索 JavaScript 及...

Fundebug
01/18
0
0
如何实现一个下载进度条/播放进度条

技术上没太大难度,有难度的地方是怎么让整个动画比较流畅。一个主要问题是动画的滞后性:当下载进度到某个点的时候,你再用250ms的动画过渡过去,这个时候已经慢了,所以很多人可能因为这个...

人人网FED
06/09
0
0
[译] JavaScript 是如何工作的:CSS 和 JS 动画背后的原理 + 如何优化性能

原文地址:How JavaScript works: Under the hood of CSS and JS animations + how to optimize their performance 原文作者:Alexander Zlatkov 译文出自:掘金翻译计划 本文永久链接:git......

辣手摧花
2018/05/15
0
0
【JSConf EU 2018】Rust + WebAssembly

欧洲JSConf上的神秘项目 在今年的欧洲JSConf上来自Mozilla的Lin Clark为我们展示一个神秘项目,一个的拱形彩虹门(视频传送门),它实际上是由三万个彩色LED组成的画布,可以展现灯光动画,并...

leyayun
2018/06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

JAVA 编写redisUtils工具类,防止高并发获取缓存出现并发问题

import lombok.extern.slf4j.Slf4j;import org.springframework.data.redis.core.BoundHashOperations;import org.springframework.data.redis.core.BoundValueOperations;import org.......

huangkejie
37分钟前
5
0
JMM内存模型(一)&volatile关键字的可见性

在说这个之前,我想先说一下计算机的内存模型: CPU在执行的时候,肯定要有数据,而数据在内存中放着呢,这里的内存就是计算机的物理内存,刚开始还好,但是随着技术的发展,CPU处理的速度越...

走向人生巅峰的大路
55分钟前
95
0
你对AJAX认知有多少(2)?

接着昨日内容,我们几天继续探讨ajax的相关知识点 提到ajax下面几个问题又是必须要了解的啦~~~ 8、在浏览器端如何得到服务器端响应的XML数据。 通过XMLHttpRequest对象的responseXMl属性 9、 ...

理性思考
今天
5
0
正则表达式基础(一)

1.转义 转义的作用: 当某个字符在表达式中具有特殊含义,例如字符串引号中出现了引号,为了可以使用这些字符本身,而不是使用其在表达式中的特殊含义,则需要通过转义符“\”来构建该字符转...

清自以敬
今天
4
0
idea中@Data标签getset不起作用

背景:换电脑以后在idea中有@data注解都不生效 解决办法:idea装个插件 https://blog.csdn.net/seapeak007/article/details/72911529...

栾小糖
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部