<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>HTML5 WebGL Three.js 3D彩色毛刺球动画特效</title>
<style>
body {
color: #000;
font-family: Monospace;
font-size: 13px;
margin: 0px;
overflow: hidden;
background-image: linear-gradient(to bottom right, #00FFF3 25%, #4b2ecf 100%);
}
.dg {
display: none;
/* remove me for dat-gui */
}
</style>
</head>
<body>
<script src="js/three.min.js"></script>
<script src="js/lodash.min.js"></script>
<script src="js/dat.gui.min.js"></script>
<script>
THREE.OrbitControls=function(e,t){function n(){return 2*Math.PI/60/60*k.autoRotateSpeed}function o(){return Math.pow(.95,k.zoomSpeed)}function a(e){z.theta-=e}function i(e){z.phi-=e}function r(e){k.object instanceof THREE.PerspectiveCamera?F/=e:k.object instanceof THREE.OrthographicCamera?(k.object.zoom=Math.max(k.minZoom,Math.min(k.maxZoom,k.object.zoom*e)),k.object.updateProjectionMatrix(),X=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),k.enableZoom=!1)}function s(e){k.object instanceof THREE.PerspectiveCamera?F*=e:k.object instanceof THREE.OrthographicCamera?(k.object.zoom=Math.max(k.minZoom,Math.min(k.maxZoom,k.object.zoom/e)),k.object.updateProjectionMatrix(),X=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),k.enableZoom=!1)}function c(e){K.set(e.clientX,e.clientY)}function u(e){Q.set(e.clientX,e.clientY)}function m(e){G.set(e.clientX,e.clientY)}function d(e){_.set(e.clientX,e.clientY),B.subVectors(_,K);var t=k.domElement===document?k.domElement.body:k.domElement;a(2*Math.PI*B.x/t.clientWidth*k.rotateSpeed),i(2*Math.PI*B.y/t.clientHeight*k.rotateSpeed),K.copy(_),k.update()}function l(e){J.set(e.clientX,e.clientY),$.subVectors(J,Q),$.y>0?r(o()):$.y<0&&s(o()),Q.copy(J),k.update()}function E(e){W.set(e.clientX,e.clientY),q.subVectors(W,G),ne(q.x,q.y),G.copy(W),k.update()}function h(e){}function p(e){e.deltaY<0?s(o()):e.deltaY>0&&r(o()),k.update()}function b(e){switch(e.keyCode){case k.keys.UP:ne(0,k.keyPanSpeed),k.update();break;case k.keys.BOTTOM:ne(0,-k.keyPanSpeed),k.update();break;case k.keys.LEFT:ne(k.keyPanSpeed,0),k.update();break;case k.keys.RIGHT:ne(-k.keyPanSpeed,0),k.update()}}function f(e){K.set(e.touches[0].pageX,e.touches[0].pageY)}function T(e){var t=e.touches[0].pageX-e.touches[1].pageX,n=e.touches[0].pageY-e.touches[1].pageY,o=Math.sqrt(t*t+n*n);Q.set(0,o)}function g(e){G.set(e.touches[0].pageX,e.touches[0].pageY)}function R(e){_.set(e.touches[0].pageX,e.touches[0].pageY),B.subVectors(_,K);var t=k.domElement===document?k.domElement.body:k.domElement;a(2*Math.PI*B.x/t.clientWidth*k.rotateSpeed),i(2*Math.PI*B.y/t.clientHeight*k.rotateSpeed),K.copy(_),k.update()}function v(e){var t=e.touches[0].pageX-e.touches[1].pageX,n=e.touches[0].pageY-e.touches[1].pageY,a=Math.sqrt(t*t+n*n);J.set(0,a),$.subVectors(J,Q),$.y>0?s(o()):$.y<0&&r(o()),Q.copy(J),k.update()}function O(e){W.set(e.touches[0].pageX,e.touches[0].pageY),q.subVectors(W,G),ne(q.x,q.y),G.copy(W),k.update()}function y(e){}function H(e){if(!1!==k.enabled){switch(e.preventDefault(),e.button){case k.mouseButtons.ORBIT:if(!1===k.enableRotate)return;c(e),V=S.ROTATE;break;case k.mouseButtons.ZOOM:if(!1===k.enableZoom)return;u(e),V=S.DOLLY;break;case k.mouseButtons.PAN:if(!1===k.enablePan)return;m(e),V=S.PAN}V!==S.NONE&&(document.addEventListener("mousemove",w,!1),document.addEventListener("mouseup",P,!1),k.dispatchEvent(D))}}function w(e){if(!1!==k.enabled)switch(e.preventDefault(),V){case S.ROTATE:if(!1===k.enableRotate)return;d(e);break;case S.DOLLY:if(!1===k.enableZoom)return;l(e);break;case S.PAN:if(!1===k.enablePan)return;E(e)}}function P(e){!1!==k.enabled&&(h(e),document.removeEventListener("mousemove",w,!1),document.removeEventListener("mouseup",P,!1),k.dispatchEvent(U),V=S.NONE)}function j(e){!1===k.enabled||!1===k.enableZoom||V!==S.NONE&&V!==S.ROTATE||(e.preventDefault(),e.stopPropagation(),p(e),k.dispatchEvent(D),k.dispatchEvent(U))}function C(e){!1!==k.enabled&&!1!==k.enableKeys&&!1!==k.enablePan&&b(e)}function M(e){if(!1!==k.enabled){switch(e.touches.length){case 1:if(!1===k.enableRotate)return;f(e),V=S.TOUCH_ROTATE;break;case 2:if(!1===k.enableZoom)return;T(e),V=S.TOUCH_DOLLY;break;case 3:if(!1===k.enablePan)return;g(e),V=S.TOUCH_PAN;break;default:V=S.NONE}V!==S.NONE&&k.dispatchEvent(D)}}function L(e){if(!1!==k.enabled)switch(e.preventDefault(),e.stopPropagation(),e.touches.length){case 1:if(!1===k.enableRotate)return;if(V!==S.TOUCH_ROTATE)return;R(e);break;case 2:if(!1===k.enableZoom)return;if(V!==S.TOUCH_DOLLY)return;v(e);break;case 3:if(!1===k.enablePan)return;if(V!==S.TOUCH_PAN)return;O(e);break;default:V=S.NONE}}function N(e){!1!==k.enabled&&(y(e),k.dispatchEvent(U),V=S.NONE)}function A(e){!1!==k.enabled&&e.preventDefault()}this.object=e,this.domElement=void 0!==t?t:document,this.enabled=!0,this.target=new THREE.Vector3,this.minDistance=0,this.maxDistance=1/0,this.minZoom=0,this.maxZoom=1/0,this.minPolarAngle=0,this.maxPolarAngle=Math.PI,this.minAzimuthAngle=-1/0,this.maxAzimuthAngle=1/0,this.enableDamping=!1,this.dampingFactor=.25,this.enableZoom=!0,this.zoomSpeed=1,this.enableRotate=!0,this.rotateSpeed=1,this.enablePan=!0,this.keyPanSpeed=7,this.autoRotate=!1,this.autoRotateSpeed=2,this.enableKeys=!0,this.keys={LEFT:37,UP:38,RIGHT:39,BOTTOM:40},this.mouseButtons={ORBIT:THREE.MOUSE.LEFT,ZOOM:THREE.MOUSE.MIDDLE,PAN:THREE.MOUSE.RIGHT},this.target0=this.target.clone(),this.position0=this.object.position.clone(),this.zoom0=this.object.zoom,this.getPolarAngle=function(){return Y.phi},this.getAzimuthalAngle=function(){return Y.theta},this.saveState=function(){k.target0.copy(k.target),k.position0.copy(k.object.position),k.zoom0=k.object.zoom},this.reset=function(){k.target.copy(k.target0),k.object.position.copy(k.position0),k.object.zoom=k.zoom0,k.object.updateProjectionMatrix(),k.dispatchEvent(x),k.update(),V=S.NONE},this.update=function(){var t=new THREE.Vector3,o=(new THREE.Quaternion).setFromUnitVectors(e.up,new THREE.Vector3(0,1,0)),i=o.clone().inverse(),r=new THREE.Vector3,s=new THREE.Quaternion;return function(){var e=k.object.position;return t.copy(e).sub(k.target),t.applyQuaternion(o),Y.setFromVector3(t),k.autoRotate&&V===S.NONE&&a(n()),Y.theta+=z.theta,Y.phi+=z.phi,Y.theta=Math.max(k.minAzimuthAngle,Math.min(k.maxAzimuthAngle,Y.theta)),Y.phi=Math.max(k.minPolarAngle,Math.min(k.maxPolarAngle,Y.phi)),Y.makeSafe(),Y.radius*=F,Y.radius=Math.max(k.minDistance,Math.min(k.maxDistance,Y.radius)),k.target.add(I),t.setFromSpherical(Y),t.applyQuaternion(i),e.copy(k.target).add(t),k.object.lookAt(k.target),!0===k.enableDamping?(z.theta*=1-k.dampingFactor,z.phi*=1-k.dampingFactor):z.set(0,0,0),F=1,I.set(0,0,0),!!(X||r.distanceToSquared(k.object.position)>Z||8*(1-s.dot(k.object.quaternion))>Z)&&(k.dispatchEvent(x),r.copy(k.object.position),s.copy(k.object.quaternion),X=!1,!0)}}(),this.dispose=function(){k.domElement.removeEventListener("contextmenu",A,!1),k.domElement.removeEventListener("mousedown",H,!1),k.domElement.removeEventListener("wheel",j,!1),k.domElement.removeEventListener("touchstart",M,!1),k.domElement.removeEventListener("touchend",N,!1),k.domElement.removeEventListener("touchmove",L,!1),document.removeEventListener("mousemove",w,!1),document.removeEventListener("mouseup",P,!1),window.removeEventListener("keydown",C,!1)};var k=this,x={type:"change"},D={type:"start"},U={type:"end"},S={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_DOLLY:4,TOUCH_PAN:5},V=S.NONE,Z=1e-6,Y=new THREE.Spherical,z=new THREE.Spherical,F=1,I=new THREE.Vector3,X=!1,K=new THREE.Vector2,_=new THREE.Vector2,B=new THREE.Vector2,G=new THREE.Vector2,W=new THREE.Vector2,q=new THREE.Vector2,Q=new THREE.Vector2,J=new THREE.Vector2,$=new THRE