Threejs 让宝可梦随着页面滚动而变换位置
先预览一下最终效果:
已关注
Follow
Replay
Like
前端程序设计
Added to Top Stories
视频卡顿,建议切换到自动
已成功切换至自动模式
时长
00:37
0 / 0
当前播放进度00:00
时长00:37
转载
Threejs 让宝可梦随着页面滚动而变换位置
前端程序设计
Added to Top Stories
进度00:00
时长00:37
时长00:37
全屏
倍速播放中
继续观看
Threejs 让宝可梦随着页面滚动而变换位置
制作方法类似前面的这篇,这次做了更多的优化处理。
引入的js库:
代码总共分3个模块:建立场景、加载模型、制作动画。
2.1 代码前期准备:
function _defineProperty(obj, key, value) {if (key in obj) {Object.defineProperty(obj, key, {value: value,enumerable: true,configurable: true,writable: true});} else {obj[key] = value;}return obj;}
2.2 建立场景类:
class Scene {constructor(model) {_defineProperty(this, "render",() =>{for (var ii = 0; ii < this.views.length; ++ii) {var view = this.views[ii];var camera = view.camera;var bottom = Math.floor(this.h * view.bottom);var height = Math.floor(this.h * view.height);this.renderer.setViewport(0, 0, this.w, this.h);this.renderer.setScissor(0, bottom, this.w, height);this.renderer.setScissorTest(true);camera.aspect = this.w / this.h;this.renderer.render(this.scene, camera);}});_defineProperty(this, "onResize",() =>{this.w = window.innerWidth;this.h = window.innerHeight;for (var ii = 0; ii < this.views.length; ++ii) {var view = this.views[ii];var camera = view.camera;camera.aspect = this.w / this.h;let camZ = (screen.width - this.w * 1) / 3;camera.position.z = camZ < 180 ? 180 : camZ;camera.updateProjectionMatrix();}this.renderer.setSize(this.w, this.h);this.render();});this.views = [{bottom: 0,height: 1},{bottom: 0,height: 0}];this.renderer = new THREE.WebGLRenderer({antialias: true,alpha: true});this.renderer.setSize(window.innerWidth, window.innerHeight);this.renderer.shadowMap.enabled = true;this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;this.renderer.setPixelRatio(window.devicePixelRatio);document.body.appendChild(this.renderer.domElement); // scenethis.scene = new THREE.Scene();for (var _ii = 0; _ii < this.views.length; ++_ii) {var _view = this.views[_ii];var _camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);_camera.position.fromArray([0, 0, 180]);_camera.layers.disableAll();_camera.layers.enable(_ii);_view.camera = _camera;_camera.lookAt(new THREE.Vector3(0, 5, 0));} //light// this.light = new THREE.PointLight(0xffffff, 0.75);// this.light.position.z = 150;// this.light.position.x = 70;// this.light.position.y = -20;// this.scene.add(this.light);// this.softLight = new THREE.AmbientLight(0xffffff, 1.5);// this.scene.add(this.softLight); // groupthis.light = new THREE.AmbientLight( new THREE.Color(0xababab)); // soft white lightthis.light.position.set(0,68,0);this.scene.add( this.light );this.dirLight = new THREE.DirectionalLight(new THREE.Color(0xababab));this.dirLight.position.set(-19.354,66.112,38.46);this.scene.add(this.dirLight);this.onResize();window.addEventListener('resize', this.onResize, false);console.log(model.children[0])var edges = new THREE.EdgesGeometry(model.children[0].geometry);let line = new THREE.LineSegments(edges);line.material.depthTest = false;line.material.opacity = 0.5;line.material.transparent = true;line.position.x = 0.5;line.position.z = -1;line.position.y = 0.2;this.modelGroup = new THREE.Group();model.layers.set(0);line.layers.set(1);this.modelGroup.add(model);this.modelGroup.add(line);this.scene.add(this.modelGroup);}}
2.3 加载obj模型:
function loadModel() {gsap.registerPlugin(ScrollTrigger);var object;function onModelLoaded() {object.traverse(function(child) {let mat = new THREE.MeshPhongMaterial({color: 0xff0000,specular: 0xD0CBC7,shininess: 5,flatShading: true});// child.material = mat;});setupAnimation(object);}var manager = new THREE.LoadingManager(onModelLoaded);manager.onProgress = (item, loaded, total) => console.log(item, loaded, total);var loader = new THREE.OBJLoader(manager);loader.load('2.obj',function(obj) {object = obj;});const mtlLoader = new THREE.MTLLoader();mtlLoader.load('2.mtl', (materials) => {console.log(materials)materials.preload();loader.setMaterials(materials);})}
2.4 制作动画
function setupAnimation(model) {let scene = new Scene(model);let plane = scene.modelGroup;//初始化位置{x: "50%",autoAlpha: 0},{duration: 1,x: "0%",autoAlpha: 1});{autoAlpha: 0});{opacity: 1});{autoAlpha: 1});let tau = Math.PI * 2;{y: tau * -.5});{x: -10,y: -12,z: 80});scene.render();var sectionDuration = 1;{height: 1,bottom: 0},{height: 0,bottom: 1,ease: 'none',scrollTrigger: {trigger: ".blueprint",scrub: true,start: "bottom bottom",end: "bottom top"}});{height: 0,bottom: 0},{height: 1,bottom: 0,ease: 'none',scrollTrigger: {trigger: ".blueprint",scrub: true,start: "top bottom",end: "top top"}});{y: "30%",scrollTrigger: {trigger: ".ground-container",scrub: true,start: "top bottom",end: "bottom top"}});{y: "25%",scrollTrigger: {trigger: ".ground-container",scrub: true,start: "top bottom",end: "bottom top"}});{drawSVG: 100,scrollTrigger: {trigger: ".length",scrub: true,start: "top bottom",end: "top top"}});{drawSVG: 100,scrollTrigger: {trigger: ".wingspan",scrub: true,start: "top 25%",end: "bottom 50%"}});{drawSVG: 100,scrollTrigger: {trigger: ".phalange",scrub: true,start: "top 50%",end: "bottom 100%"}});{opacity: 0,drawSVG: 0,scrollTrigger: {trigger: ".length",scrub: true,start: "top top",end: "bottom top"}});{opacity: 0,drawSVG: 0,scrollTrigger: {trigger: ".wingspan",scrub: true,start: "top top",end: "bottom top"}});{opacity: 0,drawSVG: 0,scrollTrigger: {trigger: ".phalange",scrub: true,start: "top top",end: "bottom top"}});let tl = new gsap.timeline({onUpdate: scene.render,scrollTrigger: {trigger: ".content",scrub: true,start: "top top",end: "bottom bottom"},defaults: {duration: sectionDuration,ease: 'power2.inOut'}});let delay = 0;{duration: 0.25,opacity: 0},delay);{x: -10,ease: 'power1.in'},delay);delay += sectionDuration;//1{x: tau * .25,y: 0,z: -tau * 0.05,ease: 'power1.inOut'},delay);{x: -40,y: 0,z: -60,ease: 'power1.inOut'},delay);delay += sectionDuration;//2{x: tau * .25,y: 0,z: tau * 0.05,ease: 'power3.inOut'},delay);{x: 40,y: 0,z: -60,ease: 'power2.inOut'},delay);delay += sectionDuration;//3{x: tau * .2,y: 0,z: -tau * 0.1,ease: 'power3.inOut'},delay);{x: -40,y: 0,z: -30,ease: 'power2.inOut'},delay);delay += sectionDuration;//4{x: 0,z: 0,y: tau * .25},delay);{x: 0,y: -10,z: 50},delay);delay += sectionDuration;delay += sectionDuration;//5{x: tau * 0.25,y: tau * .5,z: 0,ease: 'power4.inOut'},delay);{z: 30,ease: 'power4.inOut'},delay);delay += sectionDuration;//6{x: tau * 0.25,y: tau * .5,z: 0,ease: 'power4.inOut'},delay);{z: 60,x: 30,ease: 'power4.inOut'},delay);delay += sectionDuration;//7{x: tau * 0.35,y: tau * .75,z: tau * 0.6,ease: 'power4.inOut'},delay);{z: 100,x: 20,y: 0,ease: 'power4.inOut'},delay);delay += sectionDuration;//8{x: tau * 0.15,y: tau * .85,z: -tau * 0,ease: 'power1.in'},delay);{z: -150,x: 0,y: 0,ease: 'power1.inOut'},delay);delay += sectionDuration;//9{duration: sectionDuration,x: -tau * 0.5,y: -tau * 0.5,z: -tau * 0.1,ease: 'none'},delay);{duration: sectionDuration,x: 0,y: 30,z: 320,ease: 'power1.in'},delay);{duration: sectionDuration,x: 0,y: 0,z: 0},delay);}
下一篇要给这些小可爱加入动力学的碰撞。
