<html> <head> <title>A little funny christmas.</title> <style> body { margin: 0; overflow: hidden; } canvas { position: relative; width: 100vw; height: 100vh; } #info { position: absolute; top: 0px; width: 100%; padding: 1px; box-sizing: border-box; text-align: center; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; z-index: 1; font-size: 0.5rem; } #dqboard { position: absolute; width: 100%; height: 10%; bottom: 0; margin-bottom: 1.5rem; } /* 黒板 */ .blackboard { width: 80%; height: 100%; margin: auto; padding: 0.5rem; color: #fff; border: 1px solid #000; border-radius: 3px; box-shadow: 0 0 0 4px #fff inset; background-color: rgba(0, 0, 0, 0.9); -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; display: flex; align-items: center; } #message { padding-left: 1rem; font-size: 1rem; } .blink-after::after { content: '_'; animation: blink 1.4s infinite; } /* 点滅 */ @keyframes blink { 50% { opacity: 0; } } @-webkit-keyframes blink { 50% { opacity: 0; } } </style> </head> <body> <div id="info">A little funny christmas. Click anywhere!<br /> <a href="https://sketchfab.com/3d-models/winter-feast-c19d718ad85143faad163e357892a4eb" target="_blank" rel="noopener">Winter Feast</a> by <a href="https://sketchfab.com/cmdrspacecat" target="_blank" rel="noopener">Nicole "CmdrSpaceCat" Rusk</a> CC Attribution-NonCommercial-ShareAlike, <a href="https://sketchfab.com/3d-models/3d-scan-repolho-cabbage-5cf0ec7c0b6845c7af52ea1bfcb1d16c" target="_blank" rel="noopener">3D Scan - Repolho ! ( Cabbage )</a> by <a href="https://sketchfab.com/magadan" target="_blank" rel="noopener">MGD Films</a> CC Attribution, <a href="https://sketchfab.com/3d-models/boletus-edulis-mushroom-model-e7bbf028e847412b986ef4c84bc5aa85" target="_blank" rel="noopener">Boletus edulis Mushroom Model</a> by <a href="https://sketchfab.com/borkia" target="_blank" rel="noopener">borkia</a> CC AttributionCreative Commons Attribution, <a href="https://sketchfab.com/3d-models/snowman-259ed43cf4354d0eb799a3036e8f848e" target="_blank" rel="noopener">snowman</a> by <a href="https://sketchfab.com/Ekabon" target="_blank" rel="noopener">Ekabon</a> CC Attribution and <a href="https://sketchfab.com/3d-models/chocolate-owl-22411971c4094881a70ff20a851e04bd" target="_blank" rel="noopener">Chocolate Owl</a> by <a href="https://sketchfab.com/artec3d" target="_blank" rel="noopener">Artec 3D</a> CC Attribution <br /> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/mrdoob/three.js@r109/examples/js/loaders/GLTFLoader.js"></script> <script src="https://cdn.jsdelivr.net/gh/mrdoob/three.js@r109/examples/js/controls/OrbitControls.js"></script> <script> var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.gammaOutput = true; renderer.gammaFactor = 2.2; document.body.appendChild(renderer.domElement); const light = new THREE.AmbientLight(0xFFFFFF, 1.0); scene.add(light); var controls = new THREE.OrbitControls(camera, renderer.domElement); var geometry = new THREE.BoxGeometry(1, 1, 1); var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); // camera.position.z = 5; let gltfs = [ { name: "winter_feast", }, { name: "mashrooms", position: { x: 1.2, y: 1, z: 2 }, scale: { x: 0.08, y: 0.08, z: 0.08 }, }, { name: "snowman", // Sphere001_0 position: { x: 2, y: 0.1, z: 5 }, scale: { x: 0.5, y: 0.5, z: -0.5 }, }, { name: "cabbage", // material_1 position: { x: -4.25, y: 0.76, z: -1.35 }, scale: { x: 0.03, y: 0.03, z: 0.03 }, }, { name: "chocolate_owl", // position: { x: 0.1, y: 0.52, z: -1.35 }, scale: { x: 0.005, y: 0.005, z: -0.005 }, } ] gltfs.forEach(function (propaty) { var loader = new THREE.GLTFLoader(); loader.load(`https://adventcalender2019sgichang.s3-ap-northeast-1.amazonaws.com/model/gltf/${propaty.name}/scene.gltf`, function (gltf) { if (propaty.position && propaty.scale) { gltf.scene.position.set(propaty.position.x, propaty.position.y, propaty.position.z); gltf.scene.scale.set(propaty.scale.x, propaty.scale.y, propaty.scale.z); } scene.add(gltf.scene); }, // called while loading is progressing function (xhr) { console.log((xhr.loaded / xhr.total * 100) + '% loaded'); }, // called when loading has errors function (error) { console.log('An error happened'); } ) }); camera.position.set(0.1, 4.2, 5.2); var touchEvent = 'ontouchend' in document ? 'touchstart' : 'mousedown'; document.addEventListener(touchEvent, myOnClick, false); controls.update(); var animate = function () { requestAnimationFrame(animate); controls.update(); renderer.render(scene, camera); }; animate(); // clickしたら呼ばれる function myOnClick(event) { var raycaster = new THREE.Raycaster(); var mouse = new THREE.Vector2(); // マウスポインタの位置座標の取得 var x = event.clientX ? event.clientX : (event.touches[0] || event.changedTouches[0] || {}).clientX; var y = event.clientY ? event.clientY : (event.touches[0] || event.changedTouches[0] || {}).clientY; mouse.x = (x / window.innerWidth) * 2 - 1; mouse.y = - (y / window.innerHeight) * 2 + 1; // 光線を発射 raycaster.setFromCamera(mouse, camera); // 光線と交わるオブジェクトを収集 var intersects = raycaster.intersectObjects(scene.children, true); var message = ""; // 交わるオブジェクトが1個以上の場合 if (intersects.length > 0) { var name = intersects[0].object.name ? intersects[0].object.name : (intersects[0].object.material || {}).name || null; switch (name) { case 'material_0': message = "こっちおいで!…ってチョコレート!?"; break; case 'material_1': case 'material_2': message = "誰よ…こんなところに置きっぱなしにしたの…"; break; case 'Sphere001_0': case 'Sphere002_0': case 'Sphere_0': case 'Cylinder001_0': case 'Cylinder_0': message = "だ、誰よ…雪だるま家に入れたの…"; break; case 'mashrooms': message = "サンタさんまだかなあ…"; break; case 'Door_0': message = "コンコン!おや?誰かきたようですよ?"; break; case 'Fireplace_1': message = "あちっ!と思ったら火ついてなかった…"; break; case 'Cylinder004_0': message = "メリークリスマス!!"; break; case 'candle-lrg_0': case 'candle-sml_0': case 'candle-med_0': message = "あちっ! キャンドルのこうげき! くれすこは 100の ダメージをうけた"; break; case 'Cube_0': message = "だから本当、熱いんだって!";