|
| 1 | +import * as THREE from 'three' |
| 2 | +import { isStr } from './isStr' |
| 3 | +import { addEventListener } from './addEventListener' |
| 4 | +import { animationFrameWrapper } from './animationFrameWrapper' |
| 5 | + |
| 6 | +interface SThreeOptions extends Record<string, any> { |
| 7 | + createTargets: (THREE: any) => { targets: any[]; contents: any[] } |
| 8 | + createCamera: (THREE: any) => THREE.PerspectiveCamera |
| 9 | + animate: (THREE: any, targets: any[], time: number) => void | THREE.PerspectiveCamera |
| 10 | + middleware: (THREE: any, targets: any[]) => void |
| 11 | +} |
| 12 | +export function sThree(container: HTMLElement | string, options: SThreeOptions) { |
| 13 | + const renderer = new THREE.WebGLRenderer() |
| 14 | + const scene = new THREE.Scene() |
| 15 | + const camera = options.createCamera(THREE) |
| 16 | + const { targets, contents } = options.createTargets(THREE) |
| 17 | + contents.forEach(content => scene.add(content)) |
| 18 | + options.middleware?.(THREE, targets) |
| 19 | + if (options.animate) |
| 20 | + animationFrameWrapper((time: number) => renderer.render(scene, options.animate(THREE, targets, time) || camera), 0) |
| 21 | + else |
| 22 | + renderer.render(scene, camera) |
| 23 | + |
| 24 | + addEventListener(document, 'DOMContentLoaded', () => { |
| 25 | + if (isStr(container)) |
| 26 | + container = document.querySelector(container as string) as HTMLElement || container |
| 27 | + if (isStr(container)) |
| 28 | + throw new Error(`${container} container is not found`) |
| 29 | + ; (container as HTMLElement).appendChild(renderer.domElement) |
| 30 | + resize() |
| 31 | + }) |
| 32 | + addEventListener(window, 'resize', resize) |
| 33 | + |
| 34 | + function resize() { |
| 35 | + const width = (container as HTMLElement).offsetWidth |
| 36 | + const height = (container as HTMLElement).offsetHeight |
| 37 | + camera.aspect = width / height |
| 38 | + camera.updateProjectionMatrix() |
| 39 | + renderer.setSize(width, height, false) |
| 40 | + } |
| 41 | +} |
| 42 | + |
0 commit comments