d3.js 实现烟花鲜果

今天在d3.js官网上看到了一个烟花的DEMO,是canvas制作的,于是我想用d3.js来实现它,js代码只有几行。好了废话不多说,先上图。

d3.js 实现烟花鲜果

1 js 类

因为烟花要有下落的效果,所以里面用到了一些简单的数学和物理知识来模拟重力,

class Firework {
    constructor() {
        this._heightLimit = [100,200];
        this._width = 1288;
        this._svg = null;
        this._tempObj = {};
        this._colors = d3.scaleLinear().domain([0,1,2,3,4,5]).range(['#f00','#ff0','#f0f','#0ff','#0f0'])
        this.initSvg();
    }
    initSvg() {
        this._svg = d3.select('body').append('svg');
        this._width = window.innerWidth;
    }
    randomPosition() {
        setInterval(() => {
            let x = Math.floor(Math.random() * (this._width - 200) + 100);
            let y = Math.floor(Math.random() * (this._heightLimit[1] - this._heightLimit[0]) + this._heightLimit[0]);
            let v = Math.random() * 20 + 40;
            let c = Math.random() * 4;
            this.renderFire(x,y,v,c)
        }, Math.floor(Math.exp(-Math.random()) * 800))
    }
    renderFire(x,y,v,c) {
        let stamp = new Date().getTime();
        let temp = d3.range(18).map(d => {
            return {
                cx: x + 1 * Math.sin(Math.PI * d / 9),
                cy: y - 1 * Math.cos(Math.PI * d / 9),
                vx: v * Math.sin(Math.PI * d / 9),
                vy: - v *  Math.cos(Math.PI * d / 9)
            }
        })
        let t = 0;
        this._tempObj[stamp] = setInterval(() => {
            let cutStamp = new Date().getTime();
            for(var i=0; i<18; i++) {
                this._svg.append('circle')
                .attr('cx', temp[i].cx + temp[i].vx * t / 8)
                .attr('cy', t * t / 16 + temp[i].vy * t / 8 + temp[i].cy)
                .attr('r', 6)
                .attr('fill', this._colors(c))
                .attr('fill-opacity', 1)
                .transition()
                .duration(300)
                .attr('fill-opacity', 0)
                .on('end', function() {
                    d3.select(this).remove();
                })
            }
            if(cutStamp - stamp > 2000){
                clearInterval(this._tempObj[stamp])
            }
            t ++;
        }, 40)
    }
    start() {
        this.randomPosition();
    }
}

2 css 代码

* {
  padding: 0;
  margin: 0;
}
body {
  width: 100vw;
  height: 100vh;
  background: #000000;
}
.container {
  width: 100vw;
  height: 100vh;
  position: relative;
}
img {
  width: 100vw;
  height: 80vh;
}
svg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
}

3 html 代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>$Title$</title>
    <link rel="stylesheet" type="text/css" href="css/base.css"/>
    <script type="text/javascript" src="js/d3.v4.js"></script>
    <script type="text/javascript" src="js/base.js"></script>
</head>
<body>
    <div class="container">
        <img src="img/bg.jpg">
    </div>
<script>
var firework = new Firework();
firework.start()
</script>
</body>
</html>

是不是很简单

想预览或者下载demo的人请移步至原文

原文地址 1

 

上一篇:D3.js的v5版本入门教程(第十二章)—— D3.js中各种精美的图形


下一篇:媒体大数据可视化(Node.JS+Vue+Vite+D3)