2016-11-11 18:52:19 +00:00
|
|
|
/**
|
|
|
|
* Copyright 2016 Google Inc.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
const THREE = require('three')
|
|
|
|
|
|
|
|
var geometry = new THREE.PlaneGeometry( 1, 1, 1 )
|
|
|
|
var material = new THREE.MeshBasicMaterial( {color: 0x1FB7EC, side: THREE.DoubleSide} )
|
|
|
|
var aiMaterial = new THREE.MeshBasicMaterial( {color: 0xFFB729, side: THREE.DoubleSide} )
|
|
|
|
|
|
|
|
window.zero = new THREE.Vector3(0, 0, 0)
|
|
|
|
|
|
|
|
function scale(value, inMin, inMax, min, max){
|
|
|
|
return ((value - inMin) / (inMax - inMin)) * (max - min) + min
|
|
|
|
}
|
|
|
|
|
|
|
|
class Roll {
|
|
|
|
constructor(container){
|
|
|
|
this._element = document.createElement('div')
|
|
|
|
this._element.id = 'roll'
|
|
|
|
container.appendChild(this._element)
|
|
|
|
|
|
|
|
this._camera = new THREE.OrthographicCamera(0, 1, 1, 0, 1, 1000 )
|
|
|
|
this._camera.position.z = 1
|
|
|
|
this._camera.lookAt(new THREE.Vector3(0, 0, 0))
|
|
|
|
|
|
|
|
this._scene = new THREE.Scene()
|
|
|
|
|
|
|
|
this._renderer = new THREE.WebGLRenderer({alpha: true})
|
|
|
|
this._renderer.setClearColor(0x000000, 0)
|
|
|
|
this._renderer.setPixelRatio( window.devicePixelRatio )
|
|
|
|
this._renderer.sortObjects = false
|
|
|
|
this._element.appendChild(this._renderer.domElement)
|
|
|
|
|
|
|
|
this._currentNotes = {}
|
|
|
|
|
|
|
|
window.camera = this._camera
|
|
|
|
|
|
|
|
//set the size initially
|
|
|
|
this._resize()
|
|
|
|
|
|
|
|
//start the loop
|
|
|
|
this._boundLoop = this._loop.bind(this)
|
|
|
|
this._boundLoop()
|
|
|
|
window.addEventListener('resize', this._resize.bind(this))
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
keyDown(midi, box, ai=false){
|
|
|
|
const selector = ai ? `ai${midi}` : midi
|
2016-11-15 00:35:36 +00:00
|
|
|
if (!this._currentNotes.hasOwnProperty(selector)){
|
|
|
|
this._currentNotes[selector] = []
|
|
|
|
}
|
|
|
|
if (midi && box){
|
2016-11-11 18:52:19 +00:00
|
|
|
//translate the box coords to this space
|
|
|
|
const initialScaling = 10000
|
|
|
|
const plane = new THREE.Mesh( geometry, ai ? aiMaterial : material )
|
|
|
|
const margin = 4
|
|
|
|
const width = box.width - margin * 2
|
|
|
|
plane.scale.set(width, initialScaling, 1)
|
|
|
|
plane.position.z = 0
|
|
|
|
plane.position.x = box.left + margin + width / 2
|
|
|
|
plane.position.y = this._element.clientHeight + this._camera.position.y + initialScaling / 2
|
|
|
|
this._scene.add(plane)
|
|
|
|
|
2016-11-15 00:35:36 +00:00
|
|
|
this._currentNotes[selector].push({
|
2016-11-11 18:52:19 +00:00
|
|
|
plane : plane,
|
|
|
|
position: this._camera.position.y
|
2016-11-15 00:35:36 +00:00
|
|
|
})
|
2016-11-11 18:52:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
keyUp(midi, ai=false){
|
|
|
|
const selector = ai ? `ai${midi}` : midi
|
2016-11-15 00:35:36 +00:00
|
|
|
if (this._currentNotes[selector] && this._currentNotes[selector].length){
|
|
|
|
const note = this._currentNotes[selector].shift()
|
|
|
|
const plane = note.plane
|
|
|
|
const position = note.position
|
2016-11-11 18:52:19 +00:00
|
|
|
// get the distance covered
|
|
|
|
plane.scale.y = Math.max(this._camera.position.y - position, 5)
|
|
|
|
plane.position.y = this._element.clientHeight + position + plane.scale.y / 2
|
2016-11-15 00:35:36 +00:00
|
|
|
} else {
|
|
|
|
// console.log(midi)
|
|
|
|
// setTimeout(() => this.keyUp(midi, ai), 100)
|
2016-11-11 18:52:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_resize(){
|
|
|
|
var frustumSize = 1000
|
|
|
|
var aspect = this._element.clientWidth / this._element.clientHeight
|
|
|
|
//make it match the screen pixesl
|
|
|
|
this._camera.left = 0
|
|
|
|
this._camera.bottom = this._element.clientHeight
|
|
|
|
this._camera.right = this._element.clientWidth
|
|
|
|
this._camera.top = 0
|
|
|
|
|
|
|
|
//update things
|
|
|
|
this._camera.updateProjectionMatrix()
|
|
|
|
this._renderer.setSize( this._element.clientWidth, this._element.clientHeight )
|
|
|
|
}
|
|
|
|
|
|
|
|
_loop(){
|
|
|
|
requestAnimationFrame(this._boundLoop)
|
|
|
|
this._renderer.render( this._scene, this._camera )
|
|
|
|
this._camera.position.y += 2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export {Roll}
|