#holySpaceCowsWeekend using threejs and tweenmax. rotate the camera using the mouse
Forked from Karim Maaloul's Pen holy running cow.
A Pen by Captain Anonymous on CodePen.
#holySpaceCowsWeekend using threejs and tweenmax. rotate the camera using the mouse
Forked from Karim Maaloul's Pen holy running cow.
A Pen by Captain Anonymous on CodePen.
| <div id="world"></div> | |
| <div id="instructions">Press and drag <br><span class="lightInstructions">to rotate the scene</span></div> |
| //THREEJS RELATED VARIABLES | |
| var scene, | |
| camera, | |
| controls, | |
| fieldOfView, | |
| aspectRatio, | |
| nearPlane, | |
| farPlane, | |
| shadowLight, | |
| backLight, | |
| light, | |
| renderer, | |
| container; | |
| //SCENE | |
| //SCREEN VARIABLES | |
| var HEIGHT, | |
| WIDTH, | |
| windowHalfX, | |
| windowHalfY, | |
| mousePos = {x:0,y:0}; | |
| //INIT THREE JS, SCREEN AND MOUSE EVENTS | |
| function init(){ | |
| scene = new THREE.Scene(); | |
| scene.fog = new THREE.Fog( 0x363d3d, -1, 3000 ); | |
| HEIGHT = window.innerHeight; | |
| WIDTH = window.innerWidth; | |
| aspectRatio = WIDTH / HEIGHT; | |
| fieldOfView = 60; | |
| nearPlane = 1; | |
| farPlane = 2000; | |
| camera = new THREE.PerspectiveCamera( | |
| fieldOfView, | |
| aspectRatio, | |
| nearPlane, | |
| farPlane); | |
| camera.position.z = 800; | |
| camera.position.y = 300; | |
| camera.lookAt(new THREE.Vector3(0,0,0)); | |
| renderer = new THREE.WebGLRenderer({alpha: true, antialias: true }); | |
| renderer.setSize(WIDTH, HEIGHT); | |
| renderer.shadowMapEnabled = true; | |
| container = document.getElementById('world'); | |
| container.appendChild(renderer.domElement); | |
| windowHalfX = WIDTH / 2; | |
| windowHalfY = HEIGHT / 2; | |
| window.addEventListener('resize', onWindowResize, false); | |
| document.addEventListener('mousemove', handleMouseMove, false); | |
| document.addEventListener('mousedown', handleMouseDown, false); | |
| document.addEventListener('mouseup', handleMouseUp, false); | |
| document.addEventListener('touchstart', handleTouchStart, false); | |
| document.addEventListener('touchend', handleTouchEnd, false); | |
| document.addEventListener('touchmove',handleTouchMove, false); | |
| //* | |
| controls = new THREE.OrbitControls( camera, renderer.domElement); | |
| //*/ | |
| } | |
| function onWindowResize() { | |
| HEIGHT = window.innerHeight; | |
| WIDTH = window.innerWidth; | |
| windowHalfX = WIDTH / 2; | |
| windowHalfY = HEIGHT / 2; | |
| renderer.setSize(WIDTH, HEIGHT); | |
| camera.aspect = WIDTH / HEIGHT; | |
| camera.updateProjectionMatrix(); | |
| } | |
| function handleMouseMove(event) { | |
| mousePos = {x:event.clientX, y:event.clientY}; | |
| } | |
| function handleMouseDown(event) { | |
| // | |
| } | |
| function handleMouseUp(event) { | |
| // | |
| } | |
| function handleTouchStart(event) { | |
| if (event.touches.length > 1) { | |
| event.preventDefault(); | |
| mousePos = {x:event.touches[0].pageX, y:event.touches[0].pageY}; | |
| } | |
| } | |
| function handleTouchEnd(event) { | |
| mousePos = {x:windowHalfX, y:windowHalfY}; | |
| } | |
| function handleTouchMove(event) { | |
| if (event.touches.length == 1) { | |
| event.preventDefault(); | |
| mousePos = {x:event.touches[0].pageX, y:event.touches[0].pageY}; | |
| } | |
| } | |
| function createLights() { | |
| light = new THREE.HemisphereLight(0xffffff, 0xffffff, .5) | |
| shadowLight = new THREE.DirectionalLight(0xffffff, .8); | |
| shadowLight.position.set(200, 200, 200); | |
| shadowLight.castShadow = true; | |
| shadowLight.shadowDarkness = .2; | |
| backLight = new THREE.DirectionalLight(0xffffff, .4); | |
| backLight.position.set(-100, 200, 50); | |
| backLight.shadowDarkness = .2; | |
| backLight.castShadow = true; | |
| scene.add(backLight); | |
| scene.add(light); | |
| scene.add(shadowLight); | |
| } | |
| function createCows(){ | |
| cow = new Cow(); | |
| scene.add(cow.threegroup); | |
| var angx = 0; | |
| var da = Math.PI*2 / 10; | |
| for (var i=0; i<10; i++){ | |
| var planet = new Planet(); | |
| var d = 200 + Math.random()*400; | |
| angx += da; | |
| planet.threegroup.position.x = Math.cos(angx)*d; | |
| planet.threegroup.position.y = -500 + Math.random()*1000; | |
| planet.threegroup.position.z = Math.sin(angx)*d; | |
| scene.add(planet.threegroup); | |
| } | |
| } | |
| Cow = function(){ | |
| this.threegroup = new THREE.Group(); | |
| this.whiteMat = new THREE.MeshLambertMaterial ({ | |
| color: 0xffffff, | |
| shading:THREE.FlatShading | |
| }); | |
| this.blackMat = new THREE.MeshLambertMaterial ({ | |
| color: 0x000000, | |
| shading:THREE.FlatShading | |
| }); | |
| this.greyMat = new THREE.MeshLambertMaterial ({ | |
| color: 0x999999, | |
| shading:THREE.FlatShading | |
| }); | |
| this.pinkMat = new THREE.MeshLambertMaterial ({ | |
| color: 0xfaa288, | |
| shading:THREE.FlatShading | |
| }); | |
| this.greenMat = new THREE.MeshLambertMaterial ({ | |
| color: 0x6ec098, | |
| shading:THREE.FlatShading | |
| }); | |
| this.orangeMat = new THREE.MeshLambertMaterial ({ | |
| color: 0xef704f, | |
| shading:THREE.FlatShading | |
| }); | |
| this.yellowMat = new THREE.MeshLambertMaterial ({ | |
| color: 0xd7a25e, | |
| shading:THREE.FlatShading | |
| }); | |
| this.wireMat = new THREE.LineBasicMaterial ({ | |
| color:0xffffff, | |
| linewidth:1, | |
| fog : true | |
| }); | |
| var bodyGeom = new THREE.BoxGeometry(100, 100, 100); | |
| var spotGeom = new THREE.BoxGeometry(20,20, 20); | |
| var tailGeom = new THREE.BoxGeometry(10,10, 30); | |
| tailGeom.applyMatrix( new THREE.Matrix4().makeTranslation( 0, 0, -20 ) ); | |
| var faceGeom = new THREE.BoxGeometry(100,100, 100); | |
| var ringGeom = new THREE.TorusGeometry(200, 3, 4, 4) | |
| var ringGeom2 = new THREE.TorusGeometry(50, 3, 4, 4) | |
| var wireGeom = new THREE.Geometry(); | |
| wireGeom.vertices.push( | |
| new THREE.Vector3( 0, 0, 0 ), | |
| new THREE.Vector3( 0, 2000, 0 ) | |
| ); | |
| this.body = new THREE.Mesh(bodyGeom, this.whiteMat); | |
| // SPOTS | |
| this.spot1 = new THREE.Mesh(spotGeom, this.blackMat); | |
| this.spot1.position.y = 41; | |
| this.spot1.position.x = 41; | |
| this.spot1.position.z = 25; | |
| this.spot2 = new THREE.Mesh(spotGeom, this.blackMat); | |
| this.spot2.scale.set(2,2,2); | |
| this.spot2.position.y = 31; | |
| this.spot2.position.x = -31; | |
| this.spot2.position.z = -31; | |
| this.spot3 = new THREE.Mesh(spotGeom, this.blackMat); | |
| this.spot3.scale.set(2.5,2.5,2.5); | |
| this.spot3.position.y = -26; | |
| this.spot3.position.x = 26; | |
| this.spot3.position.z = 26; | |
| this.spot4 = new THREE.Mesh(spotGeom, this.blackMat); | |
| this.spot4.position.y = -41; | |
| this.spot4.position.x = 41; | |
| this.spot4.position.z = -41; | |
| // TAIL | |
| this.tail = new THREE.Mesh( tailGeom, this.whiteMat); | |
| this.tail.position.y = 45; | |
| this.tail.position.z = -60; | |
| // FACE | |
| this.face = new THREE.Mesh(faceGeom, this.pinkMat); | |
| this.face.position.z = 100; | |
| // NOSTRILS | |
| this.nostril1 = new THREE.Mesh(spotGeom, this.blackMat); | |
| this.nostril1.scale.set(.5,.5,1); | |
| this.nostril2 = this.nostril1.clone(); | |
| this.nostril1.position.z = this.nostril2.position.z =141; | |
| this.nostril1.position.y = this.nostril2.position.y =35; | |
| this.nostril1.position.x = -35; | |
| this.nostril2.position.x = 35; | |
| // EYES | |
| this.leftEye = new THREE.Mesh(spotGeom, this.whiteMat); | |
| this.leftEye.scale.set(1,2.5,2.5); | |
| this.leftEye.position.x = 41; | |
| this.leftEye.position.y = 26; | |
| this.leftEye.position.z = 100; | |
| this.rightEye = this.leftEye.clone(); | |
| this.rightEye.position.x = -41; | |
| // IRIS | |
| this.leftIris = new THREE.Mesh(spotGeom, this.blackMat); | |
| this.leftIris.scale.set(.5,.5,.5); | |
| this.leftIris.position.x = 50; | |
| this.leftIris.position.y = 26; | |
| this.leftIris.position.z = 110; | |
| this.rightIris = this.leftIris.clone(); | |
| this.leftIris.position.x = -50; | |
| // EARS | |
| this.leftEar = new THREE.Mesh(spotGeom, this.pinkMat); | |
| this.leftEar.position.x = 60; | |
| this.leftEar.position.y = 40; | |
| this.leftEar.position.z = 60; | |
| this.rightEar = this.leftEar.clone(); | |
| this.leftEar.position.x = -60; | |
| // HORNS | |
| this.leftHorn = new THREE.Mesh(spotGeom, this.greyMat); | |
| this.leftHorn.position.x = 25; | |
| this.leftHorn.position.y = 60; | |
| this.leftHorn.position.z = 60; | |
| this.rightHorn = this.leftHorn.clone(); | |
| this.rightHorn.position.x = -25; | |
| // MOUTH | |
| this.mouth = new THREE.Mesh(spotGeom, this.blackMat); | |
| this.mouth.scale.set(1,1,1); | |
| this.mouth.position.y = -40; | |
| this.mouth.position.z = 141; | |
| // LIPS | |
| this.lips = new THREE.Mesh(spotGeom, this.pinkMat); | |
| this.lips.scale.set(2,.5,1); | |
| this.lips.position.y = -55; | |
| this.lips.position.z = 140; | |
| // RINGS | |
| this.ring1 = new THREE.Mesh(ringGeom, this.yellowMat); | |
| this.ring1.position.y = 0; | |
| this.ring1.position.z = 0; | |
| this.ring1.rotation.x = -Math.PI/8; | |
| this.ring2 = new THREE.Mesh(ringGeom, this.orangeMat); | |
| this.ring2.scale.set(1.3,1.3,1.3); | |
| this.ring2.position.y = 0; | |
| this.ring2.position.z = 25; | |
| this.ring2.rotation.x = -Math.PI/8; | |
| this.ring3 = new THREE.Mesh(ringGeom, this.greenMat); | |
| this.ring3.position.y = 0; | |
| this.ring3.position.z = 50; | |
| this.ring3.rotation.x = -Math.PI/8; | |
| this.ring4 = new THREE.Mesh(ringGeom2, this.yellowMat); | |
| this.ring4.position.y = 80; | |
| this.ring4.position.z = 100; | |
| this.ring4.rotation.x = -Math.PI/2; | |
| // LEGS | |
| this.leg1 = new THREE.Mesh(spotGeom, this.pinkMat); | |
| this.leg1.position.x = -40; | |
| this.leg1.position.y = -60; | |
| this.leg1.position.z = -40; | |
| this.leg2 = this.leg1.clone(); | |
| this.leg2.position.x = 40; | |
| this.leg3 = this.leg1.clone(); | |
| this.leg3.position.z = 40; | |
| this.leg4 = this.leg3.clone(); | |
| this.leg4.position.x = 40; | |
| // UDDER | |
| this.udder = new THREE.Mesh(spotGeom, this.pinkMat); | |
| this.udder.scale.set(2,1,2); | |
| this.udder.position.y = -55; | |
| this.udder.position.z = -10; | |
| // WIRE | |
| this.wire = new THREE.Line(wireGeom, this.wireMat); | |
| this.wire.position.z = 50; | |
| this.threegroup.add(this.body); | |
| this.threegroup.add(this.spot1); | |
| this.threegroup.add(this.spot2); | |
| this.threegroup.add(this.spot3); | |
| this.threegroup.add(this.spot4); | |
| this.threegroup.add(this.tail); | |
| this.threegroup.add(this.face); | |
| this.threegroup.add(this.nostril1); | |
| this.threegroup.add(this.nostril2); | |
| this.threegroup.add(this.leftEye); | |
| this.threegroup.add(this.rightEye); | |
| this.threegroup.add(this.leftIris); | |
| this.threegroup.add(this.rightIris); | |
| this.threegroup.add(this.leftEar); | |
| this.threegroup.add(this.rightEar); | |
| this.threegroup.add(this.leftHorn); | |
| this.threegroup.add(this.rightHorn); | |
| this.threegroup.add(this.mouth); | |
| this.threegroup.add(this.lips); | |
| this.threegroup.add(this.ring1); | |
| this.threegroup.add(this.ring2); | |
| this.threegroup.add(this.ring3); | |
| this.threegroup.add(this.ring4); | |
| this.threegroup.add(this.leg1); | |
| this.threegroup.add(this.leg2); | |
| this.threegroup.add(this.leg3); | |
| this.threegroup.add(this.leg4); | |
| this.threegroup.add(this.udder); | |
| this.threegroup.add(this.wire); | |
| this.threegroup.traverse( function ( object ) { | |
| if ( object instanceof THREE.Mesh ) { | |
| object.castShadow = true; | |
| object.receiveShadow = true; | |
| } | |
| } ); | |
| } | |
| Cow.prototype.blink = function(){ | |
| TweenMax.to(this.leftEye.scale, .3, {y:0, ease:Strong.easeInOut, yoyo:true, repeat:3}); | |
| TweenMax.to(this.rightEye.scale, .3, {y:0, ease:Strong.easeInOut, yoyo:true, repeat:3}); | |
| TweenMax.to(this.leftIris.scale, .3, {y:0, ease:Strong.easeInOut, yoyo:true, repeat:3}); | |
| TweenMax.to(this.rightIris.scale, .3, {y:0, ease:Strong.easeInOut, yoyo:true, repeat:3}); | |
| } | |
| Planet = function (){ | |
| var colors = [0x000000, 0x6abc94, 0xee7351, 0xcd9b56,0xf8f8f8 ]; | |
| var col = colors[Math.floor(Math.random()*colors.length)]; | |
| this.threegroup = new THREE.Group(); | |
| this.blackMat = new THREE.MeshLambertMaterial ({ | |
| color: col, | |
| shading:THREE.FlatShading | |
| }); | |
| this.wireMat = new THREE.LineBasicMaterial ({ | |
| color:0x000000, | |
| linewidth:.3, | |
| fog : true | |
| }); | |
| var wireGeom = new THREE.Geometry(); | |
| wireGeom.vertices.push( | |
| new THREE.Vector3( 0, 0, 0 ), | |
| new THREE.Vector3( 0, 2000, 0 ) | |
| ); | |
| var s = 20 + Math.random()*20 | |
| var geom = new THREE.BoxGeometry(s,s,s); | |
| // WIRE | |
| this.wire = new THREE.Line(wireGeom, this.wireMat); | |
| this.core = new THREE.Mesh(geom, this.blackMat); | |
| this.threegroup.add(this.core); | |
| this.threegroup.add(this.wire); | |
| } | |
| var angleLegs = 0; | |
| function loop(){ | |
| angleLegs += .2; | |
| var sin = Math.sin(angleLegs); | |
| var cos = Math.cos(angleLegs); | |
| render(); | |
| cow.threegroup.rotation.y +=0.01; | |
| cow.ring1.rotation.z += .005; | |
| cow.ring2.rotation.z -= .005; | |
| cow.ring3.rotation.z += .01; | |
| cow.ring4.rotation.z += .1; | |
| cow.leg1.position.z = -40 + cos*10; | |
| cow.leg2.position.z = -40 + sin*10; | |
| cow.leg3.position.z = 40 + sin*10; | |
| cow.leg4.position.z = 40 + cos*10; | |
| cow.threegroup.position.y = cos*10; | |
| cow.leftEar.position.y = cow.rightEar.position.y = 35 + Math.sin(angleLegs)*5; | |
| cow.mouth.position.y = -40 + sin*5; | |
| cow.mouth.scale.set(1, .5 + Math.abs(cos)*.5, 1); | |
| cow.lips.position.y = -50 + sin*5; | |
| cow.tail.rotation.x = sin*Math.PI/3; | |
| cow.udder.position.y = -55 + sin*10; | |
| cow.ring4.position.y = 80 + sin*10; | |
| requestAnimationFrame(loop); | |
| } | |
| function render(){ | |
| if (controls) controls.update(); | |
| renderer.render(scene, camera); | |
| } | |
| init(); | |
| createLights(); | |
| createCows(); | |
| loop(); | |
| cow.blink(); | |
| blinkInterval = setInterval(function(){ | |
| cow.blink(); | |
| }, 4000); |
| <script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js"></script> | |
| <script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/OrbitControls.js"></script> | |
| <script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js"></script> |
| @import url(http://fonts.googleapis.com/css?family=Open+Sans:800); | |
| #world { | |
| background: #222626; | |
| position:absolute; | |
| width:100%; | |
| height:100%; | |
| overflow:hidden; | |
| } | |
| #instructions{ | |
| position:absolute; | |
| width:100%; | |
| top:50%; | |
| margin: auto; | |
| margin-top:100px; | |
| font-family:'Open Sans', sans-serif; | |
| color:#ffffff; | |
| font-size:.9em; | |
| text-transform: uppercase; | |
| text-align : center; | |
| } | |
| .lightInstructions { | |
| color:#6fbf98; | |
| font-size:.8em; | |
| } |