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