ZHANG ZENGXUAN d0dd647fac feat: INIT
2025-05-19 21:59:43 +08:00

577 lines
19 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

$(function () {
// 初始化界面
function init() {
placeholderPic()
sd1('.sd1')
sd1('.sd2')
sd2('.sd3')
sd2('.sd4')
jz()
animate()
}
init()
// 自定义字体大小
function placeholderPic() {
w = document.documentElement.clientWidth / 80;
document.documentElement.style.fontSize = w + 'px';
}
// 闪电一,二
function sd1(ele) {
var width, height
var step = 0;
var canvas = document.createElement('canvas')
var ctx = canvas.getContext('2d')
var bg = [4, 10, 11]
document.querySelector(ele).appendChild(canvas)
setTimeout(() => {
var timeID = setInterval(() => {
pt1.x += 10;
if (pt1.x > width - 10) {
clearInterval(timeID)
}
}, 60);
}, 1000)
var pt1
var pt2
window.addEventListener('resize', setup)
setup()
function setup() {
canvas.width = width = document.querySelector(ele).clientWidth
canvas.height = height = document.querySelector(ele).clientHeight
ctx.beginPath();
ctx.rect(0, 0, width, height)
ctx.fillStyle = `rgba(${bg[0]}, ${bg[1]}, ${bg[2]}, ${1})`
ctx.fill()
pt1 = { x: -20, y: height / 2 }//闪电起点
pt2 = { x: -20, y: height / 2 } //闪电终点
// draw()
}
setInterval(animate, 60)
// window.requestAnimationFrame(animate);
function blur(ctx, canvas, amt) {
ctx.filter = `blur(${amt}px)`
ctx.drawImage(canvas, 0, 0)
ctx.filter = 'none'
}
function fade(ctx, amt, width, height) {
ctx.beginPath();
ctx.rect(0, 0, width, height)
ctx.fillStyle = `rgba(${bg[0]}, ${bg[1]}, ${bg[2]}, ${amt})`
ctx.fill()
}
function animate() {
step++
blur(ctx, canvas, 1)
draw()
fade(ctx, 0.1, width, height)
// window.requestAnimationFrame(function(){animate()})
}
function draw() {
var iterations = [pt1, pt2]
var newiterations, i, j
for (i = 0; i < 8; i++) {
newiterations = [iterations[0]]
for (j = 1; j < iterations.length; j++) {
newiterations.push(getRandMidpoint(iterations[j - 1], iterations[j], 200 / (i * i + 1)))
newiterations.push(iterations[j])
}
iterations = newiterations.concat([])
}
ctx.beginPath();
ctx.moveTo(iterations[0].x, iterations[0].y);
ctx.lineWidth = 2;
ctx.strokeStyle = '#04e4c9';
// ctx.strokeStyle = `hsla(${Math.sin( step / 30) * 120 + 50},${90}%,${70}%,1)`
for (i = 1; i < iterations.length; i++) {
ctx.lineTo(iterations[i].x, iterations[i].y);
}
ctx.stroke()
ctx.closePath()
}
function getRandMidpoint(pa, pb, range) {
var a = Math.atan2(pb.y - pa.y, pb.x - pa.x) + Math.PI / 2
var half = { y: (pb.y - pa.y) / 2 + pa.y, x: (pb.x - pa.x) / 2 + pa.x }
var offset = Math.random() * range / 3 - range / 6 //这里控制闪电的抖动幅度
var ho = {
x: Math.cos(a) * offset + half.x,
y: Math.sin(a) * offset + half.y
}
return ho
}
}
//
//
//
// 闪电三,四
function sd2(ele) {
var width, height
var step = 0;
var canvas = document.createElement('canvas')
var ctx = canvas.getContext('2d')
var bg = [4, 10, 11]
document.querySelector(ele).appendChild(canvas)
setTimeout(() => {
var timeID = setInterval(() => {
pt1.x -= 10;
if (pt1.x < 10) {
clearInterval(timeID)
}
}, 60);
}, 1000)
var pt1
var pt2
window.addEventListener('resize', setup)
setup()
function setup() {
canvas.width = width = document.querySelector(ele).clientWidth
canvas.height = height = document.querySelector(ele).clientHeight
ctx.beginPath();
ctx.rect(0, 0, width, height)
ctx.fillStyle = `rgba(${bg[0]}, ${bg[1]}, ${bg[2]}, ${1})`
ctx.fill()
pt1 = { x: width + 20, y: height / 2 }//闪电起点
pt2 = { x: width + 20, y: height / 2 } //闪电终点
// draw()
}
setInterval(animate, 60)
// window.requestAnimationFrame(animate);
function blur(ctx, canvas, amt) {
ctx.filter = `blur(${amt}px)`
ctx.drawImage(canvas, 0, 0)
ctx.filter = 'none'
}
function fade(ctx, amt, width, height) {
ctx.beginPath();
ctx.rect(0, 0, width, height)
ctx.fillStyle = `rgba(${bg[0]}, ${bg[1]}, ${bg[2]}, ${amt})`
ctx.fill()
}
function animate() {
step++
blur(ctx, canvas, 1)
draw()
fade(ctx, 0.1, width, height)
// window.requestAnimationFrame(function(){animate()})
}
function draw() {
var iterations = [pt1, pt2]
var newiterations, i, j
for (i = 0; i < 8; i++) {
newiterations = [iterations[0]]
for (j = 1; j < iterations.length; j++) {
newiterations.push(getRandMidpoint(iterations[j - 1], iterations[j], 200 / (i * i + 1)))
newiterations.push(iterations[j])
}
iterations = newiterations.concat([])
}
ctx.beginPath();
ctx.moveTo(iterations[0].x, iterations[0].y);
ctx.lineWidth = 2;
ctx.strokeStyle = '#04e4c9';
// ctx.strokeStyle = `hsla(${Math.sin( step / 30) * 120 + 50},${90}%,${70}%,1)`
for (i = 1; i < iterations.length; i++) {
ctx.lineTo(iterations[i].x, iterations[i].y);
}
ctx.stroke()
ctx.closePath()
}
function getRandMidpoint(pa, pb, range) {
var a = Math.atan2(pb.y - pa.y, pb.x - pa.x) + Math.PI / 2
var half = { y: (pb.y - pa.y) / 2 + pa.y, x: (pb.x - pa.x) / 2 + pa.x }
var offset = Math.random() * range / 3 - range / 6 //这里控制闪电的抖动幅度
var ho = {
x: Math.cos(a) * offset + half.x,
y: Math.sin(a) * offset + half.y
}
return ho
}
}
// 加载动画
function jz() {
$('.jz1 ul li').each((index, item) => {
item.style.opacity = 1 - index / 10;
})
setInterval(() => {
$('.jz1 ul li').each((index, item) => {
if (item.style.opacity == 0) {
item.style.opacity = 1
}
item.style.opacity = parseFloat(item.style.opacity) - 0.1
})
}, 100)
$('.jz2 ul li').each((index, item) => {
item.style.opacity = 1 - index / 10;
})
setInterval(() => {
$('.jz2 ul li').each((index, item) => {
if (item.style.opacity == 0) {
item.style.opacity = 1
}
item.style.opacity = parseFloat(item.style.opacity) - 0.1
})
}, 100)
}
// 中间背景动画
function animate() {
var App = {};
App.setup = function () {
// 创建canvas元素并加入body中
var canvas = document.createElement('canvas');
this.filename = "spipa";
// 控制canvas幕布的大小
canvas.width = document.querySelector('.animate').clientWidth;
canvas.height = document.querySelector('.animate').clientHeight;
this.canvas = canvas;
document.querySelector('.animate').appendChild(canvas);
this.ctx = this.canvas.getContext('2d');
this.width = this.canvas.width;
this.height = this.canvas.height;
this.dataToImageRatio = 1;
this.ctx.imageSmoothingEnabled = false;
this.ctx.webkitImageSmoothingEnabled = false;
this.ctx.msImageSmoothingEnabled = false;
this.xC = this.width / 2;
this.yC = this.height / 2;
this.stepCount = 0;
this.particles = [];
this.lifespan = 1000;
this.popPerBirth = 1;
this.maxPop = 200;
this.birthFreq = 5;
// Build grid
this.gridSize = 8;// 运动坐标
this.gridSteps = Math.floor(1000 / this.gridSize);
this.grid = [];
var i = 0;
for (var xx = -500; xx < 500; xx += this.gridSize) {
for (var yy = -500; yy < 500; yy += this.gridSize) {
// 径向场r的三角函数最大值在r0附近
var r = Math.abs(xx) + Math.abs(yy),//Math.sqrt(xx*xx+yy*yy),
r0 = 3*w, //中间方形的大小
field;
if (r < r0) field = 255 / r0 * r;
else if (r > r0) field = 255 - Math.min(255, (r - r0) / 2);
this.grid.push({
x: xx,
y: yy,
busyAge: 0,
spotIndex: i,
isEdge: (xx == -500 ? 'left' :
(xx == (-500 + this.gridSize * (this.gridSteps - 1)) ? 'right' :
(yy == -500 ? 'top' :
(yy == (-500 + this.gridSize * (this.gridSteps - 1)) ? 'bottom' :
false
)
)
)
),
field: field
});
i++;
}
}
this.gridMaxIndex = i;
this.initDraw();
};
App.evolve = function () {
var time1 = performance.now();
this.stepCount++;
// Increment all grid ages
this.grid.forEach(function (e) {
if (e.busyAge > 0) e.busyAge++;
});
if (this.stepCount % this.birthFreq == 0 && (this.particles.length + this.popPerBirth) < this.maxPop) {
this.birth();
}
App.move();
App.draw();
var time2 = performance.now();
};
App.birth = function () {
var x, y;
var gridSpotIndex = Math.floor(Math.random() * this.gridMaxIndex),
gridSpot = this.grid[gridSpotIndex],
x = gridSpot.x, y = gridSpot.y;
var particle = {
hue: -10,// + Math.floor(50*Math.random()),
sat: 95,//30 + Math.floor(70*Math.random()),
lum: 20 + Math.floor(40 * Math.random()),
x: x, y: y,
xLast: x, yLast: y,
xSpeed: 0, ySpeed: 0,
age: 0,
ageSinceStuck: 0,
attractor: {
oldIndex: gridSpotIndex,
gridSpotIndex: gridSpotIndex,// Pop at random position on grid
},
name: 'seed-' + Math.ceil(10000000 * Math.random())
};
this.particles.push(particle);
};
App.kill = function (particleName) {
var newArray = _.reject(this.particles, function (seed) {
return (seed.name == particleName);
});
this.particles = _.cloneDeep(newArray);
};
App.move = function () {
for (var i = 0; i < this.particles.length; i++) {
// Get particle
var p = this.particles[i];
// Save last position
p.xLast = p.x; p.yLast = p.y;
// Attractor and corresponding grid spot
var index = p.attractor.gridSpotIndex,
gridSpot = this.grid[index];
// Maybe move attractor and with certain constraints
if (Math.random() < 0.5) {
// Move attractor
if (!gridSpot.isEdge) {
// Change particle's attractor grid spot and local move function's grid spot
var topIndex = index - 1,
bottomIndex = index + 1,
leftIndex = index - this.gridSteps,
rightIndex = index + this.gridSteps,
topSpot = this.grid[topIndex],
bottomSpot = this.grid[bottomIndex],
leftSpot = this.grid[leftIndex],
rightSpot = this.grid[rightIndex];
// Choose neighbour with highest field value (with some desobedience...)
var chaos = 30;
var maxFieldSpot = _.maxBy([topSpot, bottomSpot, leftSpot, rightSpot], function (e) {
return e.field + chaos * Math.random()
});
var potentialNewGridSpot = maxFieldSpot;
if (potentialNewGridSpot.busyAge == 0 || potentialNewGridSpot.busyAge > 15) {// Allow wall fading
//if (potentialNewGridSpot.busyAge == 0) {// Spots busy forever
// Ok it's free let's go there
p.ageSinceStuck = 0;// Not stuck anymore yay
p.attractor.oldIndex = index;
p.attractor.gridSpotIndex = potentialNewGridSpot.spotIndex;
gridSpot = potentialNewGridSpot;
gridSpot.busyAge = 1;
} else p.ageSinceStuck++;
} else p.ageSinceStuck++;
if (p.ageSinceStuck == 10) this.kill(p.name);
}
// Spring attractor to center with viscosity
var k = 8, visc = 0.4;
var dx = p.x - gridSpot.x,
dy = p.y - gridSpot.y,
dist = Math.sqrt(dx * dx + dy * dy);
// Spring
var xAcc = -k * dx,
yAcc = -k * dy;
p.xSpeed += xAcc; p.ySpeed += yAcc;
// Calm the f*ck down
p.xSpeed *= visc; p.ySpeed *= visc;
// Store stuff in particle brain
p.speed = Math.sqrt(p.xSpeed * p.xSpeed + p.ySpeed * p.ySpeed);
p.dist = dist;
// Update position
p.x += 0.1 * p.xSpeed; p.y += 0.1 * p.ySpeed;
// Get older
p.age++;
// Kill if too old
if (p.age > this.lifespan) {
this.kill(p.name);
this.deathCount++;
}
}
};
App.initDraw = function () {
this.ctx.beginPath();
this.ctx.rect(0, 0, this.width, this.height);
this.ctx.fillStyle = 'transparent';
this.ctx.fill();
this.ctx.closePath();
};
App.draw = function () {
this.drawnInLastFrame = 0;
if (!this.particles.length) return false;
this.ctx.beginPath();
this.ctx.rect(0, 0, this.width, this.height);
// this.ctx.fillStyle = 'transparent';
this.ctx.fillStyle = 'rgba(12, 22, 25, 0.1)';
this.ctx.fill();
this.ctx.closePath();
for (var i = 0; i < this.particles.length; i++) {
// Draw particle
var p = this.particles[i];
var h, s, l, a;
h = p.hue + this.stepCount / 30;
s = p.sat;
l = p.lum;
a = 1;
var last = this.dataXYtoCanvasXY(p.xLast, p.yLast),
now = this.dataXYtoCanvasXY(p.x, p.y);
var attracSpot = this.grid[p.attractor.gridSpotIndex],
attracXY = this.dataXYtoCanvasXY(attracSpot.x, attracSpot.y);
var oldAttracSpot = this.grid[p.attractor.oldIndex],
oldAttracXY = this.dataXYtoCanvasXY(oldAttracSpot.x, oldAttracSpot.y);
this.ctx.beginPath();
this.ctx.strokeStyle = 'green';
this.ctx.fillStyle = 'hsla(' + h + ', ' + s + '%, ' + l + '%, ' + a + ')';
// Particle trail
this.ctx.moveTo(last.x, last.y);
this.ctx.lineTo(now.x, now.y);
this.ctx.lineWidth = 1.5 * this.dataToImageRatio;
this.ctx.stroke();
this.ctx.closePath();
// Attractor positions
this.ctx.beginPath();
this.ctx.lineWidth = 1.5 * this.dataToImageRatio;
this.ctx.moveTo(oldAttracXY.x, oldAttracXY.y);
this.ctx.lineTo(attracXY.x, attracXY.y);
this.ctx.arc(attracXY.x, attracXY.y, 1.5 * this.dataToImageRatio, 0, 2 * Math.PI, false);
//a /= 20;
this.ctx.strokeStyle = 'green';
this.ctx.fillStyle = 'green';
//this.ctx.stroke();
this.ctx.fill();
this.ctx.closePath();
// UI counter
this.drawnInLastFrame++;
}
};
App.dataXYtoCanvasXY = function (x, y) {
var zoom = 1.6;
var xx = this.xC + x * zoom * this.dataToImageRatio,
yy = this.yC + y * zoom * this.dataToImageRatio;
return { x: xx, y: yy };
};
setTimeout(function(){
console.log(1123)
App.setup();
App.draw();
var frame = function () {
App.evolve();
requestAnimationFrame(frame);
};
frame();
},5000)
/**
* Some old util I use at times
*
* @param {Number} Xstart X value of the segment starting point
* @param {Number} Ystart Y value of the segment starting point
* @param {Number} Xtarget X value of the segment target point
* @param {Number} Ytarget Y value of the segment target point
* @param {Boolean} realOrWeb true if Real (Y towards top), false if Web (Y towards bottom)
* @returns {Number} Angle between 0 and 2PI
*/
segmentAngleRad = function (Xstart, Ystart, Xtarget, Ytarget, realOrWeb) {
var result;// Will range between 0 and 2PI
if (Xstart == Xtarget) {
if (Ystart == Ytarget) {
result = 0;
} else if (Ystart < Ytarget) {
result = Math.PI / 2;
} else if (Ystart > Ytarget) {
result = 3 * Math.PI / 2;
} else { }
} else if (Xstart < Xtarget) {
result = Math.atan((Ytarget - Ystart) / (Xtarget - Xstart));
} else if (Xstart > Xtarget) {
result = Math.PI + Math.atan((Ytarget - Ystart) / (Xtarget - Xstart));
}
result = (result + 2 * Math.PI) % (2 * Math.PI);
if (!realOrWeb) {
result = 2 * Math.PI - result;
}
return result;
}
}
})