爆炸动效分享


前言

此次分享是一次自我组件开发的总结,还是有很多不足之处,望各位大大多提宝贵意见,互相学习交流。

分享内容介绍

通过原生js代码,实现粒子爆炸效果组件 组件开发过程中,使用到了公司内部十分高效的工程化环境,特此打个广告:新浪移动诚招各种技术大大!可以私聊投简历哦!

效果预览

效果分析

  • * 点击作为动画开始的起点,自动结束

  • * 每次效果产生多个抛物线粒子运动的元素,方向随机,展示内容不一样,有空间上Z轴的大小变化

  • * 需求上可以无间隔点击,即第一组动画未结束可播放第二组动画

  • * 动画基本执行时长一致

  • css操作态变换(如focus)使子元素执行动画

`不可取,效果可多次连点,css状态变换与需求不符`

  • Js 控制动画开始,事先写好css动画预置,通过class 包含选择器切换动画 例如:.active .items{animation:xxx ...;}

`不可取,单次执行动画没有问题,但是存在效果的固定,以及无法连续执行动画`

  • 事先写好大量动画,隐藏大量dom元素,动画开始随机选取dom元素执行自己唯一的动画keyframes

`实现层面来说,行得通,但是评论列表长的时候,dom数量巨大,且css大量动画造成代码量沉重、无随机性`

  • 抛弃css动画,使用canvas 绘制动画

`可行,但是canvas维护成本略高,且自定义功能难设计,屏幕适配也有一定成本`

  • js做dom创建,生成随机css @keyframes

`可行,但是创建style样式表,引发css重新渲染页面,会导致页面的性能下降,且抛物线css的复杂度不低,暂不作为首选`

  • js 刷帧 做dom渲染

`可行,但是刷帧操作会造成性能压力`

结论

canvas虽说可行,但由于其开发弊端 本次分享不以canvas为分享内容,而是使用最后一种 js刷帧的dom操作

组件结构

由截图分享,动画可以分为两个模块,首先,随机发散的粒子具有共性:抛物线动画,淡出,渲染表情

而例子数量变多之后则为截图中的效果

但是,由于性能原因,我们需要做到粒子的掌控,实现资源再利用,那么还需要第二个模块,作为粒子的管控组件

所以:此功能可使用两个模块进行开发:partical.js 粒子功能 与 boom.js 粒子管理


实现 Partical.js

1. 前置资源:抛物线运动的物理曲线需要使用Tween.js提供的速度函数

若不想引入Tween.js 可以使用以下代码

/** Tween.js* t: current time(当前时间);* b: beginning value(初始值);* c: change in value(变化量);* d: duration(持续时间)。* you can visit '缓动函数速查表' to get effect*/            
        const Quad = {
    easeIn: function(t, b, c, d) {
        return c * (t /= d) * t + b;
    },
    easeOut: function(t, b, c, d) {
        return -c *(t /= d)*(t-2) + b;  
    },
    easeInOut: function(t, b, c, d) {
        if ((t /= d / 2) < 1) return c / 2 * t * t + b;
        return -c / 2 * ((--t) * (t-2) - 1) + b;
    }}const Linear = function(t, b, c, d) { 
     return c * t / d + b; }

2. 粒子实现

实现思路:

希望在粒子管控组件时,使用new partical的方式创建粒子,每个粒子存在自己的动画开始方法,动画结束回调。

由于评论列表可能存在数量巨大的情况,我们希望只全局创建有限个数的粒子,那么则提供呢容器移除粒子功能以及容器添加粒子的功能,实现粒子的复用

partical_style.css

//粒子充满粒子容器,需要容器存在尺寸以及relative定位.Boom-Partical_Holder{
    position: absolute;
    left:0;
    right:0;
    top:0;
    bottom:0;
    margin:auto;}

particle.js

import "partical_style.css";
        class Partical{
    // dom为装载动画元素的容器 用于设置位置等样式
    dom = null;
    // 动画开始时间
     StartTime = -1;
    // 当前粒子的动画方向,区别上抛运动与下抛运动
    direction = "UP";
    // 动画延迟
    delay = 0;
    // 三方向位移值
    targetZ = 0;
    targetY = 0;
    targetX = 0;
    // 缩放倍率
    scaleNum = 1;
    // 是否正在执行动画
    animating = false;
    // 粒子的父容器,标识此粒子被渲染到那个元素内
    parent = null;
    // 动画结束的回调函数列表
    animEndCBList = [];
    // 粒子渲染的内容容器 slot
    con = null;     constructor(){
        //创建动画粒子dom
        this.dom = document.createElement("div");
        this.dom.classList.add("Boom-Partical_Holder");
        this.dom.innerHTML = `            <div class="Boom-Partical_con">                Boom            </div>        `;
    }     // 在哪里渲染
    renderIn(parent) {
        // dom判断此处省略
        parent.appendChild(this.dom);
        this.parent = parent;
        // 此处为初始化 slot 容器
        !this.con && ( this.con = this.dom.querySelector(".Boom-Partical_con"));
     }      // 用于父容器移除当前粒子
     deleteEl(){
         // dom判断此处省略
         this.parent.removeChild(this.dom);
     }      // 执行动画,需要此粒子执行动画的角度,动画的力度,以及延迟时间
     animate({ deg, pow, delay } = {}){
         // 后续补全
     }      // 动画结束回调存储
     onAnimationEnd(cb) {
         if (typeof cb !== 'function') return;
         this.animEndCBList.push(cb);
     }      // 动画结束回调执行
     emitEndCB() {
         this.dom.style.cssText += `;-webkit-transform:translate3d(0,0,0);opacity:1;`;
         this.animating = false;
         try {
             for (let cb  of this.animEndCBList) {
                  cb();
             }
         } catch (error) {
             console.warn("回调报错:",cb);
         }
     }      // 简易实现slot功能,向粒子容器内添加元素
     insertChild(child){
         this.con.innerHTML = '';
         this.con.appendChild(child);
     }}

致此,我们先创建了一个粒子对象的构造函数,现在考虑一下我们实现了我们的设计思路吗?

  • * 使用构造函数new Partical( )粒子

  • * 粒子实力对象存在 animate 执行动画方法

  • * 有动画结束回调函数的存储和执行

  • * 设置粒子的父元素: renderIn 方法

  • * 父元素删除粒子: deleteEl 方法

为了更好的展示粒子内容,我们特意在constructor里创建了一个 Boom-Partical_con 元素用于模拟slot功能: insertChild方法,用于使用者展示不同的内容进行爆炸

【CSS】398- 原生JS实现DOM爆炸效果的更多相关文章

  1. 框架操作DOM和原生js操作DOM比较

    问题引出 对于Angular和React操作DOM的速度,和原生js操作DOM的速度进行了一个比较: 一个同学做的demo 代码如下: <!DOCTYPE html> <html n ...

  2. 面向对象原生js幻灯片代淡出效果

    面向对象原生js幻灯片代淡出效果 下面是代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" & ...

  3. 原生JS封装简单动画效果

    原生JS封装简单动画效果 一致使用各种插件,有时候对原生JS陌生了起来,所以决定封装一个简单动画效果,熟悉JS原生代码 function animate(obj, target,num){ if(ob ...

  4. 原生js实现的放大镜效果

    这是我用原生js写的放大镜效果,与各种各样的框架技术相比,我喜欢使用原生的js,在这里,想和大家一起谈谈原生和框架技术的理解与个人喜好. <!DOCTYPE HTML><html&g ...

  5. jq与原生js实现收起展开效果

    jq与原生js实现收起展开效果 (jq需自己加载) <!DOCTYPE html> <html> <head> <meta charset="UTF ...

  6. 原生JS获取DOM 节点到浏览器顶部的距离或者左侧的距离

    关于js获取dom 节点到浏览器顶/左部的距离,Jquery里面有封装好的offset().top/offset().left,只到父级的顶/左部距离position().top/position() ...

  7. 原生js操作Dom节点:CRUD

    知识点,依然会遗忘.我在思考到底是什么原因.想到研究生考试准备的那段岁月,想到知识体系的建立,知识体系分为正向知识体系和逆向知识体系:正向知识体系可以理解为教科书目录,逆向知识体系可以理解考试真题. ...

  8. 关于Echarts的原生js获取DOM元素与动态加载DOM元素的冲突问题

    1.前言: 最近在做的看板项目,因为需要循环加载后台数据,并且用Echarts做数据呈现,所以jQuery和angular等库统统靠边站,Echarts用的是原生js获取DOM元素,至于诸多不兼容等深 ...

  9. 原生js操作dom的方法

    今天学习了原生js的dom节点的操作,就记录下来,仅供自己以后参考. 1)创建节点:除了可以使用createElement创建元素,也可以使用createTextNode创建文本节点. documen ...

随机推荐

  1. Asciinema文章勘误及Web端使用介绍

    欠下的债迟早是要还的,查文档,重验证,出结果,不误导 文章勘误 在上一篇文章Asciinema:你的所有操作都将被录制中有两个地方表述有错误或瑕疵,这里更正一下 第一个地方为录制时的参数--stdin ...

  2. django 中 css文件的调用

    Django: 配置css文件 晚上搞了好久的css文件的调用,发现,我根本文件位置都放错了. 接下来要更改settings.py 和 urls.py 的设定. Settings.py 中应该: ur ...

  3. 管理系统和服务systemctl(centos6:chkconfig、service命令)

    传统:SysV init 红帽6.Ubuntu6:采用Upstart 红帽7:采用全新的Systemd SysV init运行级别,主题思想是串行的启动所有将来需要用到的服务(所以计算机没有利用多CP ...

  4. node.js传参给PHP失败,headers加上'Content-Length': Buffer.byteLength(content)

    node.js需要传参给PHP,执行计划任务 var events = require('events'); start_cron(,,{"auth":"7wElqW6v ...

  5. 11.13的C++##不想写结构,更不爱指针

    //2019.11.13 卑微的Loving-Q瞎写的程序 报错请更改VS中的SDL检查// 我要去嗨了,在线卑微 1 #include<iostream> #include<std ...

  6. js数组之sort()函数

    一般我们使用sort函数进行数组的排序,sort()方法有一个可选参数,是用来确定元素顺序的函数.如果这个参数被省略,那么数组中的元素将按照ASCII字符顺序进行排序.如: var arr = [&q ...

  7. beego框架学习--beego orm映射

    什么是ORM 即Object-Relationl Mapping,它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作 ...

  8. Git之GitFlow工作流

    一. GitFlow 介绍 1.1 什么是 GitFlow GitFlow 是一种 Git 工作流,它是团队成员遵守的一种代码管理方案 . 1.2 GitFlow 常用分支说明 分支名称 分支说明 P ...

  9. java中sleep()和wait()区别

    1,sleep方法是Thread类的静态方法,wait()是Object超类的成员方法 2,sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时 ...

  10. Kafka原理详解

    Kafka是最初由Linkedin公司开发,是一个分布式.支持分区的(partition).多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量 ...