使用CSS实现 图片帧动画 与 曲线运动

简介: 使用CSS实现 图片帧动画 与 曲线运动

640.jpg

写在前面


在前端开发中,提到动画,我们可以:

  1. 直接利用DOM实现动画。
  2. 利用canvas实现动画。
  3. 利用svg实现动画。
  4. 直接用一张gif动图。
  5. 利用图片实现帧动画。


所有动画的基本原理都是:在短时间内连续依次展示对应的图片,这样在视觉上看起来就是'动'的了。


最近又开发了一个运营活动,逻辑比较复杂,交互上也有一定的要求。本文总结一下开发过程中的两个点:图片帧动画 和 css实现曲线运动。


图片帧动画


当我们要实现的动画效果比较复杂,而且开发排期比较紧的情况下,用一张gif动图来实现动画是成本最低,效果也不错的一种方案。比如下面这种动画效果:


640.gif

可是如果想让动效在某个时候暂停,隔一段时间后,再从断点开始继续播放动效,用gif图就实现不了了。gif图的动效是没有办法暂停的。这个时候,可以考虑采用图片帧动画。


图片帧动画可以看做是:把gif图的原理在前端用代码实现了一遍。

上面那个动效,(假设)可以分成100帧,即100张图片,然后用代码控制100张图片依次显示。并且,可以随时在中途暂停。


为了节省http请求,把100张图片合成一张雪碧图,然后用background-position去控制显示哪一张图。这里推荐一个很不错的图片生成工具:GKA

我把100张图片生成了一个竖直的雪碧图。

640.png


在代码里,只需要更新DOM元素的background-position即可实现动画。

首先第一个点需要注意:background-position设置的是背景图片相对于DOM元素的起始位置。

假设DOM元素和图片宽高都是 100 * 200


--- css
#wrapper {  width: 100px;  height: 200px;  background-image: url('雪碧图.png');  background-size: 100% 10000%; // 有100张图, 100*100  background-repeat: no-repeat;}
--- js
var domEl = document.querySelector('#wrapper');var n; // n:显示雪碧图中第几张图片,n >=0 && n<100domEl.style.backgroundPosition = `0px ${-n*200}px`; // 注意这里是负值

我们只需要用js控制n的值就行,就可以很容易实现随时执行、暂停动效

上面的例子中,dom元素宽高是固定的,如果不固定、想要自适应的话,需要根据图片宽高比,通过padding-top来设置dom元素的宽高比。这个时候,在background-position中,也无法使用具体的数值了,需要使用百分比。这里有一个需要注意的地方:

background-position百分比取值时,很自然的以为是直接用背景图片宽高乘以百分比即可得到最终偏移量,但其实不是的。计算公式如下:


x偏移量 = (元素宽度—背景图片的宽度)*x百分比y偏移量 = (元素高度—背景图片的高度)*y百分比

换算一下:


x百分比 = x偏移量 / (元素宽度 - 背景图片宽度)y百分比 = y偏移量 / (元素高度 - 背景图片高度)

具体到上面的例子中,就是:


// 假设每一张小图片宽度为w, 高度为h, 当前需要展示第n张图片,一共有100张图,则var xPercent = 0;var yPercent = -hn / (h - 100h) * 100 =  n / 99 * 100;domEl.style.backgroundPosition = `${xPercent}% ${yPercent}%`;

最终,我们就能实现图片帧动画了。当然,如果不需要完全控制动画效果,可以不借助js,直接用css即可。或者直接用gif动图就好。


CSS曲线运动


曲线运动,使用svg,canvas是很不错的选择。但是在对曲线的路径不那么严格要求的时候,使用svg和canvas或许略微麻烦了。可以直接用css来实现一个『看起来是曲线』的运动。以类似抛物线的一个运动为例,大概是一个这样的效果:

640.gif



位移曲线上某点的切线就是速度,而速度可以分解成x轴的速度和y轴的速度。也就是说,上面的运动可以分解成水平方向x轴的运动和竖直方向y轴的运动。从感官上,不难看出,x轴的运动大概是匀速的,而y轴的运动是越来越快的。


另外,由于运动分解成了两个方向的运动,需要两个DOM,分别写动画,才能实现最终的效果。


--- html
<div class='x-container'>  <div class='y-container'></div></div>
--- css
.x-container {    width: 50px;    height: 50px;    animation: xMove 2s linear;}.y-container {    width: 50px;    height: 50px;    border-radius: 50%;    background-color: #000;    animation: yMove 2s cubic-bezier(.98,.03,.91,.77);}@keyframes xMove {    0% {    }    100% {      transform: translateX(400px);    }}@keyframes yMove {    0% {    }    100% {      transform: translateY(400px);    }}

两个方向的运动合起来,就是上面的效果了。关于animation属性中的运动曲线,可以参考下面这个网站:


https://cubic-bezier.com/


想要实现一个不那么严格的曲线运动,直接使用css animation,也是一个不错的选择。


写在后面


本文总结了依赖css实现图片帧动画和曲线运动的实例。在合适的场景下,使用这两种方法,或许能够达到不错的效果。符合预期。

相关文章
|
1月前
|
前端开发 计算机视觉 开发者
利用CSS改变图片颜色的100种方法!
利用CSS改变图片颜色的100种方法!
34 1
|
1月前
css3鼠标悬停图片特效源码
css3鼠标悬停图片特效,图片悬停效果源码,可以在网页上面作为自己的动态加载名片,放到侧边栏或者网站合适的位置即可
14 0
css3鼠标悬停图片特效源码
|
1月前
|
Web App开发 前端开发 iOS开发
编程笔记 html5&css&js 008 HTML图片
编程笔记 html5&css&js 008 HTML图片
|
2月前
CSS3图片反射box-reflect属性
CSS3图片反射box-reflect属性
23 0
|
3月前
|
前端开发
html+css实现图片缓慢变大效果
html+css实现图片缓慢变大效果
37 0
|
4月前
|
前端开发
【CSS】解决图片和盒子底部产生的缝隙问题
【CSS】解决图片和盒子底部产生的缝隙问题
|
4月前
|
前端开发
css文字环绕png图片
css文字环绕png图片
38 1
|
4月前
|
前端开发
css background图片
css background图片
27 1
|
5月前
|
前端开发
CSS实现鼠标悬停图片向上浮动,放大,翻转
CSS实现鼠标悬停图片向上浮动,放大,翻转
118 0
|
5月前
|
前端开发
CSS使图片居中的三种方法
CSS使图片居中的三种方法