让炮姐跟着我跑 - 缓动跟随 Demo

我们时常会遇到这样的需求:让物体平滑地移动至某处。一般来说,匀速地移动总是显得过于死板,不够 fancy,因此有变速移动的需求,即「缓动」。

这个问题的本质可以转化到对运动规律的设计上。我们都知道几种基本运动规律:匀速运动、匀加速运动、变加速运动的运动性质,要做的只是实现它们罢了。不过物理课上对它们的研究主要还是停留在连续域上,计算机世界是离散的,因此我们需要对这些运动规律做一个离散域的“移植”。

昨天我闲来无事,做了一个小的缓动跟随 Demo 如下。你可以试着以不同速度用鼠标拖动我的头像,观察炮姐头像的运动规律(手机上可能不好使)。

See the Pen FollowMe by AlanDecode (@AlanDecode) on CodePen.

当我的移动速度比较慢时,炮姐会以相对平均的速度慢慢追上我;当我的速度突然变快,我和炮姐之间的距离会被拉开,炮姐就会加快步伐追我,最后慢慢地停在我的边上。

这种运动规律与“离开多少追上多少”那种规律不同,在那种规律下,两次界面重绘之间我和炮姐拉开了多少距离,在重绘时就会立马被补上,是不是显得没什么人情味?

观察上面那个 Demo 中的 JS,核心代码是:

function followMe(){
    var me=$("#me").offset();
    var paojie=$("#paojie").offset();
    if(distance(me,paojie)>=100){
        var moveX=(me.left-paojie.left)*0.002;
        var moveY=(me.top-paojie.top)*0.002;
        $("#paojie").css("left",paojie.left+moveX+"px");
        $("#paojie").css("top",paojie.top+moveY+"px"); 
        requestAnimationFrame(followMe);
    }
}

其中 distance() 函数用于计算我和炮姐之间的曼哈顿距离:

function distance(x,y){
    return Math.abs(x.left-y.left)+Math.abs(x.top-y.top);
}

即:每两次重绘(即每两次调用 requestAnimationFrame() )之间,炮姐在每根轴上的移动距离是我和炮姐的间隔 × 0.002,直至我和炮姐的距离小于 100 像素,函数返回不再追及。随着我和炮姐之间的距离逐渐变短,炮姐每次移动的距离也变小,实现了“减速”的效果,有兴趣的话可以研究一下这到底属于哪一种运动规律。0.002 这个参数决定了追逐的速度,越大越快,你可以自己修改这个值,也可以试试在每根轴上采用不同的追逐速度。

说到这里我想到一件事。在工业设计领域,遇到直线与圆角连接时一般要保证连接点两边二阶导数连续才能算“平滑”。例如 iPhoneX 的显示界面圆角,并不是圆弧与直线连接,而是特别设计的弧,使得它在与直线的连接处足够平滑。不过这是题外话了。

Tags:none
上一篇
打赏
下一篇

添加新评论

已有 6 条评论

 jiuchi 2 天前 • |

哇,只看懂了炮姐

 熊猫小A 2 天前 • |
@jiuchi

看懂炮姐就够了哈哈

 广树 3 星期前 • |

还挺好玩的

 熊猫小A 3 星期前 • |
@广树

嘿嘿嘿 炮姐赛高

 mikusa 3 星期前 • |

手机上不是可能不好使,是根本不好使

 熊猫小A 3 星期前 • |
@mikusa

嘛……CodePen 主要还是电脑端用的