css翻转效果 每日掏心话生命最有趣的部分,但谎言令我们痛一生

  点击上方 "程序员小乐"关注, 星标或置顶一起成长

  第一时间与你相约

  每日英文

  The truth may hurt for a little while but a lie hurts forever.Something is a knot when you reserve it,a scar when it's opened.

  真相会让我们痛一阵,但谎言令我们痛一生。有些事情,不谈是个结,谈开了是个疤。

  每日掏心话

  生命最有趣的部分,正是它没有剧本、没有彩排、不能重来。时候执着是一种负担,放弃是一种解脱,人生没有完美,幸福也没有一百分。

  来自:人人网FED | 责编:乐乐

  链接:juejin.im/post/5a97bb3951882555867ecffc

  css 图片翻转_css翻转效果_background-image翻转 css

  程序员小乐(ID:study_tech)第 688 次推文 图片来自网络

  往日回顾:Git 从入门到放不下,看这篇就对了!

  正文

  background-image翻转 css_css 图片翻转_css翻转效果

  以前经常看到这种效果:在网页右下角放一个人,然后他的眼珠会跟着鼠标转,效果如下:

  css翻转效果_background-image翻转 css_css 图片翻转

  这个例子来自于CodePen,它是根据鼠标的位置设置两个眼球的transform: rotate属性做的效果。

  这种跟着鼠标移动的小交互一般都比较好玩,所以我突然想到,能不能做一只会跟着鼠标走的小,最后的效果如下所示:

  background-image翻转 css_css翻转效果_css 图片翻转

  我们一步步来实现这个效果。

  1. 小狗走的动画

  小狗走的动画应该怎么实现呢?如果用一张gif,然后根据鼠标的位置移动这张gif,那么当鼠标停下来小狗不动的效果就做不了,因为gif一直在循环播放代码控制不了这个行为。所以这种简单方案是不可行的。

  然后又想到之前用CSS的animation做过这种逐帧动画:

  background-image翻转 css_css 图片翻转_css翻转效果

  所以就有思路了,小狗的动画也是使用逐帧的动画,并且用JS控制它的播放。

  在网上搜罗了一番,还没有人做过类似的动画,不过找到了小狗的素材,这位老兄在教人怎么画行走的动物,刚好可以拿来当做我们的素材,把小狗抠出来:

  2. 画一只在原地踏步的小狗

  动画的第一步先让小狗原地踏步,即先让这个动画能播放起来,然后再做移动的动画。所谓逐帧动画就是每隔一小会就播放一帧,这样连起来就是在动了。

  写一个canvas标签,然后把它固定到页面的底部:

  然后设置宽度为页面的100%:

  这样我们就有一个画布了。接着要把图片画让去,先要把图片加载下来,上面我们准备了9张png:0.png ~ 8.png,其中0.png是小狗停住不动的图片,1.png ~ 8.png是小狗在走的图片。

  在JS里面怎么加载图片呢,用新建一个Image实例的方式css翻转效果,如下代码所示:

  由于图片比较多,我们用类的方式组织我们的代码,把数据当作类的属性,方便存取。如下代码所示:

  把狗的图片放到dogPictures数组里面,在loadResources里面进行加载,如下代码所示:

  这段加载图片的代码借助了Promise,把每张图片的加载都当作一个Promise的任务,统一放到一个数组里面,然后再借助Promise.all就知道所有的任务都完成了。这样就拿到了所有已onload的img对象,然后就可以拿来画了。

  在start函数里面添加一个画的函数walk的执行:

  实际上为了画逐帧动画,我们要使用window.requestAnimationFrame,这个函数在浏览器画它自己的动画的下一帧之前会先调一下这个函数,理想情况下,1s有60帧,即帧率为60 fps。因为不管是播放视频还是浏览网页它们都是逐帧的,例如往下滚动网页的时候就是一个滚动的动画,所以浏览器本身也是在不断地在画动画,只是当你的网页停止不动时(且页面没有动画元素),它可能会降低帧率减少资源消耗。

  所以代码改成这样:

  我们使用了一个bind(this),它的作用是让walk函数的执行上下文还是指向当前类的实例。

  现在怎么让狗动起来呢?最简单的我们可以每隔0.1s就画一帧,这样就会连起来,形成一个动画,为此我们需要记录上一次画的时间,然后判断当前时间与上一次的时间是否大于0.1s,如果是的话就画下一帧,否则什么也不用干。因为上文提过,1s最多有60帧,每一帧间隔 1s / 60 = 16.67ms。如下代码所示,先在constructor添加几个变量,包括一个记录上一帧时间的变量:

  然后在walk函数里面进行绘制,在画的时候每次画都取下张图片,即下一帧的图片,不断循环:

  这样我们就有了一只在原地踏步的小狗:

  css翻转效果_css 图片翻转_background-image翻转 css

  然后让它往前走。

  3. 让小狗往前走

  上面在drawImage的传参固定dx = 20,如果不断加大这个dx,那么它就往前走了。为此在构造函数里面添加一个变量记录当前的位移,并设置小狗的速度:

  然后在walk函数里面计算当前累加的位移:

  但是这样我们发现小狗走起路来一卡一卡的,不是很连贯:

  css 图片翻转_background-image翻转 css_css翻转效果

  这个是因为每0.1s画一帧,帧率只有10fps,所以一走起来就不太行了。方法一是让它走慢点,这样可以减缓,但是如果想保持速度甚至提高速度的话,我们得想办法优化一下。

  4. 算法优化

  考虑到狗的控制参数比较集中,把它们写到一个dog的Object里面:

  主要有两个参数,一个是狗的速度另一个是每一步走的位移,然后计算距离方式变成:

  每一步至少走10px,如果小于这个数的话就不走了。通过每步的位移和速度这两个参数可以很方便地控制狗走的快慢和帧率,例如把stepDistance改小点,speed提高就会走得比较频繁,能提高帧率,上面设置的帧率是14 fps. 不过帧率低的根本原因还是在于小狗走路的图片较少。

  5. 走到鼠标的位置停下

  给小狗添加一个停留的位置,包括往前走和往后走的,因为一个是鼠标在图片前面,一个是鼠标在图片的后面,需要区分:

  然后添加一个记录鼠标位置的函数css翻转效果,主要是监听mousemove事件:

  然后在walk函数里面用一个变量stopWalking表示小狗是否停下来,和一个direct表示小狗的方向:

  如果小狗没有停,计算位置的时候乘以direct:

  如果小狗停了,则mouseX还是上次的值。

  鼠标停留在小狗位置的那段代码可以做个优化,如果鼠标在小狗中间的右边,则方向调整为正,否则为负:

  这样鼠标在小狗左右来回移动时,小狗会转头。

  得到小狗的位置和方向之后就是画上去,正方向的还好,反方向的由于没图片,我们通过canvas的翻转flip进行绘制,如下代码所示:

  这样基本上就完成了,最后一个问题是小狗初始化位置的摆放,如果你要把它摆在右边的话,那需要把它的方向反转一下,摆在最左边也需要。不然你会发现小狗摆在左边,但它的头朝左了,需要转一下放在右边。

  一个完整的Demo:Walking Dog.

  图片的素材和绘制过程已说得很详细,读者可以自行实现,或者想其它一些跟着鼠标动的交互效果。

  欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,学习能力的提升上有新的认识,欢迎转发分享给更多人。

  猜你还想看

  阿里、腾讯、百度、华为、京东最新面试题汇集

  超燃!支付宝技术双11纪录片《一心一役》全球独家首发

  LinkedList真的是查找慢增删快?

  如何准备Java初级和高级的技术面试

  关注「程序员小乐」,收看更多精彩内容

  嘿,你在看吗?

文章由官网发布,如若转载,请注明出处:https://www.veimoz.com/1642
0 评论
605

发表评论

!