ToB企服应用市场:ToB评测及商务社交产业平台

标题: 前端常用动画 直接可以用的代码加具体流程和案例 能应付90%的开辟场景 [打印本页]

作者: 十念    时间: 2024-10-15 12:41
标题: 前端常用动画 直接可以用的代码加具体流程和案例 能应付90%的开辟场景
前端项目,特别是Toc的项目,一定少不了各种动效和动画效果。
葫芦七兄弟:


我工作的开辟情况必要考虑兼容性,且有UI支持一部分复杂动画效果,以是常用的方案包括但不限于以下三种:
gsap动画

通过Gsap动画库,可以实现纯前端的动画。从一个dom丝滑变革为另一个dom,或者dom自己巨细变革等。

  1.   const toggleAnimation = (ind) => {
  2.     const staticstate = document.querySelector(`.staticstate${ind}`);
  3.     const spinner = document.querySelector(`.spinner${ind}`);
  4.     gsap.to(staticstate, {
  5.         opacity: 0,
  6.         duration: 0,
  7.         onComplete: () => {
  8.             staticstate.style.display = 'none';
  9.             spinner.style.display = 'block';
  10.         }
  11.     });
  12.   }
  13.   const toggleAnimation2 = (ind) => {
  14.     const spinner = document.querySelector(`.spinner${ind}`);
  15.     const checkmark = document.querySelector(`.checkmark${ind}`);
  16.     gsap.to(spinner, {
  17.         opacity: 0,
  18.         duration: 0,
  19.         onComplete: () => {
  20.           gsap.to(checkmark, {
  21.               opacity: 1,// 透明度
  22.               scale: 1, // 放大效果
  23.               duration: 1, // 动画持续时间
  24.               ease: 'power1.inOut', // 动画缓动函数
  25.           });
  26.         }
  27.     });
  28.   }
复制代码

  1.   const toggleAnimation = (ind,reversal) => {
  2.     const prize = document.querySelector(`.prize-prize${ind}`);
  3.     gsap.to(prize, {
  4.         opacity: 1,// 透明度
  5.         scale: reversal?1.05:0.9, // 放大缩小效果
  6.         duration: 1.5, // 动画持续时间
  7.         ease: 'power1.inOut', // 动画缓动函数
  8.         onComplete: () => {
  9.           gsap.to(prize, {
  10.               opacity: 1,// 透明度
  11.               scale: reversal?0.9:1.05, // 放大缩小效果
  12.               duration: 1, // 动画持续时间
  13.               ease: 'power1.inOut', // 动画缓动函数
  14.           });
  15.         }
  16.     });
  17.   }
复制代码

lottie-web

这个必要依靠UI 使用Adobe After Effects【AE】制作动画,导出对应的JSON文件后使用

序列帧动画

当动画复杂度超出一定程度时,JSON动画会无法承载,导出会丢失样式【UI说的】。以是这时前端就必要接入帧动画了。
帧动画,顾名思义就是把每一帧的图片都给到前端,然后手动组装举行播放。

解决思路有很多,我这里为了分身在安卓和IOS差别情况、webview版本下的播放效果【IOS特别注意因内存机制会有闪耀问题 改用雪碧图方案 计算位移和预加载略麻烦但效果和兼容性很好】
提供以下两种思路:
  1. -------------------------html
  2.       <van-overlay style="z-index: 2;" :show="frameAnimation" :lock-scroll="false">
  3.         <div id="frameAnimationDom" class="title-bg"></div>
  4.       </van-overlay>
  5.       
  6. ---------------------------JS
  7. let timer4;//动画计时器
  8.   function preLoad() {// 预加载帧动画图片
  9.     const frameCount = 58; // 帧数
  10.     for (let i = 0; i <= frameCount; i++) {
  11.         const img = new Image();
  12.         img.src = new URL(`../assets/images/blind/frame/${i}.png`,import.meta.url).href;
  13.         images.value.push(img);
  14.     }
  15.           frameAnimation.value = true;
  16.          
  17.           // 方案一 帧动画
  18.           setTimeout(()=>{//确认支付后再播放动画开奖
  19.             const frameCount = 58; // 帧数
  20.             const frameElement = document.getElementById('frameAnimationDom');
  21.             let currentFrameIndex = 0;
  22.             let lastTime = 0;
  23.             function animate() {
  24.                 if (new Date().getTime() - lastTime >= 40) { // 40毫秒一帧  一秒25帧
  25.                     frameElement.style.backgroundImage = `url(${images.value[currentFrameIndex].src})`;
  26.                     currentFrameIndex = (currentFrameIndex + 1) % frameCount;
  27.                     lastTime = new Date().getTime();
  28.                 }
  29.                 timer4 = requestAnimationFrame(animate);
  30.             }
  31.             // 开始动画
  32.             animate();
  33.           },200)
  34.           // 方案2  雪碧图
  35.           // animate();
  36.           // const frameCount = 51; // 总帧数
  37.           // const frameWidth = 780; // 每帧宽度
  38.           // let currentFrame = 0;
  39.           // let lastTime = 0;
  40.           // function animate() {
  41.           // if (new Date().getTime() - lastTime >= 75) { // 75毫秒一帧  一秒13帧?
  42.           //  const frameElement = document.getElementById('frameAnimationDom');
  43.           // const offset = currentFrame*(100/50);
  44.           //  frameElement.style.backgroundPosition = `${offset}% 0%`;
  45.           //   currentFrame = (currentFrame + 1) % frameCount;
  46.           //  lastTime = new Date().getTime();
  47.           //  }
  48.           //   timer4 = requestAnimationFrame(animate);
  49.           // }
  50.   setTimeout(()=>{
  51.     cancelAnimationFrame(timer4)// 清除动画循环
  52.     timer4 = null; // 重置 ID
  53.     frameAnimation.value = false;
  54.   },2650)
  55. -------------------------css
  56. //  方案1  帧动画
  57. .title-bg{
  58.   width: 375px;
  59.   height: 812px;
  60.   background-size: 100% 100%;
  61.   margin: 0 auto 0 auto;
  62. }
  63.   
  64. //  方案2  雪碧图
  65. // .title-bg{  
  66. //   width: 375px;
  67. //   height: 812px;
  68. //   background-image: url(../assets/images/blind/sprites.png);//动态高度做展开  后由于图片过多改为滚动展示
  69. //   background-size: auto 100%; /* 确保背景图像的高度与容器高度一致 */
  70. //   margin: 0 auto 0 auto;
  71. // }
复制代码
未完待续…【不过一样寻常的需求这些方式也都足够了,其他的我遇到了再补充,码友们也可以作为思路再自己向外拓展哈~】

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4