All Projects → alphardex → maku.js

alphardex / maku.js

Licence: other
A bridge between HTML and WebGL(three.js).

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Welcome to maku.js 👋

Version License: MIT Twitter: alphardex007

A bridge between HTML and WebGL(three.js).

Install

npm i maku.js

Usage

  1. Define some images in your HTML, and make them transparent
<div class="image-plane fixed z-0 w-screen h-screen pointer-events-none"></div>
<div class="bg-black">
  <div class="h-20"></div>
  <div class="gallery">
    <img
      class="gallery-item"
      src="https://i.loli.net/2021/10/09/UwaE61hgctofAFL.jpg"
      crossorigin="anonymous"
      alt=""
    />
    ...
  </div>
  <div class="h-20"></div>
</div>
img {
  opacity: 0;
}
  1. Use Maku Class to sync HTML with WebGL
import * as THREE from "three";
import { Maku, MakuGroup, Scroller, getScreenFov } from "maku.js";

// Select a container
const container = document.querySelector(".image-plane");

// Create scene
const scene = new THREE.Scene();

// Create camera
// The fov of camera can be calculated by the function below to sync the unit
const cameraPosition = new THREE.Vector3(0, 0, 600);
const fov = getScreenFov(cameraPosition.z);
const aspect = container.clientWidth / container.clientHeight;
const camera = new THREE.PerspectiveCamera(fov, aspect, 100, 2000);
camera.position.copy(cameraPosition);

// Create Renderer
const renderer = new THREE.WebGLRenderer({
  alpha: true,
  antialias: true,
});
renderer.setSize(container.clientWidth, container.clientHeight);
renderer.setClearColor(0x000000, 0);
container.appendChild(renderer.domElement);

// Select all the images you want to render in WebGL
const images = [...document.querySelectorAll("img")];

// Your own vertex shader
const imagePlaneMainVertexShader = `
varying vec2 vUv;

void main(){
    vec4 modelPosition=modelMatrix*vec4(position,1.);
    vec4 viewPosition=viewMatrix*modelPosition;
    vec4 projectedPosition=projectionMatrix*viewPosition;
    gl_Position=projectedPosition;

    vUv=uv;
}
`;

// Your own fragment shader
const imagePlaneMainFragmentShader = `
uniform sampler2D uTexture;

varying vec2 vUv;

void main(){
    vec4 texture=texture2D(uTexture,vUv);
    vec3 color=texture.rgb;
    gl_FragColor=vec4(color,1.);
}
`;

// Create a ShaderMaterial
const imagePlaneMaterial = new THREE.ShaderMaterial({
  vertexShader: imagePlaneMainVertexShader,
  fragmentShader: imagePlaneMainFragmentShader,
  side: THREE.DoubleSide,
  uniforms: {
    uTexture: {
      value: null,
    },
  },
});

// Make a MakuGroup that contains all the makus!
const makuGroup = new MakuGroup();
const makus = images.map((image) => new Maku(image, imagePlaneMaterial, scene));
makuGroup.addMultiple(makus);

// Sync images positions
makuGroup.setPositions();

// Make a scroller
const scroller = new Scroller();
scroller.listenForScroll();

// Sync scroll
const update = () => {
  scroller.syncScroll();
  const currentScrollY = scroller.scroll.current;
  makuGroup.setPositions(currentScrollY);
};

// Render the scene
renderer.setAnimationLoop(() => {
  update();
  renderer.render(scene, camera);
});

// And the basic setup is done!
// For more, you should visit demos below.
// https://codepen.io/collection/xKGjro

Link for this setup: Click Me

Demos

Click Me

Author

👤 alphardex

Show your support

Give a ⭐️ if this project helped you!


This README was generated with ❤️ by readme-md-generator

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].