threejs实现三维恐龙滑板动画效果代码
代码语言:html
所属分类:三维
代码描述:threejs实现三维恐龙滑板动画效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> body { margin: 0; } .world { position: absolute; overflow: hidden; width: 100%; height: 100%; background-color: #65BDCC; } .toggle-music { position: absolute; top: 1rem; left: 1rem; width: 3rem; height: 3rem; background: url('//repo.bfw.wiki/bfwrepo/icon/60d1c2f3e1d1e.png') center center / 70% no-repeat; cursor: pointer; } .music-off { background: url('//repo.bfw.wiki/bfwrepo/icon/60d1c2e3eff9a.gif') center center / 60% no-repeat; } </style> </head> <body > <div class="world"></div><a class="toggle-music"></a> <audio class="world-music" src="//repo.bfw.wiki/bfwrepo/sound/61397f63d3f7c.mp3"></audio> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.84.js"></script> <script> 'use strict'; let scene, camera, renderer, raycaster, mouseDown, world, night = false; let ground, city, dino; let width, height; let speed = 0.05; function init() { width = window.innerWidth, height = window.innerHeight; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 50); camera.position.set(-2, 2, 12); camera.lookAt(scene.position); renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(width, height); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; addLights(); drawGround(); drawCity(); drawDino(); world = document.querySelector('.world'); world.appendChild(renderer.domElement); document.addEventListener('mousedown', onMouseDown); document.addEventListener('mouseup', onMouseUp); document.addEventListener('touchstart', onTouchStart); document.addEventListener('touchend', onTouchEnd); window.addEventListener('resize', onResize); } function addLights() { const light = new THREE.HemisphereLight(); scene.add(light); const directLight1 = new THREE.DirectionalLight(0xffffff, 0.3); directLight1.castShadow = true; directLight1.position.set(20, 10, 18); scene.add(directLight1); const directLight2 = new THREE.DirectionalLight(0xffffff, 0.8); directLight2.castShadow = true; directLight2.position.set(-14, 6, 14); scene.add(directLight2); } function drawGround() { ground = new THREE.Mesh(new THREE.PlaneGeometry(90, 30), new THREE.MeshStandardMaterial({ color: 0x375076, roughness: 1 })); ground.rotation.x = -Math.PI / 2; ground.position.y = -0.6; ground.receiveShadow = true; scene.add(ground); } function drawCity() { city = new City(); scene.add(city.group); } function drawDino() { dino = new Dino(); scene.add(dino.group); } function onResize() { width = window.innerWidth; height = window.innerHeight; camera.aspect = width / height; camera.updateProjectionMatrix(); renderer.setSize(width, height); } function onMouseDown(event) { mouseDown = true; } function onTouchStart(event) { if (event.target.classList[0] === 'toggle-music') return; event.preventDefault(); mouseDown = true; if (speed !== 0.1) speed = 0.1; } function onMouseUp() { mouseDown = false; } function onTouchEnd(event) { if (event.target.classList[0] === 'toggle-music') return; event.preventDefault(); mouseDown = false; } function animate() { requestAnimationFrame(animate); render(); } function render() { if (mouseDown) { city.move(speed * 2); dino.moveFast(speed * 2); } else { city.move(speed); dino.move(speed); } city.road.forEach(bus => { bus.moveOut(dino.group.position); }); renderer.render(scene, camera); } class City { constructor() { this.group = new THREE.Group(); this.city = new THREE.Group(); this.group.add(this.city); this.drawCity(); this.drawRoad(); this.drawSky(); } drawCity() { this.line1 = new THREE.Group(); this.line1.position.z = -3; this.city.add(this.line1); const houses = new THREE.Group(); houses.name = 'houses'; this.line1.add(houses); const houseMaterial = new THREE.MeshStandardMaterial({ color: 0x2697A8, roughness: 1, shading: THREE.FlatShading }); const windowMaterial = new THREE.MeshStandardMaterial({ color: 0xEDF0F8, roughness: 1, shading: THREE.FlatShading }); const windows = new THREE.Group(); const window1 = this.drawBox(0.2, 0.4, 0.3, windowMaterial); const window2 = window1.clone(); window2.position.x = 0.3; const window3 = window2.clone(); window3.position.y = 0.5; const window4 = window1.clone(); window4.position.y = 0.5; windows.add(window1); windows.add(window2); windows.add(window3); windows.add(window4); const house1 = this.drawBox(1, 1.2, 1, houseMaterial); const house1Windows = windows.clone(); house1Windows.position.set(-0.2, -0.2, 0.5); house1.add(house1Windows); houses.add(house1); const house2 = this.drawBox(1.1, 2.4, 1, houseMaterial); house2.position.set(1, 0.6, 0); const house2Windows = windows.clone(); house2Windows.position.set(0, 0.3, 0.5); house2.add(house2Windows); houses.add(house2); const house3 = this.drawBox(1.4, 1.6, 1, houseMaterial); house3.position.set(2.25, 0.2, 0); const house3Windows = windows.clone(); house3Windows.position.set(0, -0.4, 0.5); house3.add(house3Windows); houses.add(house3); const house4 = this.drawBox(0.9, 1, 1, houseMaterial); house4.position.set(3.4, -0.1, 0); const house4Window = window1.clone(); house4Window.position.set(0.2, 0.1, 0.5); house4.add(house4Window); houses.add(house4); const house5 = this.drawBox(1.2, 3.7, 1, houseMaterial); house5.position.set(4.5, 1.25, 0); const house5Windows = windows.clone(); house5Windows.position.set(-0.3, -0.2, 0.5); house5.add(house5Windows); houses.add(house5); for (let i = 0; i < 8; i++) { const housesClone = houses.clone(); housesClone.position.x = houses.position.x - 5.6 * (i + 1); this.line1.add(housesClone); } for (let i = 0; i < 8; i++) { const housesClone = houses.clone(); housesClone.position.x = houses.position.x + 5.6 * (i + 1); this.line1.add(housesClone); } this.line2 = this.line1.clone(); this.line2.position.set(-1, 0.3, -5); this.city.add(this.line2); this.line3 = this.line1.clone(); this.line3.position.set(-2, 0.7, -8); this.city.add(this.line3); this.line4 = this.line1.clone(); this.line4.position.set(-1.5, 1, -11); this.city.add(this.line4); } drawRoad() { this.road = []; const colors = [0x65BDCC, 0xC40066, 0xE0C538]; for (let i = 0; i < 50; i++) { const randomColor = colors[Math.floor(Math.random() * colors.length)]; const bus = new Bus(randomColor); bus.group.origX = Math.random() * 80 - 40; bus.group.origY = -0.25; bus.group.origZ = 0.8 + 3 * i / 12; bus.group.position.set(bus.group.origX, bus.group.origY, bus.group.origZ); this.group.add(bus.group); this.road.push(bus); } } drawSky() { this.sky = new THREE.Group(); this.group.add(this.sky); const geometry = new THREE.IcosahedronGeometry(0.2, 0); for (let i = 0; i < 150; i++) { const material = new THREE.MeshStandardMaterial({ color: 0xA9EFF9, roughness: 1, shading: THREE.FlatShading }); const mesh = new THREE.Mesh(geometry, material); mesh.position.set(Math.random() * 100 - 50, Math.random() * 12 + 4, Math.random() * 10 - 15); this.sky.add(mesh); } } drawCylinder(rTop, rBottom, height, rSeg, material) { const cylinder = new THREE.Mesh(new THREE.CylinderGeometry(rTop, rBottom, height, rSeg), material); cylinder.castShadow = true; cylinder.receiveShadow = true; return cylinder; } drawBox(w, h, d, material) { const box = new THREE.Mesh(new THREE.BoxGeometry(w, h, d), material); box.castShadow = true; box.receiveShadow = true; return box; } deg(degrees) { return degrees * (Math.PI / 180); } move(speed) { const lineLimits = [56, 54, 52, 53]; const lines = [this.line1, this.line2, this.line3, this.line4]; lines.forEach((line, index) => { line.traverse(houses => { if (houses.name === 'houses') { houses.position.x += speed; if (houses.position.x > lineLimits[index]) { houses.position.x = lineLimits[index] - 95.2; } } }); }); this.sky.traverse(cloud => { if (cloud instanceof THREE.Mesh) { cloud.position.x += speed; if (cloud.position.x > 50) { cloud.position.x = -50; } } }); this.road.forEach(bus => { bus.move(speed); }); }} class Dino { constructor() { this.group = new THREE.Group(); this.group.position.y = 0.7; this.group.position.z = 6; this.vAngle = 0; this.skinMaterial = new THREE.MeshStandardMaterial({ color: 0xE0C538, roughness: 1, shading: THREE.FlatShading }); this.whiteMaterial = new THREE.MeshStandardMaterial({ color: 0xEDF0F8, roughness: 1, shading: THREE.FlatShading }); this.darkMaterial = new THREE.MeshStandardMaterial({ color: 0x375076, roughness: 1, shading: THREE.FlatShading }); this.drawBody(); this.drawLegs(); this.drawAirship(); } drawBody() { this.body = new THREE.Group(); this.body.position.y = 0.75; this.body.rotation.set(this.deg(-23.3), this.deg(40), this.deg(34)); this.group.add(this.body); const torso = this.drawCylinder(0.4, 1, 1.3, 4, this.skinMaterial); torso.position.y = 0.95; this.body.add(torso); const back = this.drawCylinder(1, 0.75, 0.85, 4, this.skinMaterial); back.position.y = -0.11; this.body.add(back); this.drawHead(); this.drawTail(); this.drawHands(); } drawHead() { this.head = new THREE.Group(); this.head.rotation.set(0, this.deg(-45), this.deg(-20)); this.head.posit.........完整代码请登录后点击上方下载按钮下载查看
网友评论0