js实现canvas吸引粒子运动动画效果代码

代码语言:html

所属分类:粒子

代码描述:js实现canvas吸引粒子运动动画效果代码

代码标签: 吸引 粒子 运动 动画 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<html lang="en">
<head>

    <meta charset="UTF-8">







</head>

<body >


    <script >
    const canvas = document.createElement('canvas');
canvas.style.background = '#000'
document.body.appendChild(canvas);
document.body.style.margin = 0;
document.body.style.overflow = 'hidden';

const gl = canvas.getContext("webgl", {preserveDrawingBuffer: true}); 
const controls = OrbitControls(0, 0, 150);
const fullScreenTriangle = new Float32Array([-1,3,-1,-1,3,-1])
const thomasAttractor = new Float32Array(Array(15000).fill(0).map(() => Math.random()*6-3))

const clearPass = program(gl, `
attribute vec2 pt = () => fullScreenTriangle;
void main() {
    gl_Position = vec4(pt, 0.0, 1.0);
}`, `
void main() {
    gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);
}`);

const particles = program(gl, `
attribute vec3 pt = () => thomasAttractor;
uniform vec2 resolution = () => [innerWidth, innerHeight];
uniform float time = () => [window.t];
uniform float a1 = () => [controls.a1];
uniform float a2 = () => [controls.a2];
uniform float k = () => [controls.k];
void main() {
    float far = 1000.0;
    float x = pt.x*cos(a1) + pt.z*sin(a1);
    float z = pt.z*cos(a1) - pt.x*sin(a1);
    float y = pt.y*cos(a2) + z*sin(a2);
    float d = z*cos(a2) - pt.y*sin(a2) + far;
    vec2 pos = vec2( (k/d)*x, (k/d)*y );
    pos.y *= resolution.x/resolution.y;
    gl_Position = vec4(pos, 0.0, 1.0);
    gl_PointSize = 2.0;
}`, `
void main() {
    gl_FragColor = vec4(1.0);
}`);

gl.enable(gl.BLEND);

requestAnimationFrame(function draw(t) {
    window. t = t;
    thomasAttractorTick(thomasAttractor, t);

    if (canvas.width != innerWidth || canvas.height !== innerHeight) 
        gl.viewport(0, 0, canvas.width = innerWidth, canvas.height = innerHeight);

    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); 
    clearPass(3, gl.TRIANGLES);

    // addittive blending
    gl.blendFunc(gl.ONE, gl.ONE); 
    particles(thomasAttractor.length/3, gl.POINTS);

    requestAnimationFrame(draw);
});

function thomasAttractorTick(pts, t) {
    const b = 0.208186 + Math.sin(t/1000)*0.05;
    const dt = (t - pts.t0 || 0)/1000;
    const max = pts.length/3;
    for (let i = 0; i < max; i++){
        const x = pts[i*3]
        const y = pts[i*3+1]
        const z = pts[i*3+2]
        pts[i*3]   = x + dt * (Math.sin(y) - b*x);
        pts[i*3+1] = y + dt * (Math.sin(z) - b*y);
        pts[i*3+2] = z + dt * (Math.sin(x) - b*z);
        if (Math.random() > 0.9999) {
            pts[i*3] *= 2;
            pts[i*3+1] *= 2;
            pts[i*3+2] *= 2;
        }
            
    }
    pts.t0 = t;
}

function OrbitControls(a1 = 0, a2 = 0, k = 150, p){
    const _ = {a1, a2, k}
    const evt = (t, f) => addEventListener(t, f);//e => f(e)
    evt('wheel', e => _.k *= 1 - Math.sign(e.deltaY)*0.1)
    evt('mouseup', e => p = null)
    evt('mousedown', e => p = {x: e.x, y: e.y, a1.........完整代码请登录后点击上方下载按钮下载查看

网友评论0