JS烟花案例优化版
不明白为什么是烟花优化版本的先参考作者的烟花基础版本
烟花优化版本主要实在优化爆炸的范围和运动上做了优化,爆炸范围我们采用已圆的爆炸方式,以鼠标点击的位置为圆形爆炸的烟花效果
<!DOCTYPE html>
<!--
* @Descripttion:
* @version:
* @Author: 小小荧
* @Date: 2020-03-18 19:15:15
* @LastEditors: 小小荧
* @LastEditTime: 2020-03-18 20:31:12
-->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container {
width: 80%;
height: 600px;
border: 2px solid red;
background: #000;
margin: 20px auto;
cursor: pointer;
position: relative;
left: 0;
top: 0;
overflow: hidden;
}
.fire {
width: 10px;
height: 10px;
position: absolute;
bottom: 0;
}
</style>
</head>
<body>
<div class="container"></div>
<script src="./js/animate.js"></script>
<script src="./js/utils.js"></script>
<script src="./js/index.js"></script>
<script>
let container_ele = document.querySelector(".container");
container_ele.addEventListener("click", function(evt){
var e = evt || event;
new FireWork(e.offsetX, e.offsetY, ".container", "circular");
})
</script>
</body>
</html>
运动函数部分
/*
* @Descripttion:
* @version:
* @Author: 小小荧
* @Date: 2020-03-17 18:01:21
* @LastEditors: 小小荧
* @LastEditTime: 2020-03-18 20:49:13
*/
/**
* 多属性的动画函数
* @param {*} ele 需要运动的节点
* @param {*} attr_options 传入的是一个需要运动的属性包括运动的目标值,操作的节点属性
* @param {*} timefn 运动的形式,默认是缓冲运动
* @param {*} speed 运动的速度
*/
function animate(ele, attr_options, callback, timefn = "swing", speed = 5) {
// 我们需要把传入的options处理成
/*
{“width : {
target : 200,
iNow : 100
}}这个形式
*/
for (var attr in attr_options) {
attr_options[attr] = {
target: attr === "opacity" ? parseInt(attr_options[attr] * 100) : attr_options[attr],
// 需要计算得到
iNow: attr === "opacity" ? parseInt(getComputedStyle(ele)[attr] * 100) : parseInt(getComputedStyle(ele)[attr])
}
}
// 为了防止每个节点的定时器冲突,每次进入的时候我们需要先清理下节点的定时器
clearInterval(ele.timer);
// 然后再去设置定时器
ele.timer = setInterval(function () {
// 因为是多属性运动,我们首先循环遍历每一个属性
for (var attr in attr_options) {
var target = attr_options[attr].target;
var iNow = attr_options[attr].iNow;
// 计算speed 判断是不是缓冲运动
if (timefn === "swing") {
speed = (target - iNow) / 20;
// 为了防止速度无法达到一个整数
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
}
// 判断是不是匀速运动
else if (timefn === "liner") {
speed = attr_options[attr].iNow < attr_options[attr].target ? Math.abs(speed) : -Math.abs(speed);
}
// 运动之中条件的判断
if (Math.abs(target - iNow) <= Math.abs(speed)) {
console.log(1);
if (attr === "opacity") {
ele.style[attr] = target / 100;
} else {
ele.style[attr] = target + "px";
}
// 每次一个属性运动完成之后我们就直接将它删除
delete attr_options[attr];
// 每次都去循环看一下还有没有属性需要操作
for (var num in attr_options) {
return false;
}
// 清理定时器 因为我们是一个定时器绑定多个属性操作所以我们需要保证所有的属性都完成之后我们才可以将定时器清除
clearInterval(ele.timer);
// 等结束之后我们需要判断这个回到函数是函数我们就回调
typeof callback === "function" ? callback() : ""
} else {
attr_options[attr].iNow += speed;
if (attr === "opacity") {
ele.style[attr] = attr_options[attr].iNow / 100;
} else {
ele.style[attr] = attr_options[attr].iNow + "px";
}
}
}
}, 30);
}
工具类
let res = "#";
for (let i = 0; i < 6; i++) {
res += parseInt(Math.random() * 10).toString(16);
}
return res;
核心烟花JS代码
/*
* @Descripttion:
* @version:
* @Author: 小小荧
* @Date: 2020-03-18 19:16:48
* @LastEditors: 小小荧
* @LastEditTime: 2020-03-21 13:51:37
*/
class FireWork {
// 构造器
/**
*
* @param {*} x x轴坐标
* @param {*} y y轴坐标
* @param {*} seletor 选择器名
*/
constructor(x, y, seletor, blastType) {
// 父容器的节点 单例模式,因为这个父盒子只有一个随意每次创建烟花的时候我们需要判断一下,如果存在了这个父盒子我们就不需要再去冲去获取节点元素了
if(FireWork.main && FireWork.main.seletor === seletor){
this.main = FireWork.main.ele;
console.log("dasd");
}else {
FireWork.main = {
ele : document.querySelector(seletor),
seletor : seletor,
}
this.main = FireWork.main.ele;
}
this.blastType = blastType;
// 初始化
this.init(x, y);
}
/**
* 初始化方法
* @param {*} x x的坐标
* @param {*} y y的坐标
*/
init(x, y) {
this.x = x;
this.y = y;
// 创建的烟花的节点
this.ele = this.createFireWorkEle();
// 运动的最大left值
this.left_max = this.main.offsetWidth - this.ele.offsetWidth;
// 运动的最大的top值
this.top_max = this.main.offsetHeight - this.ele.offsetHeight;
// 设置烟花的开始颜色
this.randomColor(this.ele);
// 烟花开始运动
this.fireworkUp(this.ele);
}
/**
* 创建烟花的元素
*/
createFireWorkEle() {
// 创建节点
let ele = document.createElement("div");
// 设置类名
ele.className = "fire";
// 在父容器追加节点
this.main.appendChild(ele);
return ele;
}
/**
*
* 烟花运动的方法
* @param {*} ele 运动的这个烟花
*/
fireworkUp(ele) {
// 设置left
ele.style.left = this.x + "px";
// 烟花向上的运动我们使用animate动画
animate(ele, {
top: this.y,
}, () => {
// 等到这个烟花运动结束之后呢我们需要将这个烟花给删除了
ele.parentNode.removeChild(ele);
// 结束之后烟花开始爆炸
this.fireworkBlast();
});
}
/**
* 烟花爆炸的方法
*/
fireworkBlast() {
// 我们设置爆炸的数量为20
for (let i = 0; i < 20; i++) {
// 我们需要重新创建烟花的元素
let ele = this.createFireWorkEle();
// 给元素设置随机背景颜色和left,top,圆角属性值
this.randomColor(ele);
ele.style.left = this.x + "px";
ele.style.top = this.y + "px";
ele.style.borderRadius = "50%";
// 然后我们需要让这些元素开始运动,先获取随机坐标带你
animate(ele, this.blastType === "circular" ? this.circularBlast(i, 20) : this.randomPos(), () => {
// 删除烟花
ele.parentNode.removeChild(ele)
});
}
}
/**
* 原型烟花爆炸状态
* @param {*} now_index 当前的元素下标
* @param {*} total 总共的下标
*/
circularBlast(now_index, total) {
// 设定圆的半径为100
let r = 100;
// 我们需要计算圆的角度
let deg = now_index / total * 360;
// 在计算弧度
let reg = Math.PI / 180 * deg;
// 返回结果
return {
left: parseInt(Math.cos(reg) * r) + this.x,
top: parseInt(Math.sin(reg) * r) + this.y,
}
}
/**
* 随机获取坐标点
*/
randomPos() {
return {
left: Math.round(Math.random() * this.left_max),
top: Math.round(Math.random() * this.top_max)
}
}
/**
*
* 随机背景颜色
* @param {*} ele 小烟花的元素
*/
randomColor(ele) {
return ele.style.backgroundColor = utils.randomColor();
}
}
JS烟花案例优化版的更多相关文章
- JS烟花案例
html代码部分 <!DOCTYPE html> <!-- * @Descripttion: * @version: * @Author: 小小荧 * @Date: 2020-03- ...
- Atiti attilax主要成果与解决方案与案例rsm版 v4
Atiti attilax主要成果与解决方案与案例rsm版 v4 版本历史记录1 1. ##----------主要成果与解决方案与 参与项目1 ###开发流程与培训系列1 #-----组织运营与文 ...
- Atiti attilax主要成果与解决方案与案例rsm版 v2
Atiti attilax主要成果与解决方案与案例rsm版 v2 1. ##----------主要成果与解决方案与 参与项目1 ###开发流程与培训系列1 #-----组织运营与文化建设系列1 # ...
- Atiti attilax主要成果与解决方案与案例rsm版
Atiti attilax主要成果与解决方案与案例rsm版 1. ##----------主要成果与解决方案与 参与项目1 ###开发流程系列1 ###架构系列 (au1 ###编程语言系列与架构系 ...
- 通用PE工具箱 4.0精简优化版
通用PE工具箱 4.0精简优化版 经用过不少 WinPE 系统,都不是很满意,普遍存在篡改主页.添加广告链接至收藏夹.未经允许安装推广软件等流氓行为,还集成了诸多不常用的工具,令人头疼不已.那么今天给 ...
- GHOST WIN7系统64位经典优化版 V2016年
来自系统妈:http://www.xitongma.com 深度技术GHOST win7系统32,64位经典优化版 V2016年3月 系统概述 深度技术ghost win7系统64位经典优化版适用于笔 ...
- Chrome 扩展程序 CrxMouse 优化版 v3.0.1
说明 CrxMouse 原版更新至 v2.7.8,跟进升级优化版至 v3.0.1. 改动说明: 1. 去除可能存在的后台数据上传隐患: 2. 解决鼠标右键拖动时的轨迹漂移问题. 3. 加入部分默认设置 ...
- POJ-2533最长上升子序列(DP+二分)(优化版)
Longest Ordered Subsequence Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 41944 Acc ...
- js加载优化三
Javascript性能优化之异步加载和执行 Author:小欧2013-09-17 随着科技的发展,如今的网站和五六年前相比,现在的人们对web的要求越来越高了,用户体验,交互效果,视觉效果等等都有 ...
随机推荐
- 使用 Redis 如何实现查询附近的人?「视频版」——面试突击 003 期
面试问题 Redis 如何实现查询附近的人? 涉及知识点 Redis 中如何操作位置信息? GEO 底层是如何实现的? 如何在程序实现查询附近的人? 在实际使用中需要注意哪些问题? 视频答案 视频地址 ...
- Core + Vue 后台管理基础框架0——开篇
1.背景 最近,打算新开个项目,鉴于团队技术栈,选型.net core + vue,前后端分离.本打算捡现成的轮子的,github上大致逛了逛,总发现这样那样的不太适合心中那些“完美实践”,例如:Ab ...
- c++第一章1.6
测试已完成(bingo) 1 [单选题] 下面代码能够实现交换操作的函数有( ) A. swap(int a,int b) { int t=a;a=b;b=t;} B. swa ...
- Django中update和save()同时作用
数据更新操作,对单条记录,可以使用save或者是update两种方式. save() 默认保存后会看到sql语句中更新了所有字段,而save的值是之前获取时候的字段值,是缓存下来的,并不一定最新,可能 ...
- gcc错误[Error] ld returned 1 exit status
出现这个错误的原因是:(目前遇见两种情况了) 你的编译器正在执行刚刚的程序还没关:小黑框还在. 解决措施:关闭就好. 定义的函数和调用的函数名字不一样,也会造成产生这种错误!!!代码如下: bool ...
- 曹工杂谈:花了两天时间,写了一个netty实现的http客户端,支持同步转异步和连接池(1)--核心逻辑讲解
背景 先说下写这个的目的,其实是好奇,dubbo是怎么实现同步转异步的,然后了解到,其依赖了请求中携带的请求id来完成这个连接复用:然后我又发现,redisson这个redis客户端,底层也是用的ne ...
- JetBrains Quest 3
起因 今天早上看了一篇博文: 此时的我:"哎,这等好事不等我!" 然后......我打开官方推特: "什么?最后的任务?" 于是就有了这篇文章 开始操作 1.神 ...
- 【Java面试题】List如何一边遍历,一边删除?
这是最近面试时被问到的1道面试题,本篇博客对此问题进行总结分享. 1. 新手常犯的错误 可能很多新手(包括当年的我,哈哈)第一时间想到的写法是下面这样的: public static void mai ...
- Java 并发容器(转)
转自:https://blog.ouyangsihai.cn/%2Fjava-gao-bing-fa-zhi-bing-fa-rong-qi-xiang-jie-cong-ru-men-dao-cha ...
- Natas23 Writeup(php弱类型)
Natas23: 一个登录页面,查看源码,发现关键代码: if(array_key_exists("passwd",$_REQUEST)){ if(strstr($_REQUEST ...