JavaScript 运动 03 —— 缓冲运动

缓冲运动和匀速运动的区别

匀速运动:速度一直不变的运动
缓冲运动:速度逐渐加快或者减慢的运动
缓冲运动的速度处于不断的变化中,和匀速运动不同的是,缓冲运动一般不设置初始速度,而是在运动函数内部进行计算。

缓冲运动公式

缓冲运动是速度逐渐变化的运动,速度公式为:(目标点 - 当前位置)/ 缩放系数
缓冲运动的停止条件:当前位置 = 目标点
修改 animate 函数:

function animate(ele = null,config = {
    attrs:{},
    scale:10,
}){
    // 清除定时器
    clearInterval(ele.timer);
    const attrs = config.attrs;
    const scale = config.scale;
    return new Promise((resolve)=>{
        ele.timer = setInterval(()=>{
            let flag = true;
            for(const attr in attrs){
                // 设置目标距离
                let target = Number.parseInt(attrs[attr]);

                // 获取当前的样式
                let currentStyle = (attr === "opacity")?(Number.parseInt(Number.parseFloat(getCurrentStyle(ele,attr))*100)):Number.parseInt(getCurrentStyle(ele,attr));

                // 如果改变的样式是 opacity,target乘以100
                if(attr === "opacity"){
                    target = Number.parseInt(Number.parseFloat(attrs[attr])*100);
                }

                // 获取速度
                let speed = (target - currentStyle) / scale
                speed = (speed > 0) ? Math.ceil(speed):Math.floor(speed);

                // 根据运动是否完成来设定 flag
                if(currentStyle !== target){
                    flag = false;
                }

                // 运动到目标点后清除定时器
                if(currentStyle === target){
                    ele.style[attr] = (attr === "opacity")? target / 100 : target + "px";
                }else{
                    // 根据当前样式动态改变物体的样式
                    ele.style[attr] = (attr === "opacity")?( currentStyle + speed)/100:(currentStyle + speed) + "px";
                    currentStyle += speed;
                }
            }

            if(flag){
                clearInterval(ele.timer);
                resolve();
            }
        },30);
    });
}

调用运动函数:

const ele = document.getElementById("inner");
const par = document.getElementById("par");
async function start(){
    await animate(ele,{
        attrs:{
            left:"500px",
        },
        scale:10,
    });

    await animate(ele,{
        attrs:{
            left:0,
        },
        scale:5,
    });
}

查看效果:

缓冲运动.gif

关于速度计算

现在解释下上面的速度计算方式:

let speed = (target - currentStyle) / scale
speed = (speed > 0) ? Math.ceil(speed):Math.floor(speed);

由于我们给的 scale 并不总是让 speed 的计算结果为整数,很可能出现浮点数的情况,因此需要对 speed 浮点数进行处理。在处理时又分为两种情况:

  • speed > 0
  • speed < 0

当 speed >0 时,speed 无限接近于 +0,以缩放系数为 10 进行举例:

运动次数 速度 位置 目标位置
1 50 50 500
2 45 95 500
3 40.5 135.5 500
... ... ... 500
43 1 491 500
44 0.9 491.9 500
45 0.9 491.9 500
... ... 491.9 500

在某个时候,速度会成为小数,于是当前位置也是小数,由于像素不可能有小数值,于是当前位置后的小数值会被抛弃,看起来小滑块停止到目标点之前了,而定时器仍然在运动(当前位置不等于目标位置),如图所示:

缓冲运动速度-1.gif

因此我们将速度向上取整,当速度小于 1 时,取整后速度为 1,最终的速度为 1,就能保证小滑块一像素一像素的移动到目标点,然后停止定时器。
当 speed < 0 时,分析方式和上面一样。这里便不再赘述,结论是当速度小于 0 时,对速度进行向下取整,最终速度为 -1

多值缓冲运动

由于缓冲运动是基于前面的运动框架搭建的,因此也是支持多值运动的,下面罗列出一个栗子:

const ele = document.getElementById("inner");
async function start(){
    await animate(ele,{
        attrs:{
            left:"500px",
            width:"50px",
            height:"50px",
            fontSize:"10px",
            lineHeight:"50px",
            opacity:1,
        },
        scale:10,
    });
}

效果如图:

多值缓冲运动.gif

总结

本文介绍了缓冲运动,下面简单总结下二者的差距:

| | 缓冲运动 | 匀速运动 |
| :--------: | :-----: | :----: | :----: |
|运动形式 | 速度越来越慢 | 速度不变 |
|停止条件 | 当前位置和目标点重合 | 当前位置和目标点差值的绝对值小于速度值 |
|速度 | 需要进行取整操作 | 速度不变 |
|最终速度 | 1 或 -1 | 速度不变 |

从视觉效果来看,缓冲运动比匀速运动更为炫酷一些,也是常用的运动方式。后序的文章中,我们还会介绍另外两种运动形式:弹性运动和碰撞运动。

完。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容