Skip to main content

Try vis-engine

Using an ES6 Module Bundler

Install the package.

yarn add @sakitam-gis/vis-engine

一个简单的示例

Result
Loading...
Live Editor
function render(props) {
  const drawModelVertex = `
    attribute vec2 uv;
    attribute vec3 position;
    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;

    varying vec2 vUv;

    void main() {
        vUv = uv;

        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);

        // gl_PointSize only applicable for gl.POINTS draw mode
        gl_PointSize = 5.0;
    }
    `;

  const drawModelFragment = `
    precision highp float;

    uniform float uTime;
    varying vec2 vUv;

    void main() {
        gl_FragColor.rgb = 0.5 + 0.3 * sin(vUv.yxx + uTime) + vec3(0.2, 0.0, 0.1);
        gl_FragColor.a = 1.0;
    }
    `;

  const refDom = useRef(null);
  const meshRef = useRef(null);
  const cameraRef = useRef(null);
  const renderRef = useRef(null);

  const store = leva.useCreateStore();

  const fov = 15;
  const nearZ = 0.1;

  const farZ = 100;

  const config = {
    fov: {
      value: fov,
      min: -50,
      max: 50,
      step: 1,
      onChange: (fov) => {
        if (cameraRef.current) {
          cameraRef.current.fov = fov;
        }
      },
    },
    nearZ: {
      value: nearZ,
      min: -50,
      max: 50,
      step: 0.1,
      onChange: (nearZ) => {
        if (cameraRef.current) {
          cameraRef.current.nearZ = nearZ;
        }
      },
    },
    farZ: {
      value: farZ,
      min: -500,
      max: 500,
      step: 1,
      onChange: (farZ) => {
        if (cameraRef.current) {
          cameraRef.current.farZ = farZ;
        }
      },
    },
    cameraPosition: {
      value: [0, 0, 15],
      onChange: (p) => {
        if (cameraRef.current) {
          cameraRef.current.position.set(...p);
        }
      },
    },
    wireframe: {
      value: false,
      onChange: (p) => {
        if (meshRef.current) {
          meshRef.current.wireframe = p;
        }
      },
    }
  };

  leva.useControls(config, {
    store: store,
  });

  const init = () => {
    const canvas = refDom.current;

    canvas.width = canvas.clientWidth;
    canvas.height = canvas.clientHeight;
    const renderer = new Renderer(canvas, {
      alpha: true,
    });

    renderRef.current = renderer;

    const camera = new PerspectiveCamera(fov, canvas.width / canvas.height, nearZ, farZ);
    camera.position.z = fov;

    cameraRef.current = camera;

    function resize(target) {
      const { width, height } = target.getBoundingClientRect();
      renderer.setSize(width, height);
      camera.aspect = width / height;
    }

    const scene = new Scene();

    const geometry = new Geometry(renderer, {
      position: {
        size: 3,
        data: new Float32Array([
          -1.6, 1.5, 0,
          -1, -1, 0,
          1, -1, 0,
          -1, -1, 0,
          1, -1, 0,
          1.6, 1.5, 0,
        ])
      },
    });

    const program = new Program(renderer, {
      vertexShader: drawModelVertex,
      fragmentShader: drawModelFragment,
      uniforms: {
        uTime: { value: 0 },
      },
    });

    const triangles = new Mesh(renderer, { mode: renderer.gl.TRIANGLES, geometry, program });
    triangles.setParent(scene);
    triangles.position.set(0, 0, 0);

    meshRef.current = triangles;

    const raf = new Raf((t) => {
      program.setUniform('uTime', t);
      renderer.render({ scene, camera });
    });

    return {
      canvas,
      resize,
    }
  }

  useEffect(() => {
    const { canvas, resize } = init();

    observe(canvas, resize);

    return () => {
      unobserve(canvas, resize);
    };
  }, []);

  return (
    <div className="live-wrap">
      <div className="leva-wrap">
        <Leva
          fill
        ></Leva>
        <LevaPanel store={store} fill></LevaPanel>
      </div>
      <canvas className="scene-canvas" ref={refDom}></canvas>
    </div>
  );
}
import React, { useRef, useEffect } from 'react';
import { useControls, Leva, useCreateStore, LevaPanel } from 'leva';
import vertex from 'raw-loader!glslify-loader!./shaders/draw-modes.vert.glsl';
import fragment from 'raw-loader!glslify-loader!./shaders/draw-modes.frag.glsl';

import { observe, unobserve } from '../utils/observer';

import { Renderer, Mesh, Raf, Scene, Program, PerspectiveCamera, Geometry } from '@sakitam-gis/vis-engine';

export default function DrawModel(props) {
const refDom = useRef(null);
const meshRef = useRef(null);
const cameraRef = useRef(null);
const renderRef = useRef(null);

const store = useCreateStore();

const fov = 15;
const nearZ = 0.1;

const farZ = 100;

const config: any = {
fov: {
value: fov,
min: -50,
max: 50,
step: 1,
onChange: (fov) => {
if (cameraRef.current) {
cameraRef.current.fov = fov;
}
},
},
nearZ: {
value: nearZ,
min: -50,
max: 50,
step: 0.1,
onChange: (nearZ) => {
if (cameraRef.current) {
cameraRef.current.near = nearZ;
}
},
},
farZ: {
value: farZ,
min: -500,
max: 500,
step: 1,
onChange: (farZ) => {
if (cameraRef.current) {
cameraRef.current.far = farZ;
}
},
},
cameraPosition: {
value: [0, 0, 15],
onChange: (p) => {
if (cameraRef.current) {
cameraRef.current.position.set(...p);
}
},
},
wireframe: {
value: false,
onChange: (p) => {
if (meshRef.current) {
meshRef.current.wireframe = p;
}
},
}
};

useControls(config, {
store: store,
});

const init = () => {
const canvas = refDom.current;

canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
const renderer = new Renderer(canvas, {
alpha: true,
});

renderRef.current = renderer;

const camera = new PerspectiveCamera(fov, canvas.width / canvas.height, nearZ, farZ);
camera.position.z = fov;

cameraRef.current = camera;

function resize(target) {
const { width, height } = target.getBoundingClientRect();
renderer.setSize(width, height);
camera.aspect = width / height;
}

const scene = new Scene();

const geometry = new Geometry(renderer, {
position: {
size: 3,
data: new Float32Array([
-1.6, 1.5, 0,
-1, -1, 0,
1, -1, 0,
-1, -1, 0,
1, -1, 0,
1.6, 1.5, 0,
])
},
});

const program = new Program(renderer, {
vertexShader: vertex,
fragmentShader: fragment,
uniforms: {
uTime: { value: 0 },
},
});

const triangles = new Mesh(renderer, { mode: renderer.gl.TRIANGLES, geometry, program });
triangles.setParent(scene);
triangles.position.set(0, 0, 0);

meshRef.current = triangles;

const raf = new Raf((t) => {
program.setUniform('uTime', t);
renderer.render({ scene, camera });
});

return {
canvas,
resize,
}
}

useEffect(() => {
const { canvas, resize } = init();

observe(canvas, resize);

return () => {
unobserve(canvas, resize);
};
}, []);

return (
<div className="live-wrap">
<div className="leva-wrap">
<Leva
fill
></Leva>
<LevaPanel store={store} fill></LevaPanel>
</div>
<canvas className="scene-canvas" ref={refDom}></canvas>
</div>
);
}