ToB企服应用市场:ToB评测及商务社交产业平台
标题:
前端常用动画 直接可以用的代码加具体流程和案例 能应付90%的开辟场景
[打印本页]
作者:
十念
时间:
2024-10-15 12:41
标题:
前端常用动画 直接可以用的代码加具体流程和案例 能应付90%的开辟场景
前端项目,特别是Toc的项目,一定少不了各种动效和动画效果。
葫芦七兄弟:
CSS 动画
长处:兼容性强;欣赏器针对的流畅度优化;语法简单;某些属性(如 transform 和 opacity)可以利用 GPU 加速,提高性能;
缺点:复杂的动画和交互难以实现;调试困难;
JavaScript 动画 requestAnimationFrame
长处:可以实现复杂的动画效果和交互;精确控制动画的每一帧;运行时动态天生和修改动画;
缺点:编写和维护复杂;欣赏器兼容性需手动处理;
Web Animations API (WAAPI)
长处:结合了 CSS 动画的性能上风和 JavaScript 的灵活性;可以利用硬件加速。
缺点:旧版本的欣赏器大概不支持;API 较为复杂;
SVG 动画
长处:矢量图形无限缩放而不失真;简单的动画性能好;
缺点:SVG 动画的开辟工具较少;旧版本的欣赏器大概存在问题;
Lottie
长处:可以导入 After Effects 动画,保持高质量的计划;支持 Web、iOS、Android 等多个平台;只需加载 JSON 文件即可渲染动画,无需手动编写动画代码;
缺点:依靠工具;不支持所有 After Effects 特性,某些高级效果大概无法导出;
GSAP (GreenSock Animation Platform)
长处:高性能适合复杂的动画;提供了丰富的动画控制和插值函数;兼容性好;
缺点:API 较为复杂;部分高级功能必要购买商业允许;
Three.js
相对比webgl简单,但都是相当难的一档了。必要大量专业知识。包括但不限于:数学、建模、绘图、3D等。把握熟练后都可以直接转行3D了哈哈哈,一样寻常需求不建议搞这个。
我工作的开辟情况必要考虑兼容性,且有UI支持一部分复杂动画效果,以是常用的方案包括但不限于以下三种:
gsap动画
通过Gsap动画库,可以实现纯前端的动画。从一个dom丝滑变革为另一个dom,或者dom自己巨细变革等。
文档
文档地点 比反人类的swiper文档好用太多
安装
npm install gsap
引入
import gsap from 'gsap'//奖品动画效果
代码1
差别Dom的丝滑切换
const toggleAnimation = (ind) => {
const staticstate = document.querySelector(`.staticstate${ind}`);
const spinner = document.querySelector(`.spinner${ind}`);
gsap.to(staticstate, {
opacity: 0,
duration: 0,
onComplete: () => {
staticstate.style.display = 'none';
spinner.style.display = 'block';
}
});
}
const toggleAnimation2 = (ind) => {
const spinner = document.querySelector(`.spinner${ind}`);
const checkmark = document.querySelector(`.checkmark${ind}`);
gsap.to(spinner, {
opacity: 0,
duration: 0,
onComplete: () => {
gsap.to(checkmark, {
opacity: 1,// 透明度
scale: 1, // 放大效果
duration: 1, // 动画持续时间
ease: 'power1.inOut', // 动画缓动函数
});
}
});
}
复制代码
动画效果1
从未完成 加载中 完成的状态变革的动画
代码2
同一DOM的放大缩小
const toggleAnimation = (ind,reversal) => {
const prize = document.querySelector(`.prize-prize${ind}`);
gsap.to(prize, {
opacity: 1,// 透明度
scale: reversal?1.05:0.9, // 放大缩小效果
duration: 1.5, // 动画持续时间
ease: 'power1.inOut', // 动画缓动函数
onComplete: () => {
gsap.to(prize, {
opacity: 1,// 透明度
scale: reversal?0.9:1.05, // 放大缩小效果
duration: 1, // 动画持续时间
ease: 'power1.inOut', // 动画缓动函数
});
}
});
}
复制代码
动画效果2
附近悬浮的就是gsap动画效果
中间的是lottie-JSON(png)动画,下面就会讲到
lottie-web
这个必要依靠UI 使用Adobe After Effects【AE】制作动画,导出对应的JSON文件后使用
文档
文档地点
仓库
文档地点
安装
npm install lottie-web
引入
import lottie from 'lottie-web';//JSON动画接入
lottie JSON动画(svg)
引入项目打开后看到大概是如许,SVG范例没有附加文件,通过点和线的计算绘制就可以实现动画效果
lottie JSON动画(png)
引入项目打开后看到大概是如许,PNG范例有附加文件,实现的效果一样寻常较为复杂,必要通过底子的图片来实现动画。
这时会涉及到引用路径的问题
因为无法再JSON中使用相对路径和vite的import.meta.url
以是我把他们放在了public目录下,克制被打包附加的哈希值影响
序列帧动画
当动画复杂度超出一定程度时,JSON动画会无法承载,导出会丢失样式【UI说的】。以是这时前端就必要接入帧动画了。
帧动画,顾名思义就是把每一帧的图片都给到前端,然后手动组装举行播放。
解决思路有很多,我这里为了分身在安卓和IOS差别情况、webview版本下的播放效果【IOS特别注意因内存机制会有闪耀问题 改用雪碧图方案 计算位移和预加载略麻烦但效果和兼容性很好】
提供以下两种思路:
-------------------------html
<van-overlay style="z-index: 2;" :show="frameAnimation" :lock-scroll="false">
<div id="frameAnimationDom" class="title-bg"></div>
</van-overlay>
---------------------------JS
let timer4;//动画计时器
function preLoad() {// 预加载帧动画图片
const frameCount = 58; // 帧数
for (let i = 0; i <= frameCount; i++) {
const img = new Image();
img.src = new URL(`../assets/images/blind/frame/${i}.png`,import.meta.url).href;
images.value.push(img);
}
frameAnimation.value = true;
// 方案一 帧动画
setTimeout(()=>{//确认支付后再播放动画开奖
const frameCount = 58; // 帧数
const frameElement = document.getElementById('frameAnimationDom');
let currentFrameIndex = 0;
let lastTime = 0;
function animate() {
if (new Date().getTime() - lastTime >= 40) { // 40毫秒一帧 一秒25帧
frameElement.style.backgroundImage = `url(${images.value[currentFrameIndex].src})`;
currentFrameIndex = (currentFrameIndex + 1) % frameCount;
lastTime = new Date().getTime();
}
timer4 = requestAnimationFrame(animate);
}
// 开始动画
animate();
},200)
// 方案2 雪碧图
// animate();
// const frameCount = 51; // 总帧数
// const frameWidth = 780; // 每帧宽度
// let currentFrame = 0;
// let lastTime = 0;
// function animate() {
// if (new Date().getTime() - lastTime >= 75) { // 75毫秒一帧 一秒13帧?
// const frameElement = document.getElementById('frameAnimationDom');
// const offset = currentFrame*(100/50);
// frameElement.style.backgroundPosition = `${offset}% 0%`;
// currentFrame = (currentFrame + 1) % frameCount;
// lastTime = new Date().getTime();
// }
// timer4 = requestAnimationFrame(animate);
// }
setTimeout(()=>{
cancelAnimationFrame(timer4)// 清除动画循环
timer4 = null; // 重置 ID
frameAnimation.value = false;
},2650)
-------------------------css
// 方案1 帧动画
.title-bg{
width: 375px;
height: 812px;
background-size: 100% 100%;
margin: 0 auto 0 auto;
}
// 方案2 雪碧图
// .title-bg{
// width: 375px;
// height: 812px;
// background-image: url(../assets/images/blind/sprites.png);//动态高度做展开 后由于图片过多改为滚动展示
// background-size: auto 100%; /* 确保背景图像的高度与容器高度一致 */
// margin: 0 auto 0 auto;
// }
复制代码
未完待续…【不过一样寻常的需求这些方式也都足够了,其他的我遇到了再补充,码友们也可以作为思路再自己向外拓展哈~】
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4