您所在的位置:Web培训学院>web特效设计 > three.js简介——3D框架

three.js简介——3D框架

2017-12-27 18:02:18来源:互联网浏览次数:

  1. <!DOCTYPE html> 
  2. <html lang="en"
  3.  
  4. <head> 
  5.   <meta charset="UTF-8"
  6.   <title>Bestvist | threejs-cat</title> 
  7.   <meta name="keywords" content="THREEJS,javascript"
  8.   <meta name="description" content="随着HTML5的普及,网页的表现能力越来越强大,浏览器提供了WebGL接口,可以通过调用对应API进行3D图形的绘制,Three.js在这些基础接口之上又做了一层封装。"
  9.  
  10.   <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css"
  11.  
  12.   <style> 
  13.     @import url(https://fonts.googleapis.com/css?family=Open+Sans:800); 
  14.  
  15.     #world { 
  16.       position: absolute; 
  17.       width: 100%; 
  18.       height: 100%; 
  19.       background-color: #6ecccc; 
  20.       overflow: hidden; 
  21.     } 
  22.  
  23.     #doc { 
  24.       position: absolute; 
  25.       width: 100%; 
  26.       margin: auto; 
  27.       bottom: 0; 
  28.       margin-bottom: 20px; 
  29.       font-family: 'Open Sans', sans-serif; 
  30.       color: #328685; 
  31.       font-size: 0.7em; 
  32.       text-transform: uppercase; 
  33.       text-align: center; 
  34.     } 
  35.  
  36.     #doc a { 
  37.       color: #328685; 
  38.     } 
  39.  
  40.     #doc a:hover { 
  41.       color: #630d15; 
  42.     } 
  43.   </style> 
  44. </head> 
  45.  
  46. <body> 
  47.  
  48.   <div id="world" /> 
  49.  
  50.   <div id="doc"><a href="http://www.bestvist.com/2017/12/25/threejs/">Three.js简介</a></div> 
  51.  
  52.   <script src='http://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js'></script> 
  53.   <script src='http://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js'></script> 
  54.   <script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/OrbitControls.js'></script> 
  55.   <script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/Cat.js'></script> 
  56.  
  57.   <script> 
  58.     //THREEJS RELATED VARIABLES  
  59.  
  60.     var scene, 
  61.       camera, fieldOfView, aspectRatio, nearPlane, farPlane, 
  62.       gobalLight, shadowLight, backLight, 
  63.       renderer, 
  64.       container, 
  65.       controls; 
  66.  
  67.     //SCREEN & MOUSE VARIABLES 
  68.  
  69.     var HEIGHT, WIDTH, windowHalfX, windowHalfY, 
  70.       mousePos = { 
  71.         x: 0, 
  72.         y: 0 
  73.       }, 
  74.       oldMousePos = { 
  75.         x: 0, 
  76.         y: 0 
  77.       }, 
  78.       ballWallDepth = 28; 
  79.  
  80.  
  81.     //3D OBJECTS VARIABLES 
  82.  
  83.     var hero; 
  84.  
  85.     //INIT THREE JS, SCREEN AND MOUSE EVENTS 
  86.  
  87.     function initScreenAnd3D() { 
  88.  
  89.       HEIGHT = window.innerHeight; 
  90.       WIDTH = window.innerWidth; 
  91.       windowHalfX = WIDTH / 2; 
  92.       windowHalfY = HEIGHT / 2; 
  93.  
  94.       scene = new THREE.Scene(); 
  95.       aspectRatio = WIDTH / HEIGHT; 
  96.       fieldOfView = 50; 
  97.       nearPlane = 1; 
  98.       farPlane = 2000; 
  99.       camera = new THREE.PerspectiveCamera( 
  100.         fieldOfView, 
  101.         aspectRatio, 
  102.         nearPlane, 
  103.         farPlane 
  104.       ); 
  105.       camera.position.x = 0; 
  106.       camera.position.z = 300; 
  107.       camera.position.y = 250; 
  108.       camera.lookAt(new THREE.Vector3(0, 60, 0)); 
  109.  
  110.       renderer = new THREE.WebGLRenderer({ 
  111.         alpha: true
  112.         antialias: true 
  113.       }); 
  114.       renderer.setPixelRatio(window.devicePixelRatio); 
  115.       renderer.setSize(WIDTH, HEIGHT); 
  116.       renderer.shadowMapEnabled = true
  117.  
  118.       container = document.getElementById('world'); 
  119.       container.appendChild(renderer.domElement); 
  120.  
  121.       window.addEventListener('resize', handleWindowResize, false); 
  122.       document.addEventListener('mousemove', handleMouseMove, false); 
  123.       document.addEventListener('touchmove', handleTouchMove, false); 
  124.     } 
  125.  
  126.     function handleWindowResize() { 
  127.       HEIGHT = window.innerHeight; 
  128.       WIDTH = window.innerWidth; 
  129.       windowHalfX = WIDTH / 2; 
  130.       windowHalfY = HEIGHT / 2; 
  131.       renderer.setSize(WIDTH, HEIGHT); 
  132.       camera.aspect = WIDTH / HEIGHT; 
  133.       camera.updateProjectionMatrix(); 
  134.     } 
  135.  
  136.     function handleMouseMove(event) { 
  137.       mousePos = { 
  138.         x: event.clientX, 
  139.         y: event.clientY 
  140.       }; 
  141.     } 
  142.  
  143.     function handleTouchMove(event) { 
  144.       if (event.touches.length == 1) { 
  145.         event.preventDefault(); 
  146.         mousePos = { 
  147.           x: event.touches[0].pageX, 
  148.           y: event.touches[0].pageY 
  149.         }; 
  150.       } 
  151.     } 
  152.  
  153.     function createLights() { 
  154.       globalLight = new THREE.HemisphereLight(0xffffff, 0xffffff, .5) 
  155.  
  156.       shadowLight = new THREE.DirectionalLight(0xffffff, .9); 
  157.       shadowLight.position.set(200, 200, 200); 
  158.       shadowLight.castShadow = true
  159.       shadowLight.shadowDarkness = .2; 
  160.       shadowLight.shadowMapWidth = shadowLight.shadowMapHeight = 2048; 
  161.  
  162.       backLight = new THREE.DirectionalLight(0xffffff, .4); 
  163.       backLight.position.set(-100, 100, 100); 
  164.       backLight.castShadow = true
  165.       backLight.shadowDarkness = .1; 
  166.       backLight.shadowMapWidth = shadowLight.shadowMapHeight = 2048; 
  167.  
  168.       scene.add(globalLight); 
  169.       scene.add(shadowLight); 
  170.       scene.add(backLight); 
  171.     } 
  172.  
  173.     function createFloor() { 
  174.       floor = new THREE.Mesh(new THREE.PlaneBufferGeometry(1000, 1000), new THREE.MeshBasicMaterial({ 
  175.         color: 0x6ecccc 
  176.       })); 
  177.       floor.rotation.x = -Math.PI / 2; 
  178.       floor.position.y = 0; 
  179.       floor.receiveShadow = true
  180.       scene.add(floor); 
  181.     } 
  182.  
  183.     function createHero() { 
  184.       hero = new Cat(); 
  185.       scene.add(hero.threeGroup); 
  186.     } 
  187.  
  188.     function createBall() { 
  189.       ball = new Ball(); 
  190.       scene.add(ball.threeGroup); 
  191.     } 
  192.  
  193.     // BALL RELATED CODE 
  194.  
  195.  
  196.     var woolNodes = 10, 
  197.       woolSegLength = 2, 
  198.       gravity = -.8, 
  199.       accuracy = 1; 
  200.  
  201.  
  202.     Ball = function () { 
  203.  
  204.       var redMat = new THREE.MeshLambertMaterial({ 
  205.         color: 0x630d15, 
  206.         shading: THREE.FlatShading 
  207.       }); 
  208.  
  209.       var stringMat = new THREE.LineBasicMaterial({ 
  210.         color: 0x630d15, 
  211.         linewidth: 3 
  212.       }); 
  213.  
  214.       this.threeGroup = new THREE.Group(); 
  215.       this.ballRay = 8; 
  216.  
  217.       this.verts = []; 
  218.  
  219.       // string 
  220.       var stringGeom = new THREE.Geometry(); 
  221.  
  222.       for (var i = 0; i < woolNodes; i++) { 
  223.         var v = new THREE.Vector3(0, -i * woolSegLength, 0); 
  224.         stringGeom.vertices.push(v); 
  225.  
  226.         var woolV = new WoolVert(); 
  227.         woolV.x = woolV.oldx = v.x; 
  228.         woolV.y = woolV.oldy = v.y; 
  229.         woolV.z = 0; 
  230.         woolV.fx = woolV.fy = 0; 
  231.         woolV.isRootNode = (i == 0); 
  232.         woolV.vertex = v; 
  233.         if (i > 0) woolV.attach(this.verts[(i - 1)]); 
  234.         this.verts.push(woolV); 
  235.  
  236.       } 
  237.       this.string = new THREE.Line(stringGeom, stringMat); 
  238.  
  239.       // body 
  240.       var bodyGeom = new THREE.SphereGeometry(this.ballRay, 5, 4); 
  241.       this.body = new THREE.Mesh(bodyGeom, redMat); 
  242.       this.body.position.y = -woolSegLength * woolNodes; 
  243.  
  244.       var wireGeom = new THREE.TorusGeometry(this.ballRay, .5, 3, 10, Math.PI * 2); 
  245.       this.wire1 = new THREE.Mesh(wireGeom, redMat); 
  246.       this.wire1.position.x = 1; 
  247.       this.wire1.rotation.x = -Math.PI / 4; 
  248.  
  249.       this.wire2 = this.wire1.clone(); 
  250.       this.wire2.position.y = 1; 
  251.       this.wire2.position.x = -1; 
  252.       this.wire1.rotation.x = -Math.PI / 4 + .5; 
  253.       this.wire1.rotation.y = -Math.PI / 6; 
  254.  
  255.       this.wire3 = this.wire1.clone(); 
  256.       this.wire3.rotation.x = -Math.PI / 2 + .3; 
  257.  
  258.       this.wire4 = this.wire1.clone(); 
  259.       this.wire4.position.x = -1; 
  260.       this.wire4.rotation.x = -Math.PI / 2 + .7; 
  261.  
  262.       this.wire5 = this.wire1.clone(); 
  263.       this.wire5.position.x = 2; 
  264.       this.wire5.rotation.x = -Math.PI / 2 + 1; 
  265.  
  266.       this.wire6 = this.wire1.clone(); 
  267.       this.wire6.position.x = 2; 
  268.       this.wire6.position.z = 1; 
  269.       this.wire6.rotation.x = 1; 
  270.  
  271.       this.wire7 = this.wire1.clone(); 
  272.       this.wire7.position.x = 1.5; 
  273.       this.wire7.rotation.x = 1.1; 
  274.  
  275.       this.wire8 = this.wire1.clone(); 
  276.       this.wire8.position.x = 1; 
  277.       this.wire8.rotation.x = 1.3; 
  278.  
  279.       this.wire9 = this.wire1.clone(); 
  280.       this.wire9.scale.set(1.2, 1.1, 1.1); 
  281.       this.wire9.rotation.z = Math.PI / 2; 
  282.       this.wire9.rotation.y = Math.PI / 2; 
  283.       this.wire9.position.y = 1; 
  284.  
  285.       this.body.add(this.wire1); 
  286.       this.body.add(this.wire2); 
  287.       this.body.add(this.wire3); 
  288.       this.body.add(this.wire4); 
  289.       this.body.add(this.wire5); 
  290.       this.body.add(this.wire6); 
  291.       this.body.add(this.wire7); 
  292.       this.body.add(this.wire8); 
  293.       this.body.add(this.wire9); 
  294.  
  295.       this.threeGroup.add(this.string); 
  296.       this.threeGroup.add(this.body); 
  297.  
  298.       this.threeGroup.traverse(function (object) { 
  299.         if (object instanceof THREE.Mesh) { 
  300.           object.castShadow = true
  301.           object.receiveShadow = true
  302.         } 
  303.       }); 
  304.  
  305.     } 
  306.  
  307.     /*  
  308.     The next part of the code is largely inspired by this codepen : 
  309.     https://codepen.io/dissimulate/pen/KrAwx?editors=001 
  310.     thanks to dissimulate for his great work 
  311.     */ 
  312.  
  313.     /* 
  314.     Copyright (c) 2013 dissimulate at Codepen 
  315.  
  316.     Permission is hereby granted, free of charge, to any person obtaining a copy 
  317.     of this software and associated documentation files (the "Software"), to deal 
  318.     in the Software without restriction, including without limitation the rights 
  319.     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
  320.     copies of the Software, and to permit persons to whom the Software is 
  321.     furnished to do so, subject to the following conditions: 
  322.  
  323.     The above copyright notice and this permission notice shall be included in 
  324.     all copies or substantial portions of the Software. 
  325.  
  326.     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
  327.     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
  328.     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
  329.     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
  330.     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
  331.     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
  332.     THE SOFTWARE. 
  333.     */ 
  334.  
  335.  
  336.  
  337.     WoolVert = function () { 
  338.       this.x = 0; 
  339.       this.y = 0; 
  340.       this.z = 0; 
  341.       this.oldx = 0; 
  342.       this.oldy = 0; 
  343.       this.fx = 0; 
  344.       this.fy = 0; 
  345.       this.isRootNode = false
  346.       this.constraints = []; 
  347.       this.vertex = null
  348.     } 
  349.  
  350.  
  351.     WoolVert.prototype.update = function () { 
  352.       var wind = 0; //.1+Math.random()*.5; 
  353.       this.add_force(wind, gravity); 
  354.  
  355.       nx = this.x + ((this.x - this.oldx) * .9) + this.fx; 
  356.       ny = this.y + ((this.y - this.oldy) * .9) + this.fy; 
  357.       this.oldx = this.x; 
  358.       this.oldy = this.y; 
  359.       this.x = nx; 
  360.       this.y = ny; 
  361.  
  362.       this.vertex.x = this.x; 
  363.       this.vertex.y = this.y; 
  364.       this.vertex.z = this.z; 
  365.  
  366.       this.fy = this.fx = 0 
  367.     } 
  368.  
  369.     WoolVert.prototype.attach = function (point) { 
  370.       this.constraints.push(new Constraint(this, point)); 
  371.     }; 
  372.  
  373.     WoolVert.prototype.add_force = function (x, y) { 
  374.       this.fx += x; 
  375.       this.fy += y; 
  376.     }; 
  377.  
  378.     Constraint = function (p1, p2) { 
  379.       this.p1 = p1; 
  380.       this.p2 = p2; 
  381.       this.length = woolSegLength; 
  382.     }; 
  383.  
  384.     Ball.prototype.update = function (posX, posY, posZ) { 
  385.  
  386.       var i = accuracy; 
  387.  
  388.       while (i--) { 
  389.  
  390.         var nodesCount = woolNodes; 
  391.  
  392.         while (nodesCount--) { 
  393.  
  394.           var v = this.verts[nodesCount]; 
  395.  
  396.           if (v.isRootNode) { 
  397.             v.x = posX; 
  398.             v.y = posY; 
  399.             v.z = posZ; 
  400.           } else { 
  401.  
  402.             var constraintsCount = v.constraints.length; 
  403.  
  404.             while (constraintsCount--) { 
  405.  
  406.               var c = v.constraints[constraintsCount]; 
  407.  
  408.               var diff_x = c.p1.x - c.p2.x, 
  409.                 diff_y = c.p1.y - c.p2.y, 
  410.                 dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y), 
  411.                 diff = (c.length - dist) / dist; 
  412.  
  413.               var px = diff_x * diff * .5; 
  414.               var py = diff_y * diff * .5; 
  415.  
  416.               c.p1.x += px; 
  417.               c.p1.y += py; 
  418.               c.p2.x -= px; 
  419.               c.p2.y -= py; 
  420.               c.p1.z = c.p2.z = posZ; 
  421.             } 
  422.  
  423.             if (nodesCount == woolNodes - 1) { 
  424.               this.body.position.x = this.verts[nodesCount].x; 
  425.               this.body.position.y = this.verts[nodesCount].y; 
  426.               this.body.position.z = this.verts[nodesCount].z; 
  427.  
  428.               this.body.rotation.z += (v.y <= this.ballRay) ? (v.oldx - v.x) / 10 : Math.min(Math.max(diff_x / 2, -.1), 
  429.                 .1); 
  430.             } 
  431.           } 
  432.  
  433.           if (v.y < this.ballRay) { 
  434.             v.y = this.ballRay; 
  435.           } 
  436.         } 
  437.       } 
  438.  
  439.       nodesCount = woolNodes; 
  440.       while (nodesCount--) this.verts[nodesCount].update(); 
  441.  
  442.       this.string.geometry.verticesNeedUpdate = true
  443.  
  444.  
  445.     } 
  446.  
  447.     Ball.prototype.receivePower = function (tp) { 
  448.       this.verts[woolNodes - 1].add_force(tp.x, tp.y); 
  449.     } 
  450.  
  451.     // Enf of the code inspired by dissmulate 
  452.     // Make everything work together : 
  453.  
  454.     var t = 0; 
  455.  
  456.     function loop() { 
  457.       render(); 
  458.  
  459.       t += .05; 
  460.       hero.updateTail(t); 
  461.  
  462.       var ballPos = getBallPos(); 
  463.       ball.update(ballPos.x, ballPos.y, ballPos.z); 
  464.       ball.receivePower(hero.transferPower); 
  465.       hero.interactWithBall(ball.body.position); 
  466.  
  467.       requestAnimationFrame(loop); 
  468.     } 
  469.  
  470.  
  471.     function getBallPos() { 
  472.       var vector = new THREE.Vector3(); 
  473.  
  474.       vector.set( 
  475.         (mousePos.x / window.innerWidth) * 2 - 1, -(mousePos.y / window.innerHeight) * 2 + 1, 
  476.         0.1); 
  477.  
  478.       vector.unproject(camera); 
  479.       var dir = vector.sub(camera.position).normalize(); 
  480.       var distance = (ballWallDepth - camera.position.z) / dir.z; 
  481.       var pos = camera.position.clone().add(dir.multiplyScalar(distance)); 
  482.       return pos; 
  483.     } 
  484.  
  485.     function render() { 
  486.       if (controls) controls.update(); 
  487.       renderer.render(scene, camera); 
  488.     } 
  489.  
  490.     window.addEventListener('load', init, false); 
  491.  
  492.     function init(event) { 
  493.       initScreenAnd3D(); 
  494.       createLights(); 
  495.       createFloor() 
  496.       createHero(); 
  497.       createBall(); 
  498.       loop(); 
  499.     } 
  500.   </script> 
  501.  
  502. </body> 
  503.  
  504. </html> 

 

[免责声明]本文来源于网络转载,仅供学习交流使用,不构成商业目的。版权归原作者所有,如涉及作品内容、版权和其它问题请在30日内与本网联系,我们将在第一时进行处理

上一篇:PPT演示稿效果的JavaScript幻灯片插件

下一篇:JS弹幕实现

热门标签

HTML语言

吐血推荐

中公优就业荣获知名IT品牌

中公优就业荣获中国教育在线“2017年度知名IT培训品牌”大奖


5分钟读懂HTML5
共有590人在学 | 免费
微信号:ujiuye
获取更多Web资源
中公教育IT培训品牌
官方微博
获取Web新动向
中公教育IT培训品牌