ThreeJS - 3D Bar and Progress Bar > 개발자팁

개발자팁

개발과 관련된 유용한 정보를 공유하세요.
질문은 QA에서 해주시기 바랍니다.

ThreeJS - 3D Bar and Progress Bar 정보

JavaScript ThreeJS - 3D Bar and Progress Bar

본문


import * as THREE from "https://cdn.skypack.dev/three@0.136.0";
import {OrbitControls} from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls";
import {createNoise2D} from "https://cdn.skypack.dev/simplex-noise@4.0.0";
console.clear();
let scene = new THREE.Scene();
scene.background = new THREE.Color(0x7f7f7f);
let camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 1, 1000);
camera.position.set(-5, 10, 10).setLength(20);
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", event => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
})
let controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
let light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.set(0.75, 0.5, 1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));
scene.add(new THREE.GridHelper());
class ProgressBar extends THREE.Sprite{
  constructor(_progress){
    super();
    this.scale.set(2, 0.1);
    this.material = new THREE.SpriteMaterial({
      onBeforeCompile: shader => {
        shader.uniforms.progress = _progress;
        shader.fragmentShader = `
          #define ss(a, b, c) smoothstep(a, b, c)
          uniform float progress;
          ${shader.fragmentShader}
        `.replace(
          `outgoingLight = diffuseColor.rgb;`,
          `outgoingLight = diffuseColor.rgb;
            vec3 backColor = mix(vec3(0), vec3(0, 0.5, 0), progress);
            float pb = step(progress, vUv.x);
            outgoingLight.rgb = mix(vec3(0, 1, 0), backColor, pb);
          `
        );
        console.log(shader.fragmentShader);
      }
    });
    this.material.defines = {"USE_UV" : ""};
    this.center.set(0.5, 0);
  }
}
class ProgressObject extends THREE.Object3D{
  constructor(height){
    const rand = Math.random() * 100;
    const noise = createNoise2D();
    super();
    let _progress = {value: 0.5};
    let og = new THREE.BoxGeometry().translate(0, 0.5, 0);
    let om = new THREE.MeshLambertMaterial();
    let o = new THREE.Mesh(og, om);
    o.scale.y = height;
    
    let lg = new THREE.EdgesGeometry(new THREE.BoxGeometry());
    lg.translate(0, 0.5, 0);
    lg.scale(1, height, 1);
    let lm = new THREE.LineBasicMaterial({color: new THREE.Color(Math.random() * 0xffffff).multiplyScalar(0.5).addScalar(0.5)});
    let l = new THREE.LineSegments(lg, lm);
    
    let pbar = new ProgressBar(_progress);
    pbar.position.y = height * 1.1;
    
    this.add(o, l, pbar);
    
    this.update = val => {
      _progress.value = noise(val, 0.25) * 0.5 + 0.5;
      o.scale.y = height * _progress.value;
    }
  }
}
let tmu = THREE.MathUtils;
let POs = new Array(5).fill().map(o => {
  let po = new ProgressObject(tmu.randInt(2, 5));
  po.position.x = tmu.randInt(-5, 4) + 0.5;
  po.position.z = tmu.randInt(-5, 4) + 0.5;
  scene.add(po);
  return po
})
let clock = new THREE.Clock();
renderer.setAnimationLoop(() => {
  controls.update();
  let t = clock.getElapsedTime() * 0.5;
  POs.forEach(po => {po.update(t)});
  renderer.render(scene, camera);
});
추천
1

댓글 1개

전체 5,352
개발자팁 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT