动画
<canvas id="mainCanvas"></canvas>
<script type="importmap">
{
"imports": {
"three": "./js/build/three.module.js",
"three/addons/": "./js/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";
import { TrackballControls } from "three/addons/controls/TrackballControls.js";
import { GUI } from "three/addons/libs/lil-gui.module.min.js";
import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight, addPlane, addBox, addSphere, addCylinder } from "./init.js";
const gui = new GUI();
function init() {
window.addEventListener("resize", onResize, false);
document.addEventListener("mousedown", onDocumentMouseDown, false);
document.addEventListener("mousemove", onDocumentMouseMove, false);
const renderer = initRenderer("mainCanvas");
const scene = new THREE.Scene();
const camera = initPerspectiveCamera();
scene.add(camera);
const ambientLight = initAmbientLight();
scene.add(ambientLight);
const spotLight = initSpotLight();
scene.add(spotLight);
const plane = addPlane();
scene.add(plane);
const cube = addBox({ color: 0xff0000, width: 4, height: 4, depth: 4 });
cube.position.set(-10, 5, 0);
scene.add(cube);
const sphere = addSphere({ color: 0x7777ff, radius: 4 });
sphere.position.set(20, 5, 0);
scene.add(sphere);
const cylinder = addCylinder({ color: 0x77ff77, tr: 2, br: 2, height: 20 });
scene.add(cylinder);
let step = 0;
let scalingStep = 0;
const controls = new (function () {
this.rotationSpeed = 0.02;
this.bouncingSpeed = 0.03;
this.scalingSpeed = 0.03;
this.showRay = false;
})();
gui.add(controls, "rotationSpeed", 0, 0.5);
gui.add(controls, "bouncingSpeed", 0, 0.5);
gui.add(controls, "scalingSpeed", 0, 0.5);
gui.add(controls, "showRay").onChange(function (e) {
if (tube) scene.remove(tube);
});
const trackballControls = new TrackballControls(camera, renderer.domElement);
const clock = new THREE.Clock();
let tube;
render();
function render() {
trackballControls.update(clock.getDelta());
cube.rotation.x += controls.rotationSpeed;
cube.rotation.y += controls.rotationSpeed;
cube.rotation.z += controls.rotationSpeed;
step += controls.bouncingSpeed;
sphere.position.x = 20 + 10 * Math.cos(step);
sphere.position.y = 2 + 10 * Math.abs(Math.sin(step));
scalingStep += controls.scalingSpeed;
const scaleX = Math.abs(Math.sin(scalingStep / 4));
const scaleY = Math.abs(Math.cos(scalingStep / 5));
const scaleZ = Math.abs(Math.sin(scalingStep / 7));
cylinder.scale.set(scaleX, scaleY, scaleZ);
requestAnimationFrame(render);
renderer.render(scene, camera);
}
function onResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onDocumentMouseDown(event) {
let vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1, 0.5);
vector = vector.unproject(camera); //将此向量(坐标)从相机的标准化设备坐标 (NDC) 空间投影到世界空间
// 光线投射Raycaster 用于进行raycasting(光线投射)。光线投射用于进行鼠标拾取
const raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
const intersects = raycaster.intersectObjects([sphere, cylinder, cube]); //检测所有在射线与这些物体之间,包括或不包括后代的相交部分。
if (intersects.length > 0) {
console.log(intersects[0]);
intersects[0].object.material.transparent = true; //未生效 ???
intersects[0].object.material.opacity = 0.1;
}
}
function onDocumentMouseMove(event) {
if (controls.showRay) {
let vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1, 0.5);
vector = vector.unproject(camera);
const raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
const intersects = raycaster.intersectObjects([sphere, cylinder, cube]);
if (intersects.length > 0) {
const points = [];
points.push(new THREE.Vector3(-30, 29.8, 30));
points.push(intersects[0].point);
const mat = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.6 });
const tubeGeometry = new THREE.TubeGeometry(new THREE.CatmullRomCurve3(points), 60, 0.001);
if (tube) scene.remove(tube);
if (controls.showRay) {
tube = new THREE.Mesh(tubeGeometry, mat);
scene.add(tube);
}
}
}
}
}
init();
</script>
TWEEN
<canvas id="mainCanvas"></canvas>
<script type="importmap">
{
"imports": {
"three": "./js/build/three.module.js",
"three/addons/": "./js/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";
import { TrackballControls } from "three/addons/controls/TrackballControls.js";
import { GUI } from "three/addons/libs/lil-gui.module.min.js";
import * as TWEEN from "three/addons/libs/tween.module.js";
import { PLYLoader } from "three/addons/loaders/PLYLoader.js";
import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight } from "./init.js";
function init() {
const renderer = initRenderer("mainCanvas");
const scene = new THREE.Scene();
const camera = initPerspectiveCamera();
scene.add(camera);
const ambientLight = initAmbientLight();
scene.add(ambientLight);
const spotLight = initSpotLight();
scene.add(spotLight);
const posSrc = { pos: 1 };
const tween = new TWEEN.Tween(posSrc).to({ pos: 0 }, 2000);
tween.easing(TWEEN.Easing.Bounce.InOut);
const tweenBack = new TWEEN.Tween(posSrc).to({ pos: 1 }, 2000);
tweenBack.easing(TWEEN.Easing.Bounce.InOut);
tweenBack.chain(tween);
tween.chain(tweenBack);
tween.start();
let group;
const loader = new PLYLoader();
loader.load("./models/ply/ascii/dolphins.ply", function (geometry) {
const origPosition = geometry.attributes["position"].clone();
geometry.origPosition = origPosition;
const material = new THREE.PointsMaterial({
color: 0xffffff,
size: 1,
opacity: 0.6,
transparent: true,
blending: THREE.AdditiveBlending,
depthWrite: false,
map: generateSprite(),
});
group = new THREE.Points(geometry, material);
group.scale.set(0.05, 0.05, 0.05);
scene.add(group);
});
const trackballControls = new TrackballControls(camera, renderer.domElement);
const clock = new THREE.Clock();
render();
function render() {
trackballControls.update(clock.getDelta());
TWEEN.update();
if (typeof group != "undefined") {
const positionArray = group.geometry.attributes["position"];
const origPosition = group.geometry.origPosition;
for (let i = 0; i < positionArray.count; i++) {
const oldPosX = origPosition.getX(i);
const oldPosY = origPosition.getY(i);
const oldPosZ = origPosition.getZ(i);
positionArray.setX(i, oldPosX * posSrc.pos);
positionArray.setY(i, oldPosY * posSrc.pos);
positionArray.setZ(i, oldPosZ * posSrc.pos);
}
positionArray.needsUpdate = true;
}
requestAnimationFrame(render);
renderer.render(scene, camera);
}
}
function generateSprite() {
const canvas = document.createElement("canvas");
canvas.width = 16;
canvas.height = 16;
const context = canvas.getContext("2d");
const gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
gradient.addColorStop(0, "rgba(255,255,255,1)");
gradient.addColorStop(0.2, "rgba(0,255,255,1)");
gradient.addColorStop(0.4, "rgba(0,0,64,1)");
gradient.addColorStop(1, "rgba(0,0,0,1)");
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
const texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
return texture;
}
init();
</script>
标签:scene,动画,const,THREE,three,add,new,js From: https://www.cnblogs.com/caroline2016/p/18208941