Created
August 23, 2013 05:34
-
-
Save edom18/6315849 to your computer and use it in GitHub Desktop.
Three.jsのCSS3DRendererでサイコロ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #CSS3DRenderer使ってみました | |
| あまり複雑なモデルなどは表現できませんが、ちょっとした形のものとか | |
| 立体感のある演出、くらいなら問題なく使えそうです。 | |
| Cannon.jsと組み合わせてサイコロを振ったような演出を作ってみました。 | |
| CSSレンダリングなのでもちろんiPhoneでも動きます。 | |
| 画面をクリックすることで、サイコロを追加することができます。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @import "compass/reset"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div id="d0"></div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function (win, doc) { | |
| 'use strict'; | |
| var world, ground, timeStep = 1 / 60, | |
| diceRigids = [], dicies = [], | |
| camera, scene, renderer, floorObj, | |
| startDiceNum = 3, | |
| cubeSize = 2; | |
| function createCube(w, h, d) { | |
| var geometry = new THREE.CubeGeometry(w, h, d, 10, 10); | |
| var material = new THREE.MeshLambertMaterial({ | |
| color: 0x666666 | |
| }); | |
| var mesh = new THREE.Mesh(geometry, material); | |
| return mesh; | |
| } | |
| function createPlane(w, h) { | |
| var geometry = new THREE.PlaneGeometry(w, h); | |
| var material = new THREE.MeshPhongMaterial({ | |
| color: 0xffffff, | |
| specular: 0xeeeeee, | |
| shininess: 50 | |
| }); | |
| var mesh = new THREE.Mesh(geometry, material); | |
| return mesh; | |
| } | |
| function createDice(x, y, z) { | |
| var boxInfo = [ | |
| { | |
| url: 'http://jsrun.it/assets/g/N/z/s/gNzsx.png', | |
| position: [ -cubeSize, 0, 0 ], | |
| rotation: [ 0, Math.PI / 2, 0 ] | |
| }, | |
| { | |
| url: 'http://jsrun.it/assets/b/X/8/T/bX8TN.png', | |
| position: [ cubeSize, 0, 0 ], | |
| rotation: [ 0, -Math.PI / 2, 0 ] | |
| }, | |
| { | |
| url: 'http://jsrun.it/assets/u/G/6/B/uG6BH.png', | |
| position: [ 0, cubeSize, 0 ], | |
| rotation: [ Math.PI / 2, 0, Math.PI ] | |
| }, | |
| { | |
| url: 'http://jsrun.it/assets/e/s/z/w/eszwi.png', | |
| position: [ 0, -cubeSize, 0 ], | |
| rotation: [ - Math.PI / 2, 0, Math.PI ] | |
| }, | |
| { | |
| url: 'http://jsrun.it/assets/9/t/3/9/9t39J.png', | |
| position: [ 0, 0, cubeSize ], | |
| rotation: [ 0, Math.PI, 0 ] | |
| }, | |
| { | |
| url: 'http://jsrun.it/assets/h/e/o/9/heo9V.png', | |
| position: [ 0, 0, -cubeSize ], | |
| rotation: [ 0, 0, 0 ] | |
| } | |
| ]; | |
| { | |
| var el, dice, | |
| info, img, face; | |
| el = doc.createElement('div'); | |
| el.style.width = cubeSize * 2 + 'px'; | |
| el.style.height = cubeSize * 2 + 'px'; | |
| dice = new THREE.CSS3DObject(el); | |
| for (var j = 0; j < boxInfo.length; j++) { | |
| info = boxInfo[j]; | |
| img = document.createElement('img'); | |
| img.width = cubeSize * 2; | |
| img.src = info.url; | |
| face = new THREE.CSS3DObject(img); | |
| face.position.fromArray(info.position); | |
| face.rotation.fromArray(info.rotation); | |
| dice.add(face); | |
| } | |
| scene.add(dice); | |
| dicies.push(dice); | |
| } | |
| //Create physics. | |
| { | |
| var mass = 1; | |
| var box = new CANNON.Box(new CANNON.Vec3(cubeSize, cubeSize, cubeSize)); | |
| var body = new CANNON.RigidBody(mass, box); | |
| body.position.set(x, y, z); | |
| body.velocity.set(0, 0, Math.random() * -50 - 30); | |
| body.angularVelocity.set(10, 10, 10); | |
| body.angularDamping = 0.001; | |
| world.add(body); | |
| diceRigids.push(body); | |
| } | |
| } | |
| // | |
| function initCannon() { | |
| //Cannonの世界を生成 | |
| world = new CANNON.World(); | |
| //重力を設定 | |
| world.gravity.set(0, -90.82, 0); | |
| world.broadphase = new CANNON.NaiveBroadphase(); | |
| world.solver.iterations = 10; | |
| world.solver.tolerance = 0.001; | |
| //地面用にPlaneを生成 | |
| var plane = new CANNON.Plane(); | |
| //Planeの剛体を質量0で生成する | |
| ground= new CANNON.RigidBody(0, plane); | |
| //X軸に90度(つまり地面)に回転 | |
| ground.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2); | |
| world.add(ground); | |
| } | |
| function initThree() { | |
| var w = win.innerWidth; | |
| var h = win.innerHeight; | |
| camera = new THREE.PerspectiveCamera(60, w / h, 1, 10000); | |
| camera.position.set(Math.cos(Math.PI / 5) * 30, 20, Math.sin(Math.PI / 5) * 80); | |
| camera.lookAt(new THREE.Vector3(0, 0, 0)); | |
| scene = new THREE.Scene(); | |
| renderer = new THREE.CSS3DRenderer(); | |
| renderer.setSize(w, h); | |
| var floorEle = doc.createElement('div'); | |
| floorEle.style.width = '200px'; | |
| floorEle.style.height = '200px'; | |
| floorEle.style.background = '-webkit-linear-gradient(0deg, #ccc 0%, #444 100%)'; | |
| floorObj = new THREE.CSS3DObject(floorEle); | |
| floorObj.position.fromArray([0, 0, 0]); | |
| floorObj.rotation.fromArray([Math.PI / 2, 0, 0]); | |
| scene.add(floorObj); | |
| scene.add(camera); | |
| var container = doc.getElementById('d0'); | |
| container.appendChild(renderer.domElement); | |
| renderer.render(scene, camera); | |
| } | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| updatePhysics(); | |
| render(); | |
| } | |
| function updatePhysics() { | |
| //物理エンジンの時間を進める | |
| world.step(timeStep); | |
| //物理エンジンで計算されたbody(RigidBody)の位置をThree.jsのMeshにコピー | |
| for (var i = 0; i < diceRigids.length; i++) { | |
| diceRigids[i].position.copy(dicies[i].position); | |
| diceRigids[i].quaternion.copy(dicies[i].quaternion); | |
| } | |
| ground.position.copy(floorObj.position); | |
| ground.quaternion.copy(floorObj.quaternion); | |
| } | |
| function render() { | |
| renderer.render(scene, camera); | |
| } | |
| initCannon(); | |
| initThree(); | |
| animate(); | |
| // | |
| (function throwDice() { | |
| if (!startDiceNum) { | |
| return; | |
| } | |
| setTimeout(throwDice, 1000); | |
| createDice(0, 30, 30); | |
| startDiceNum--; | |
| }()); | |
| // | |
| var camBasePos = camera.position; | |
| var camBaseLookAt = new THREE.Vector3(3, 3, -10); | |
| var flg = false; | |
| var container = doc.getElementById('d0'); | |
| var isTouch = 'ontouchstart' in window, | |
| M_DOWN = isTouch ? 'touchstart' : 'mousedown', | |
| M_MOVE = isTouch ? 'touchmove' : 'mousemove', | |
| M_UP = isTouch ? 'touchend' : 'mouseup'; | |
| doc.addEventListener(M_DOWN, function (e) { | |
| flg = true; | |
| }, false); | |
| doc.addEventListener(M_UP, function (e) { | |
| flg = false; | |
| }, false); | |
| doc.addEventListener(M_MOVE, function(e){ | |
| if(flg){ | |
| var cp = container.getBoundingClientRect(); | |
| camera.position = camBasePos.clone(); | |
| camera.position.subVectors(camera.position, camBaseLookAt); | |
| camera.position.applyAxisAngle(new THREE.Vector3(0, 1, 0), (e.clientX - cp.left - 160) / 72); | |
| camera.lookAt(scene.position); | |
| camera.position.addVectors(camera.position, camBaseLookAt.clone()); | |
| } | |
| }, false); | |
| doc.addEventListener('click', function (e) { | |
| createDice(0, 30, 30); | |
| }, false); | |
| }(window, document)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment