canvas+webgl实现炫酷blob点交互动画效果代码
代码语言:html
所属分类:动画
代码描述:canvas+webgl实现炫酷blob点交互动画效果代码
代码标签: canvas webgl 炫酷 blob 点 交互 动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> * { margin: 0; padding: 0; background: black; overflow: hidden; } </style> </head> <body translate="no"> <script > function createShader(type, source) { const shader = gl.createShader(type); gl.shaderSource(shader, source); gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { console.error(gl.getShaderInfoLog(shader)); gl.deleteShader(shader); return null; } return shader; } function createProgram(vertexShader, fragmentShader) { const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { console.error(gl.getProgramInfoLog(program)); gl.deleteProgram(program); return null; } return program; } const canvas = document.createElement('canvas'); canvas.style.filter = 'saturate(.8) contrast(1.5)'; const gl = canvas.getContext('webgl', { preserveDrawingBuffer: true, powerPreference: 'high-performance' }); document.body.append(canvas); function resize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); } resize(); window.addEventListener('resize', resize); class FlyShape { constructor({ verts = [], colors = [], sizes = [], vert, frag, indices } = {}) { Object.assign(this, { verts: new Float32Array(verts), sizes: new Float32Array(sizes), colors: new Float32Array(colors), vertexBuffer: gl.createBuffer(), indices: indices && new Uint16Array(indices), indexBuffer: gl.createBuffer(), program: createProgram( createShader(gl.VERTEX_SHADER, vert || ` precision lowp float; attribute vec3 position; attribute vec4 vertexColor; attribute float pointSize; // Use this attribute varying vec4 fragColor; uniform mat4 flatMatrix; void main(void) { gl_Position = flatMatrix * vec4(position, 1.0); gl_PointSize = pointSize; fragColor = vertexColor; } `), createShader(gl.FRAGMENT_SHADER, frag || ` precision mediump float; varying vec4 fragColor; void main() { float dist = length(gl_PointCoord - vec2(0.5)); float edge = 0.1; float alpha = 1.0 - smoothstep(0.5 - edge, 0.5, dist); gl_FragColor = vec4(fragColor.r, fragColor.g, fragColor.b, fragColor.a * alpha); }`)) }); gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, this.verts, gl.STATIC_DRAW); if (indices) { gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); } this.position = gl.getAttribLocation(this.program, 'position'); gl.enableVertexAttribArray(this.position); gl.vertexAttribPointer(this.position, 3, gl.FLOAT, false, 0, 0); this.colorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(), gl.DYNAMIC_DRAW); this.vertexColor = gl.getAttribLocation(this.program, 'vertexColor'); gl.enableVertexAttribArray(this.vertexColor); gl.vertexAttribPointer(this.vertexColor, 4, gl.FLOAT, false, 0, 0); this.sizeBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, this.sizeBuffer); gl.bufferData(gl.ARRAY_BUFFER, this.sizes, gl.STATIC_DRAW); this.pointSize = gl.getAttribLocation(this.program, 'pointSize'); gl.enableVertexAttribArray(this.pointSize); gl.vertexAttribPointer(this.pointSize, 1, gl.FLOAT, false, 0, 0); this.flatMatrix = gl.getUniformLocation(this.program, 'flatMatrix'); this.perspective = new DOMMatrix(); } run() { gl.useProgram(this.program); this.update(this); } updateBuffers(target) { // @TODO consider way to handle index buffers here // down the road gl.bindBuffer(gl.ARRAY_BUFFER, dots.vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, target.points, gl.DYNAMIC_DRAW); gl.vertexAttribPointer(dots.position, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, dots.colorBuffer); gl.bufferData(gl.ARRAY_BUFFER, target.colors, gl.DYNAMIC_DRAW); gl.vertexAttribPointer(dots.vertexColor, 4, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, dots.sizeBuffer); gl.bufferData(gl.ARRAY_BUFFER, target.sizes, gl.DYNAMIC_DRAW); gl.vertexAttribPointer(dots.pointSize, 1, gl.FLOAT, false, 0, 0); gl.uniformMatrix4fv(this.flatMatrix, false, target.perspective. toFloat32Array()); } // @TODO in theory this may also be something that // can be flyweight update(target) { gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); gl.vertexAttribPointer(target.position, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); gl.bufferData(gl.ARRAY_BUFFER, target.colors, gl.DYNAMIC_DRAW); gl.vertexAttribPointer(this.vertexColor, 4, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, this.sizeBuffer); gl.bufferData(gl.ARRAY_BUFFER, target.sizes, gl.DYNAMIC_DRAW); gl.vertexAttribPointer(this.pointSize, 1, gl.FLOAT, false, 0, 0); gl.uniformMatrix4fv(this.flatMatrix, false, target.perspective. toFloat32Array()); } draw() { gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); }} const plane = new FlyShape({ frag: ` precision lowp float; varying vec4 fragColor; void main(void) { gl_FragColor = fragColor; } `, verts: [ -1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 1, 0], indices: [0, 1, 2, 0, 2, 3], sizes: [0, 0, 0, 0], colors: [ 0, 0, 0, .015, 0, 0, 0, .015, 0, 0, 0, .015, 0, 0, 0, .015] }); const dots = new FlyShape(); function createPerspectiveMatrix(fov, width, height, near, far, .........完整代码请登录后点击上方下载按钮下载查看
网友评论0