使用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月前
|
前端开发 UED
Webpack 中处理 CSS 和图片资源的多 Loader 配置
【10月更文挑战第12天】 处理 CSS 和图片资源是 Webpack 配置中的重要部分。通过合理选择和配置多个 Loader,可以实现对这些资源的精细处理和优化,提升项目的性能和用户体验。在实际应用中,需要不断探索和实践,根据项目的具体情况进行灵活调整和优化,以达到最佳的处理效果。通过对 Webpack 中多 Loader 处理 CSS 和图片资源的深入了解和掌握,你将能够更好地应对各种复杂的资源处理需求,为项目的成功构建和运行提供坚实的基础。
56 1
|
3月前
|
前端开发
如何使用 CSS object-fit 进行图片的缩放和裁剪
如何使用 CSS object-fit 进行图片的缩放和裁剪
91 0
如何使用 CSS object-fit 进行图片的缩放和裁剪
|
3月前
|
前端开发
视觉冲击:CSS实现相册图片的放大效果,让网站首页更震撼!
视觉冲击:CSS实现相册图片的放大效果,让网站首页更震撼!
|
4月前
|
前端开发 容器
CSS【详解】对齐 (含文本垂直对齐,文本水平对齐、单行文本垂直居中、多行文本垂直居中、6 种方案块级元素水平垂直居中 、7 种方案图片水平垂直居中、文本自适应对齐、图标和文本对齐,图片和文本对齐等)
CSS【详解】对齐 (含文本垂直对齐,文本水平对齐、单行文本垂直居中、多行文本垂直居中、6 种方案块级元素水平垂直居中 、7 种方案图片水平垂直居中、文本自适应对齐、图标和文本对齐,图片和文本对齐等)
78 0
|
4月前
|
前端开发 C++
css 鼠标悬浮显示放大图片 vs 鼠标点击显示放大图片
css 鼠标悬浮显示放大图片 vs 鼠标点击显示放大图片
52 0
|
4月前
|
前端开发 UED
前端 CSS 经典:在 Vue3 中使用渐进式图片
前端 CSS 经典:在 Vue3 中使用渐进式图片
114 0
|
4月前
|
前端开发
前端 CSS 经典:图片边框
前端 CSS 经典:图片边框
39 0
|
4月前
|
前端开发 容器
css 【详解】—— 图片底部留有间隙(含解决方案)
css 【详解】—— 图片底部留有间隙(含解决方案)
134 0
|
4月前
|
Web App开发 前端开发
css小技巧——鼠标悬浮时切换图片
css小技巧——鼠标悬浮时切换图片
393 0
|
4月前
|
前端开发
css实用技巧——异步加载图片时,在图片完成加载前,鼠标悬浮到占位图片上时显示图片的alt信息
css实用技巧——异步加载图片时,在图片完成加载前,鼠标悬浮到占位图片上时显示图片的alt信息
27 0