<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>HTML5 Canvas 2D绘制云雾中的电流动画特效</title>
<style>
canvas,
body {
padding: 0;
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script src="js/dat.gui.min.js"></script>
<script>
ctrl = {
numParticles: 35,
maxRadius: 80,
hue: 220,
hueRange: 15,
fade: 0.36,
halo: true,
zappy: true,
zapComplexity: 1
}
var gui = new dat.GUI();
gui.add(ctrl, 'numParticles', 1, 150).step(1);
gui.add(ctrl, 'maxRadius', 30, 150).step(1);
gui.add(ctrl, 'hue', 0, 359).step(1);
gui.add(ctrl, 'hueRange', 0, 180).step(1);
gui.add(ctrl, 'fade', 0, 0.4).step(0.001);
gui.add(ctrl, 'zapComplexity', 0, 4).step(1);
gui.add(ctrl, 'halo');
// gui.add(ctrl, 'zappy');
// create a canvas element
var canvas = document.createElement("canvas")
// attach element to DOM
document.body.appendChild(canvas)
// background color [r, g, b]
var bg = [10, 10, 30]
var wh = window.innerHeight
// get the canvas context (this is the part we draw to)
var ctx = canvas.getContext("2d")
function setup() {
// setup the canvas size to match the window
canvas.width = window.innerWidth
canvas.height = window.innerHeight
wh = window.innerWidth < window.innerHeight ? window.innerWidth : window.innerHeight
// set the 0,0 point to the middle of the canvas, this is not necessary but it can be handy
ctx.translate(canvas.width / 2, canvas.height / 2)
fill(bg, 1)
}
// fill entire canvas with a preset color
function fill(rgb, amt) {
ctx.beginPath(); // start path
ctx.rect(-canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height) // set rectangle to be the same size as the window
ctx.fillStyle = `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${amt})` // use the rgb array/color for fill, and amt for opacity
ctx.fill() // do the drawing
}
function drawCircle(x, y, r, color) {
ctx.beginPath()
ctx.arc(x, y, r, 0, 2 * Math.PI)
ctx.fillStyle = color || 'white'
ctx.fill()
ctx.closePath()
}
function Particle() {
// initialize loopers with random trange and offset
this.loop1 = new Looper(1200 + 200 * Math.random(), 9000 * Math.random())
this.loop2 = new Looper(880 + 950 * Math.random(), 9000 * Math.random())
this.loop3 = new Looper(550 + 920 * Math.random(), 9000 * Math.random())
this.history = []
this.history_max = 1
this.c = ``
this.hsv = {}
this.offset = Math.random() // some color offset for the color
this.signals = 0 // count connection - update every frame
this.sstrength = 0 // running average using signals
this.destroy = function() {
this.loop1 = null
this.loop2 = null
this.loop3 = null
this.history = null
this.history_max = null
this.c = null
this.hsv = null
this.offset = null
delete this
}
this.draw = function() {
this.sstrength = this.signals * 0.02 + this.sstrength * 0.91;
this.loop1.update() // update looper
this.loop2.update() // update looper
this.loop3.update() // update looper
// set x,y, radius, and color params
var x = this.loop1.sin * (canvas.width / 4) + this.loop2.sin * (canvas.width / 3) * this.loop3.cos * this.loop2.sin
var y = this.loop1.cos * (canvas.height / 4) + this.loop2.cos * (canvas.height / 3) * this.loop3.cos * this.loop2.sin
// var r = 0.2 + 3 * this.loop1.sinNorm * this.loop2.sinNorm // set the radius
this.hsv = {
// this is where we set the color...
h: ctrl.hue + ctrl.hueRange * (this.loop3.cosNorm + this.offset) * this.loop2.sinNorm,
// the saturation depends on the loop
s: 80 + 7 * this.loop1.sinNorm,
// ..and so does the value - we want to keep that close to 50%
v: 70 + 5 * this.loop3.sin
}
this.c = `hsla(${this.hsv.h}, ${this.hsv.s}%, ${this.hsv.v}%, ${1})`
if (ctrl.halo) {
var grd = ctx.createRadialGradient(Math.round(x), Math.round(y), 0, Math.round(x), Math.round(y), ctrl.maxRadius);
grd.addColorStop(0.0, `hsla(${this.hsv.h}, ${this.hsv.s}%, ${this.hsv.v}%, ${0.1 * this.sstrength})`);
// grd.addColorStop(0.2, `hsla(${this.hsv.h}, ${this.hsv.s}%, ${this.hsv.v}%, ${0.03 * this.sstrength})`);
grd.addColorStop(0.9, `hsla(${this.hsv.h}, ${this.hsv.s}%, ${this.hsv.v}%, ${0})`);
drawCircle(x, y, ctrl.maxRadius, grd); // draw the circle
}
this.history = [
[x, y]
]
this.signals = 0;
}
this.addSignal = function() {
this.signals++;
}
}
// initialize a set of particle
var particles = []
function draw() {
// fill context with background color
fill(bg, ctrl.fade)
//add particles
while (particles.length < ctrl.numParticles) {
particles.push(new Particle())
}
// drop old particles
while (particles.length >= ctrl.numParticles) {
particles.pop().destroy()
}
var x0
var y0
var x1
var y1
var d
var r = ctrl.maxRadius * ctrl.maxRadius
var s
// update all the particles
for (var i = 0; i < particles.length; i++) {
particles[i].draw() // do it once
for (var j = 0; j < i; j++) {
if (particles[j] && particles[j].history && particles[j].history.length > 0) {
x0 = particles[i].history[0][0]
y0 = particles[i].history[0][1]
x1 = particles[j].history[0][0]
y1 = particles[j].history[0][1]
d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)
if (d < r && d > 50) {
particles[i].addSignal();
particles[j].addSignal();
s = 1 - Math.sin(d / r * d / r * Math.PI / 2)
if (!ctrl.zappy) {
// straight line
ctx.beginPath();
ctx.moveTo(x0, y0);
ctx.lineTo(x1, y1);
ctx.lineWidth = s * 1.6;
ctx.strokeStyle = particles[i].c
ctx.stroke()
ctx.closePath()
} else {
// zappy line
var iterations = [{
x: x0,
y: y0
}, {
x: x1,
y: y1
}]
var newiterations, ii, ij
for (ii = 0; ii < ctrl.zapComplexity; ii++) {
newiterations = [iterations[0]]
for (ij = 1; ij < iterations.length; ij++) {
newiterations.push(getRandMidpoint(iterations[ij - 1], iterations[ij], ctrl.maxRadius / 3 / (ii * ii + 1) * (1 - s * 0.7)))
newiterations.push(iterations[ij])
}
iterations = newiterations.concat([])
}
ctx.beginPath();
ctx.moveTo(iterations[0].x, iterations[0].y);
ctx.lineWidth = s * 1.6;
ctx.strokeStyle = particles[i].c
for (ii = 1; ii < iterations.length; ii++) {
ctx.lineTo(iterations[ii].x, iterations[ii].y);
}
HTML5 Canvas绘制的云雾中电流交织2D动画特效源码.zip
版权申诉
58 浏览量
2022-11-03
23:31:44
上传
评论
收藏 18KB ZIP 举报
毕业_设计
- 粉丝: 1925
- 资源: 1万+
最新资源
- 基于知识图谱的推荐算法-MKR的实现python源码+运行说明.zip
- 基于matlab实现的电动汽车动力性经济性UI,希望对初学者有用 .rar
- 基于matlab实现的负荷平衡的配电网重构程序 matlab下调试通过.rar
- 基于matlab实现的利用矩阵的运算来编写旋转,使用矩阵进行坐标运算,使用矩阵进行坐标旋转.rar
- 基于matlab实现的利用前推回代法计算配电网潮流,可以算得电压,功率以及电流.rar
- 基于matlab实现的配电网潮流计算,PQ分解法,IEEE30节点验证 .rar
- 博客系统(struts+hibernate+spring)
- 基于matlab实现的汽车动力性,燃油经济性计算,基于MATLAB计算的,汽车理论相关内容 .rar
- 基于matlab实现的汽车动力性和经济性双目标函数的优化设计.rar
- 使用 Redis +Python+Flask+MySQL开发简单接口实例.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈