diff options
| author | Jules Laplace <jules@okfoc.us> | 2016-10-28 18:06:46 -0400 |
|---|---|---|
| committer | Jules Laplace <jules@okfoc.us> | 2016-10-28 18:06:46 -0400 |
| commit | 9e7bacd46c1e5d0e1c24433690d421ab3f3a11f2 (patch) | |
| tree | 4d0cefa2780dfa4382f1ed2ea481b6aafbdbb15e /public/assets/javascripts/mx | |
| parent | 50da9e3e677f121f15e501bf062da6c45db255ad (diff) | |
| parent | cce1dea756717f1308c6b72f762b5ea5f5b43958 (diff) | |
merge
Diffstat (limited to 'public/assets/javascripts/mx')
| -rw-r--r-- | public/assets/javascripts/mx/extensions/mx.movements.js | 406 | ||||
| -rw-r--r-- | public/assets/javascripts/mx/extensions/mx.movementsMobile.js | 203 | ||||
| -rw-r--r-- | public/assets/javascripts/mx/extensions/mx.orbitCamera.js | 97 | ||||
| -rw-r--r-- | public/assets/javascripts/mx/mx.js | 16 | ||||
| -rw-r--r-- | public/assets/javascripts/mx/primitives/mx.grid.js | 70 | ||||
| -rw-r--r-- | public/assets/javascripts/mx/primitives/mx.image.js | 42 | ||||
| -rw-r--r-- | public/assets/javascripts/mx/primitives/mx.point.js | 17 | ||||
| -rw-r--r-- | public/assets/javascripts/mx/primitives/mx.polyline.js | 57 | ||||
| -rw-r--r-- | public/assets/javascripts/mx/primitives/mx.soundcloud.js | 130 | ||||
| -rw-r--r-- | public/assets/javascripts/mx/primitives/mx.text.js | 75 | ||||
| -rw-r--r-- | public/assets/javascripts/mx/primitives/mx.video.js | 17 | ||||
| -rw-r--r-- | public/assets/javascripts/mx/primitives/mx.vimeo.js | 30 | ||||
| -rw-r--r-- | public/assets/javascripts/mx/primitives/mx.youtube.js | 28 |
13 files changed, 935 insertions, 253 deletions
diff --git a/public/assets/javascripts/mx/extensions/mx.movements.js b/public/assets/javascripts/mx/extensions/mx.movements.js index 669a7f4..3e34c1b 100644 --- a/public/assets/javascripts/mx/extensions/mx.movements.js +++ b/public/assets/javascripts/mx/extensions/mx.movements.js @@ -16,193 +16,281 @@ MX.Movements = function (cam) { creeping = false, locked = false, gravity = false, - rotationX_min = PI/-2, - rotationX_max = PI/2 + rotationX_min = PI/-4, + rotationX_max = PI/6 var v = 12, - vr = Math.PI * 0.012, + vr = Math.PI * 0.018, jumpV = 23, vx = vy = vz = 0, creepFactor = 0.3 + var mouseX, mouseY, dx, dy, rotX, rotY, dragging = false + + var trackpad + var DEFAULT_SCALE = 1.0, scale = DEFAULT_SCALE var pos = { x: 0, y: 0, z: 0, rotationX: 0, rotationY: 0 } - return { + $(document).one("keydown", function(){ + $("#keyhint").fadeOut(250); + $('.reader #minimap').addClass('active'); + }) - init: function () { + function clampRotation( vr ) { + if (window.Rooms && Rooms.mover.noclip) { + return clamp(vr, PI/-2, PI/2 ) + } + else { + return clamp(vr, PI/-4, PI/6 ) + } + } - document.addEventListener('keydown', function (e) { - // console.log(e.keyCode) - if (locked || e.altKey || e.metaKey || e.ctrlKey) { - return - } - switch ( e.keyCode ) { - - case 16: // shift - creeping = true - break + var exports = { + + init: function () { + + trackpad = new wheel ({ + el: scene.el, + update: exports.mousewheel, + }) + + document.addEventListener('keydown', exports.keydown) + document.addEventListener('keyup', exports.keyup) + document.addEventListener('mousedown', exports.mousedown) + document.addEventListener('mousemove', exports.mousemove) + document.addEventListener('mouseup', exports.mouseup) + window.addEventListener('blur', exports.reset) + window.addEventListener('focus', exports.reset) + }, + + keydown: function (e) { + // console.log(e.keyCode) + if (locked || e.altKey || e.metaKey || e.ctrlKey) { + return + } + switch ( e.keyCode ) { + + case 16: // shift + creeping = true + break - case 38: // up - case 87: // w - moveForward = true - break + case 38: // up + case 87: // w + moveForward = true + break - case 37: // left - case 65: // a - moveLeft = true - break + case 65: // a + moveLeft = true + break - case 40: // down - case 83: // s - moveBackward = true - break + case 40: // down + case 83: // s + moveBackward = true + break - case 39: // right - case 68: // d - moveRight = true - break + case 68: // d + moveRight = true + break - case 81: // q - turnLeft = true - break - - case 69: // e - turnRight = true - break - - case 82: // r - turnUp = true - break + case 37: // left + case 81: // q + turnLeft = true + break + + case 39: // right + case 69: // e + turnRight = true + break + + case 82: // r + turnUp = true + break - case 70: // f - turnDown = true - break + case 70: // f + turnDown = true + break - case 32: // space - if (gravity) { - jumping = true - vy = abs(vy) + jumpV * scale - if (e.shiftKey) { - vy *= -1 - } + case 32: // space + if (gravity) { + jumping = true + vy = abs(vy) + jumpV * scale + if (e.shiftKey) { + vy *= -1 + } + } + else { + if (e.shiftKey) { + moveDown = true } else { - if (e.shiftKey) { - moveDown = true - } - else { - moveUp = true - } + moveUp = true } - break + } + break - case 27: // esc - map.toggle() - break - } - }) + case 27: // esc + if (Scenery.nextMedia) { + Scenery.nextMedia = null + app.tube('cancel-scenery') + } + else if (Scenery.nextWallpaper) { + Scenery.nextWallpaper = null + app.tube('cancel-wallpaper') + } + else if (app.controller.mediaViewer && app.controller.mediaViewer.$el.hasClass("active")) { + app.controller.mediaViewer.hide() + $(".inuse").removeClass("inuse") + } + else if (app.controller.colorControl && app.controller.colorControl.$el.hasClass('active')) { + app.controller.colorControl.hide() + $(".inuse").removeClass("inuse") + } + else if (app.controller.wallpaperPicker && app.controller.wallpaperPicker.$el.hasClass('active')) { + app.controller.wallpaperPicker.hide() + $(".inuse").removeClass("inuse") + } + else if (app.controller.presets && app.controller.presets.$el.hasClass('active')) { + app.controller.presets.hide() + $(".inuse").removeClass("inuse") + } + else if (Rooms.shapesMode) { + // don't show map in editor for now.. + } + else { + app.controller.toolbar.toggleMap() + } + break + + case 8: // backspace + e.preventDefault() + if (app.controller.sculptureEditor && app.controller.sculptureEditor.sculpture) { + app.controller.sculptureEditor.sculpture.remove() + } + else if (app.controller.mediaEditor && app.controller.mediaEditor.scenery) { + app.controller.mediaEditor.scenery.remove() + } + else if (app.controller.textEditor && app.controller.textEditor.scenery) { + app.controller.textEditor.scenery.remove() + } + } + }, - document.addEventListener('keyup', function (e) { - if (locked) return; - switch ( e.keyCode ) { - - case 16: // shift - creeping = false - break + keyup: function (e) { + if (locked) return; + switch ( e.keyCode ) { + + case 16: // shift + creeping = false + break - case 38: // up - case 87: // w - moveForward = false - break + case 38: // up + case 87: // w + moveForward = false + break - case 37: // left - case 65: // a - moveLeft = false - break + case 65: // a + moveLeft = false + break - case 40: // down - case 83: // s - moveBackward = false - break + case 40: // down + case 83: // s + moveBackward = false + break - case 39: // right - case 68: // d - moveRight = false - break + case 68: // d + moveRight = false + break - case 81: // q - turnLeft = false - break - - case 69: // e - turnRight = false - break + case 37: // left + case 81: // q + turnLeft = false + break + + case 39: // right + case 69: // e + turnRight = false + break - case 82: // r - turnUp = false - break + case 82: // r + turnUp = false + break - case 70: // f - turnDown = false - break + case 70: // f + turnDown = false + break - case 32: // space - moveUp = moveDown = false - break + case 32: // space + moveUp = moveDown = false + break /* - case 48: // 0 - cam.rotationX = 0 - cam.rotationY = 0 - cam.x = 0 - cam.y = viewHeight - cam.z = 0 - break + case 48: // 0 + movements.center() + break */ - } - }) - - var mouseX, mouseY, dx, dy, rotX, rotY, dragging = false - document.addEventListener('mousedown', function (e) { - if (locked) return; - mouseX = e.pageX - mouseY = e.pageY - rotX = cam.rotationX - rotY = cam.rotationY - dragging = true - }) - - document.addEventListener('mousemove', function (e) { - if (locked || ! dragging) return - var dx = (e.pageX - mouseX) / window.innerWidth * Math.PI/3 - var dy = (e.pageY - mouseY) / window.innerHeight * Math.PI/3 - cam.rotationY = rotY + dx - cam.rotationX = clamp( rotX - dy, rotationX_min, rotationX_max ) - }) - - document.addEventListener('mouseup', function (e) { - dragging = false - }) - - window.addEventListener('blur', reset) - window.addEventListener('focus', reset) - function reset(){ - moveForward = moveLeft = moveBackward = moveRight = moveUp = moveDown = turnLeft = turnRight = jumping = dragging = creeping = false } + }, + + center: function(){ + cam.rotationX = 0 + cam.rotationY = 0 + cam.x = 0 + cam.y = viewHeight + cam.z = 0 + }, + mousedown: function (e) { + if (locked) return; + mouseX = e.pageX + mouseY = e.pageY + rotX = cam.rotationX + rotY = cam.rotationY + dragging = true + }, + + mousemove: function (e) { + if (locked || ! dragging) return + var dx = (e.pageX - mouseX) / window.innerWidth * Math.PI/3 + var dy = (e.pageY - mouseY) / window.innerHeight * Math.PI/3 + cam.rotationY = rotY + dx + cam.rotationX = clampRotation( rotX - dy ) + }, + + mouseup: function (e) { + dragging = false + }, + + reset: function(){ + moveForward = moveLeft = moveBackward = moveRight = moveUp = moveDown = turnLeft = turnRight = jumping = dragging = creeping = false + }, + + mousewheel: function (e, deltaY, deltaX) { + if (e.shiftKey) { + cam.rotationY -= deltaY / 150 + } + else { + pos.x += deltaY * Math.cos(cam.rotationY + Math.PI / 2) * 10 + pos.z += deltaY * Math.sin(cam.rotationY + Math.PI / 2) * 10 + app.tube("move", pos) + } }, - update: function () { + update: function (dt) { - if (locked) return; + if (locked) { return } var ry = cam.rotationY var s = creeping ? scale * creepFactor : scale - var vrrrr = creeping ? vr * creepFactor * 5 : vr + var vrrrr = creeping ? vr * creepFactor * 5 : vr * 0.5 var moving = moveForward || moveBackward || moveRight || moveLeft || moveUp || moveDown || turnLeft || turnRight || turnUp || turnDown vx = vz = 0 + + var vv = v +// vv *= dt / 100 * 8 +// s *= dt / 100 * 8 +// console.log(dt / 100 * 8) pos.x = cam.x pos.z = cam.z @@ -210,33 +298,33 @@ MX.Movements = function (cam) { if (moving) { if (moveForward) { - vx += v * Math.cos(ry + Math.PI / 2) * s - vz += v * Math.sin(ry + Math.PI / 2) * s + vx += vv * Math.cos(ry + Math.PI / 2) * s + vz += vv * Math.sin(ry + Math.PI / 2) * s } if (moveBackward) { - vx -= v * Math.cos(ry + Math.PI / 2) * s - vz -= v * Math.sin(ry + Math.PI / 2) * s + vx -= vv * Math.cos(ry + Math.PI / 2) * s + vz -= vv * Math.sin(ry + Math.PI / 2) * s } if (moveLeft) { - vx -= v * Math.cos(ry) * s - vz -= v * Math.sin(ry) * s + vx -= vv * Math.cos(ry) * s + vz -= vv * Math.sin(ry) * s } if (moveRight) { - vx += v * Math.cos(ry) * s - vz += v * Math.sin(ry) * s + vx += vv * Math.cos(ry) * s + vz += vv * Math.sin(ry) * s } if (moveUp) { - pos.y += v * scale + pos.y += vv * scale } if (moveDown) { - pos.y -= v * scale + pos.y -= vv * scale } if (turnUp) { - cam.rotationX = clamp( cam.rotationX - vrrrr*s, rotationX_min, rotationX_max) + cam.rotationX = clampRotation( cam.rotationX - vrrrr*s ) } if (turnDown) { - cam.rotationX = clamp( cam.rotationX + vrrrr*s, rotationX_min, rotationX_max) + cam.rotationX = clampRotation( cam.rotationX + vrrrr*s ) } if (turnLeft) { cam.rotationY += vrrrr*s @@ -261,15 +349,13 @@ MX.Movements = function (cam) { pos.y = viewHeight vy = 0 jumping = false - vz = vz || 1 } - var ceiling = (Rooms.mover.room ? Rooms.mover.room.height : 5000) + var ceiling = ((window.Rooms && Rooms.mover.room) ? Rooms.mover.room.height : 5000) - if (pos.y >= ceiling) { + if (pos.y >= ceiling-5) { vy = 0 - pos.y = ceiling - vz = vz || 1 + pos.y = ceiling-5 } } @@ -286,4 +372,6 @@ MX.Movements = function (cam) { velocity: function(n){ v = clamp(n, 1, 50) }, jumpVelocity: function(n){ jumpV = clamp(n, 1, 50) }, } + + return exports } diff --git a/public/assets/javascripts/mx/extensions/mx.movementsMobile.js b/public/assets/javascripts/mx/extensions/mx.movementsMobile.js index 994c8d7..95b61d1 100644 --- a/public/assets/javascripts/mx/extensions/mx.movementsMobile.js +++ b/public/assets/javascripts/mx/extensions/mx.movementsMobile.js @@ -14,56 +14,169 @@ MX.MobileMovements = function (cam) { var pos = { x: 0, y: viewHeight, z: 0, rotationX: 0, rotationY: 0 } var pointX, pointY, deltaX, deltaY, distX = 0, distY = 0, absDistX = 0, absDistY = 0, startTime - - return { + + var rotationX = 0, rotationY = 0, destRotationX = 0, destRotationY = 0 + var rotationSum = 0 + var rotationMedian = 0 + var orientationMax = 0 + var samples = 0 + var sampleThreshold = 120 + var lastAlpha + + var is_portrait + + var exports = { init: function () { - document.addEventListener("touchstart", function(e){ - if (e.touches.length == 1) { - touching = true - - startTime = Date.now() - - var point = event.touches[0] - pointX = point.pageX - pointY = point.pageY - distX = distY = 0 - pos.x = cam.x - pos.z = cam.z - pos.rotationY = cam.rotationY - } - }) - document.addEventListener("touchmove", function(e){ - e.preventDefault() - if (e.touches.length == 1) { + exports.orientationchange() + + document.addEventListener("touchstart", exports.touchstart) + document.addEventListener("touchmove", exports.touchmove) + document.addEventListener("touchend", exports.touchend) + window.addEventListener('orientationchange', exports.orientationchange) + window.addEventListener("devicemotion", exports.devicemotion) + window.addEventListener("deviceorientation", exports.deviceorientation) + }, + touchstart: function(e){ + if (e.touches.length == 1) { + touching = true + + startTime = Date.now() + + var point = event.touches[0] + pointX = point.pageX + pointY = point.pageY + distX = distY = 0 + pos.x = cam.x + pos.z = cam.z + pos.rotationY = cam.rotationY + } + }, + touchmove: function(e){ + e.preventDefault() + if (e.touches.length == 1) { + + var timestamp = Date.now() + var point = event.touches[0] + deltaX = point.pageX - pointX + deltaY = point.pageY - pointY + + pointX = point.pageX + pointY = point.pageY + + distX += deltaX + distY += deltaY + absDistX = abs(distX) + absDistY = abs(distY) + } + }, + touchend: function(e){ + e.preventDefault() + if (e.touches.length == 0) { + touching = directionLocked = false + var timestamp = Date.now() + var duration = startTime - timestamp + if (duration < 300) { + } + } + }, + orientationchange: function(e){ + is_portrait = window.innerWidth < window.innerHeight + if (is_portrait) { + lastAlpha = 0 + } + }, + devicemotion: function(e) { + if (! is_portrait) return; + var rotationBeta = e.rotationRate.alpha; // weird! + rotationSum += rotationBeta; + samples += 1; + }, + deviceorientation: function (e) { + if (! lastAlpha) { lastAlpha = e.alpha } + is_portrait ? exports.portraitorientation(e) : exports.landscapeorientation(e) + }, + portraitorientation: function(e) { + // compass gives most accurate orientation in portrait mode + var alpha, dx = 0, dy = 0 + + if (e.webkitCompassHeading) { + alpha = 180 - e.webkitCompassHeading; + } + else { + alpha = 180 - e.alpha; + } + + // android rotates in reverse + if (is_android) { + alpha = 360 - alpha + } + + // use rotationRate to gauge if we've tilted the screen past vertical + // for looking at ceiling + if (e.beta > orientationMax) { + orientationMax = e.beta + rotationMedian = rotationSum + } + + // this number was only going to 83 max.. not 90.. weird + var beta = e.beta + 7; + + // if we've got enough motion data, we should be able to determine + // if we've tilted backwards. otherwise, lock to the horizon. + if (! is_android && samples > sampleThreshold) { + dx = rotationSum > rotationMedian ? e.beta - 90 : 90 - e.beta + } + else { + dx = 0 + } + + // avoid jumping around in a circle + if (Math.abs(alpha - lastAlpha) < 100 || Math.abs(alpha - lastAlpha) > 300) { + dy = alpha - lastAlpha + lastAlpha = alpha + } + + // avoid jumping around in a circle #2 + if (dy > 300) { + dy -= 360 + } else if (dy < -300) { + dy += 360 + } + + destRotationX = MX.toRad(dx) + destRotationY += MX.toRad(dy) + }, + + landscapeorientation: function (e) { + var dx, dy + + dx = e.gamma > 0 ? 90 - e.gamma : 90 + e.gamma + dy = e.alpha - lastAlpha + lastAlpha = e.alpha - var timestamp = Date.now() - var point = event.touches[0] - deltaX = point.pageX - pointX - deltaY = point.pageY - pointY - - pointX = point.pageX - pointY = point.pageY + // avoid the sudden jump from 0 to -360 + if (dy > 300) { + dy -= 360 + } + else if (dy < -300) { + dy += 360 + } - distX += deltaX - distY += deltaY - absDistX = abs(distX) - absDistY = abs(distY) - } - }) - document.addEventListener("touchend", function(e){ - e.preventDefault() - if (e.touches.length == 0) { - touching = directionLocked = false - var timestamp = Date.now() - var duration = startTime - timestamp - if (duration < 300) { - } - } - }) + destRotationX = dx > 45 ? 0 : MX.toRad(dx) + destRotationY += MX.toRad(dy) }, update: function () { + var drx, dry + + dry = (destRotationY - rotationY) / 6 + drx = (destRotationX - rotationX) / 6 + rotationY += dry + rotationX += drx + cam.rotationY = pos.rotationY += dry + cam.rotationX = pos.rotationX += drx + if (distX || distY) { var oldDistY = absDistY, oldDistX = absDistX absDistY = avg(absDistY, 0, 5) @@ -77,8 +190,7 @@ MX.MobileMovements = function (cam) { pos.x -= dy * Math.cos(pos.rotationY + Math.PI / 2) pos.z -= dy * Math.sin(pos.rotationY + Math.PI / 2) - pos.rotationY += dx / (window.innerWidth) * Math.PI / 2 - cam.rotationY = pos.rotationY + cam.rotationY = pos.rotationY += dx / (window.innerWidth) * Math.PI / 2 app.tube("move", pos) } @@ -93,6 +205,7 @@ MX.MobileMovements = function (cam) { jumpVelocity: function(n){ jumpV = clamp(n, 1, 50) }, } + return exports } diff --git a/public/assets/javascripts/mx/extensions/mx.orbitCamera.js b/public/assets/javascripts/mx/extensions/mx.orbitCamera.js new file mode 100644 index 0000000..a936cef --- /dev/null +++ b/public/assets/javascripts/mx/extensions/mx.orbitCamera.js @@ -0,0 +1,97 @@ +MX.OrbitCamera = function(opt){ + var exports = {}, bound = false + exports.opt = opt = defaults(opt, { + el: window, // object to bind events on + camera: scene.camera, // camera object we'll be moving + radius: 100, + radiusRange: [ 10, 1000 ], + rotationX: PI/2, + rotationY: 0, + center: { x: 0, y: 0, z: 0 }, + sensitivity: 10, // moving 1 pixel is like moving N radians + wheelSensitivity: 10, + ease: 10, + }) + var rx, ry, radius, px, py, epsilon = 1e-10, dragging = false + exports.init = function(){ + ry = opt.rotationY + rx = opt.rotationX + radius = opt.radius + exports.wheel = new wheel({ + el: opt.el, + update: function(e, delta){ + opt.radius = clamp( opt.radius + delta * opt.wheelSensitivity, opt.radiusRange[0], opt.radiusRange[1] ) + }, + }) + exports.bind() + } + exports.toggle = function(state){ + if (state) exports.bind() + else exports.unbind() + } + exports.bind = function(){ + if (bound) return; + bound = true + opt.el.addEventListener("mousedown", down) + window.addEventListener("mousemove", move) + window.addEventListener("mouseup", up) + exports.wheel.unlock() + } + exports.unbind = function(){ + if (! bound) return; + bound = false + opt.el.removeEventListener("mousedown", down) + window.removeEventListener("mousemove", move) + window.removeEventListener("mouseup", up) + exports.wheel.lock() + } + function down (e) { + px = e.pageX + py = e.pageY + dragging = true + } + function move (e) { + if (! dragging) return + exports.delta(px- e.pageX, py - e.pageY) + px = e.pageX + py = e.pageY + } + function up (e) { + dragging = false + } + exports.delta = function(x,y){ + opt.rotationY += x/window.innerWidth * opt.sensitivity + opt.rotationX = clamp( opt.rotationX + y/window.innerHeight * opt.sensitivity, 0, PI) + } + exports.move = function(y, x){ + opt.rotationY = y + if (typeof x == "number") { opt.rotationX = x } + } + exports.update = function(){ + if (! bound) return + if (abs(ry - opt.rotationY) > epsilon) { + ry = avg(ry, opt.rotationY, opt.ease) + } + else { + ry = opt.rotationY + } + if (abs(rx - opt.rotationX) > epsilon) { + rx = avg(rx, opt.rotationX, opt.ease) + } + else { + rx = opt.rotationX + } + if (abs(radius - opt.radius) > epsilon) { + radius = avg(radius, opt.radius, opt.ease) + } + else { + radius = opt.radius + } + opt.camera.x = opt.center.x + radius * sin(rx) * cos(ry) + opt.camera.y = opt.center.y + radius * cos(rx) + opt.camera.z = opt.center.z + radius * sin(rx) * sin(ry) + opt.camera.rotationX = PI/2 - rx + opt.camera.rotationY = ry + PI/2 + } + return exports +} diff --git a/public/assets/javascripts/mx/mx.js b/public/assets/javascripts/mx/mx.js index 40a5f2e..60651eb 100644 --- a/public/assets/javascripts/mx/mx.js +++ b/public/assets/javascripts/mx/mx.js @@ -25,7 +25,7 @@ var MX = MX || (function (undefined) { var MX = { version: '0.1.0', prefix: undefined, - rotationUnit: 'rad' + rotationUnit: 'rad', } var floatPrecision = 5 @@ -162,24 +162,24 @@ var MX = MX || (function (undefined) { Object.defineProperty(this, 'width', { get: function () { return width - || parseInt(self.el.style.width, 10) + || parseInt(self.el.style.width, 10) * app_devicePixelRatio || 0 }, set: function (val) { width = val - this.el.style.width = width + 'px' + this.el.style.width = (width/app_devicePixelRatio) + 'px' } }) Object.defineProperty(this, 'height', { get: function () { return height - || parseInt(self.el.style.height, 10) + || parseInt(self.el.style.height, 10) * app_devicePixelRatio || 0 }, set: function (val) { height = val - this.el.style.height = height + 'px' + this.el.style.height = (height/app_devicePixelRatio) + 'px' } }) } @@ -302,9 +302,9 @@ var MX = MX || (function (undefined) { + (-this.y).toFixed(floatPrecision) + 'px,' + (-this.z).toFixed(floatPrecision) + 'px) ' + 'scale3d(' - + this.scaleX.toFixed(floatPrecision) + ',' - + this.scaleY.toFixed(floatPrecision) + ',' - + this.scaleZ.toFixed(floatPrecision) + ') ' + + (app_devicePixelRatio * this.scaleX).toFixed(floatPrecision) + ',' + + (app_devicePixelRatio * this.scaleY).toFixed(floatPrecision) + ',' + + (app_devicePixelRatio * this.scaleZ).toFixed(floatPrecision) + ') ' if (rotationTranslation) { transformString += rotationTranslation.before diff --git a/public/assets/javascripts/mx/primitives/mx.grid.js b/public/assets/javascripts/mx/primitives/mx.grid.js new file mode 100644 index 0000000..a765c89 --- /dev/null +++ b/public/assets/javascripts/mx/primitives/mx.grid.js @@ -0,0 +1,70 @@ +MX.Grid = MX.Object3D.extend({ + init: function (ops) { + + this.type = "Grid" + + var ops = this.ops = defaults(ops, { + x: 0, + y: 0, + z: 0, + space: 20, + cells: 20, + }) + + ops.side = ops.space * ops.cells + + var ctx, canvas = document.createElement("canvas") + + this.el = canvas + this.width = this.height = canvas.width = canvas.height = ops.side + 4 + + ctx = canvas.getContext('2d') + + this.x = ops.x || 0 + this.y = ops.y || 0 + this.z = ops.z || 0 + this.rotationX = PI/2 + this.scale = ops.scale || 1 + this.backface = ops.backface || false + + ops.className && this.el.classList.add(ops.className) + this.backface && this.el.classList.add("backface-visible") + this.el.classList.add("mx-grid") + + this.draw(ctx) + }, + + draw: function(ctx, recenter){ + ctx = ctx || this.ctx + + if (recenter) { + ctx.save() + ctx.translate( -grid.width/2, -grid.height/2 ) + } + + var cells = this.ops.cells, + space = this.ops.space, + side = this.ops.side + + ctx.strokeStyle = "#444" + ctx.lineWidth = 1 + ctx.beginPath() + ctx.translate(1,1) + for (var i = 0; i <= cells; i++) { + ctx.moveTo(i*space, 0) + ctx.lineTo(i*space, side) + ctx.moveTo(0, i*space) + ctx.lineTo(side, i*space) + } + ctx.closePath() + ctx.stroke() + + if (recenter) { + ctx.restore() + } + + }, + +}) + + diff --git a/public/assets/javascripts/mx/primitives/mx.image.js b/public/assets/javascripts/mx/primitives/mx.image.js index 575e9c0..ce99592 100644 --- a/public/assets/javascripts/mx/primitives/mx.image.js +++ b/public/assets/javascripts/mx/primitives/mx.image.js @@ -1,6 +1,7 @@ MX.Image = MX.Object3D.extend({ init: function (ops) { - + ops = ops || {} + this.type = "Image" this.media = ops.media this.width = 0 @@ -12,13 +13,13 @@ MX.Image = MX.Object3D.extend({ this.backface = ops.backface || false ops.className && this.el.classList.add(ops.className) - this.backface && this.el.classList.add("backface-visible") + this.backface && this.el.classList.add("backface-visible") this.el.classList.add("image") this.el.classList.add("mx-scenery") this.el.style.backgroundRepeat = 'no-repeat' - this.load(ops) + ops.src && this.load(ops) }, load: function(ops){ @@ -41,8 +42,41 @@ MX.Image = MX.Object3D.extend({ layer.el.classList.add('image') layer.dirty = true layer.update() + layer.ops.onload + + if (ops.keepImage) { + layer.image = image + } + } + + if (ops.src) { + image.src = ops.src + } + else if (ops.media) { + image.src = ops.media.url + } + else if (ops.url) { + image.src = ops.url + } + }, + + draw: function(ctx, recenter){ + if (! this.image) { return } + + if (recenter) { + ctx.save() + ctx.scale(-1, 1) + ctx.translate( -this.width/2 * this.scale, -this.height/2 * this.scale ) + } + + ctx.drawImage(this.image, + 0, 0, this.image.naturalWidth, this.image.naturalHeight, + 0, 0, this.image.width * this.scale * devicePixelRatio, this.image.height * this.scale * devicePixelRatio + ) + + if (recenter) { + ctx.restore() } - image.src = ops.src; }, }) diff --git a/public/assets/javascripts/mx/primitives/mx.point.js b/public/assets/javascripts/mx/primitives/mx.point.js new file mode 100644 index 0000000..41a7732 --- /dev/null +++ b/public/assets/javascripts/mx/primitives/mx.point.js @@ -0,0 +1,17 @@ +MX.Point = MX.Object3D.extend({ + init: function(p){ + this.updateChildren = false + this.move({ + x: p.a, + y: 11, + z: p.b, + width: 20, + height: 20, + rotationX: PI/2, + }) + this.el.style.backgroundColor = 'rgb(' + [abs(floor(p.a*30)), 0, abs(floor(p.b*30))] + ')' + this.el.style.backfaceVisibility = "visible" + this.el.style.borderRadius = "50%" + scene.add(this) + } +}) diff --git a/public/assets/javascripts/mx/primitives/mx.polyline.js b/public/assets/javascripts/mx/primitives/mx.polyline.js new file mode 100644 index 0000000..e549150 --- /dev/null +++ b/public/assets/javascripts/mx/primitives/mx.polyline.js @@ -0,0 +1,57 @@ +MX.Polyline = MX.Object3D.extend({ + init: function(polyline){ + this.faces = [] + this.points = polyline.points + for (var i = 1; i < this.points.length; i++) { + var mx = new MX.Object3D() + var head = this.points[i-1] + var tail = this.points[i] + this.move_face(mx, head, tail) + this.faces.push(mx) + scene.add(mx) + } + }, + + rebuild: function(){ + for (var i = 1; i < this.points.length; i++) { + var mx = this.faces[i-1] + var head = this.points[i-1] + var tail = this.points[i] + this.move_face(mx, head, tail) + } + }, + + move_face: function (mx, head, tail){ + var mid_x = (head.a + tail.a) + var mid_z = (head.b + tail.b) + var len = head.distanceTo( tail ) + var angle = atan2( head.b - tail.b, head.a - tail.a ) + mx.move({ + x: mid_x / 2, + y: wallHeight/2 + 1, + z: mid_z / 2, + width: ceil(len), + height: wallHeight, + rotationY: angle + }) + // var hue = abs(round( angle / PI * 90 + 300)) + // mx.el.style.backgroundColor = 'hsl(' + [hue, "100%", "50%"] + ')' + var lum = abs(round( angle / PI * 20 + 70)) + mx.el.style.backgroundColor = 'hsla(' + ["0", "0%", lum + "%", "0.99"] + ')' + }, + + set_height: function(height){ + for (var i = 0; i < this.faces.length; i++) { + this.faces[i].height = height + this.faces[i].y = height / 2 + 1 + } + }, + + destroy: function(){ + this.faces.forEach(function(mx){ + scene.remove(mx) + }) + this.faces = null + this.points = null + }, +}) diff --git a/public/assets/javascripts/mx/primitives/mx.soundcloud.js b/public/assets/javascripts/mx/primitives/mx.soundcloud.js new file mode 100644 index 0000000..fecb2f4 --- /dev/null +++ b/public/assets/javascripts/mx/primitives/mx.soundcloud.js @@ -0,0 +1,130 @@ +MX.Soundcloud = MX.Object3D.extend({ + init: function (ops) { + + this.type = "Soundcloud" + this.media = ops.media + this.width = 0 + this.height = 0 + this.x = ops.x || 0 + this.y = ops.y || 0 + this.z = ops.z || 0 + this.scale = ops.scale || 1 + this.backface = ops.backface || false + + ops.className && this.el.classList.add(ops.className) + this.backface && this.el.classList.add("backface-visible") + this.el.classList.add("audio") + this.el.classList.add("mx-scenery") + + this.el.style.backgroundRepeat = 'no-repeat' + this.paused = true + + this.ops = ops + }, + + load: function(ops){ + if (ops) { + ops = this.ops = defaults(ops, this.ops) + } + else { + ops = this.ops + } + + this.width = ops.media.width + this.height = ops.media.height + + var tag = Parser.lookup.soundcloud.tag(ops.media) + var $iframe = $(tag) + var iframe = $iframe[0] + $iframe.css('z-index', '-1') + this.el.appendChild( iframe ) + + var overlay = this.overlay = document.createElement("div") + overlay.style.width = "100%" + overlay.style.height = "100%" + overlay.style.position = "absolute" + overlay.style.top = "0" + overlay.style.left = "0" + overlay.style.zIndex = "2" + overlay.className = "overlay" + this.el.appendChild(overlay) + + this.player = SC.Widget( iframe ) + this.player.setVolume(80) + + this.duration = 0 + + this.player.bind(SC.Widget.Events.READY, this.ready.bind(this)) +// this.player.bind(SC.Widget.Events.LOAD_PROGRESS, this.loadProgress.bind(this)) +// this.player.bind(SC.Widget.Events.PLAY_PROGRESS, this.playProgress.bind(this)) + this.player.bind(SC.Widget.Events.PLAY, this.didPlay.bind(this)) + this.player.bind(SC.Widget.Events.PAUSE, this.didPause.bind(this)) + this.player.bind(SC.Widget.Events.FINISH, this.finished.bind(this)) + }, + + ready: function(){ + this.seek( this.media.keyframe || 0 ) + + if (this.media.autoplay) { + this.play() + } + + this.player.getDuration(function(duration){ + this.duration = duration + }.bind(this)) + }, + + play: function(){ + this.player.play() + }, + + pause: function(){ + this.player.pause() + }, + + toggle: function(state){ + if (typeof state === "boolean") { + if (state) this.play() + else this.pause() + } + else { + this.player.toggle() + } + }, + + seek: function(n){ + if (n < 1) { + n = n * this.duration + } + this.player.seekTo(n) + }, + + setLoop: function(state){ + this.media.loop = state + }, + + setVolume: function(n){ + if (this.muted || ! this.player) return + this.player.setVolume(floor( n * 100 )) + }, + + didPlay: function(){ + this.paused = false + }, + + didPause: function(){ + this.paused = true + }, + + finished: function(){ + console.log("soundcloud finished") + if (this.media.loop) { + this.seek(0) + this.play() + } + else if (this.bound) { + $(".playButton").removeClass('playing') + } + }, + +}) diff --git a/public/assets/javascripts/mx/primitives/mx.text.js b/public/assets/javascripts/mx/primitives/mx.text.js index 9c7af5c..3095b67 100644 --- a/public/assets/javascripts/mx/primitives/mx.text.js +++ b/public/assets/javascripts/mx/primitives/mx.text.js @@ -3,34 +3,57 @@ MX.Text = MX.Object3D.extend({ init: function (ops) { this.type = "Text" - - var layer = new MX.Object3D('text') - layer.width = ops.width || 100 - layer.height = ops.height || 50 - layer.x = ops.x || 0 - layer.y = ops.y || 0 - layer.z = ops.z || 0 - layer.scale = ops.scale || 1 - layer.el.innerHTML = ops.value || "" - if (ops.id) layer.el.id = ops.id; - if (ops.background) layer.el.style.background = ops.background; - if (ops.color) layer.el.style.color = ops.color; - if (ops.fontSize) layer.el.style.fontSize = ops.fontSize + "px"; - this.add(layer) + this.type = "Image" + this.media = ops.media + this.width = 0 + this.height = 0 + this.x = ops.x || 0 + this.y = ops.y || 0 + this.z = ops.z || 0 + this.scale = ops.scale || 1 + this.backface = ops.backface || false + + this.scale = ops.scale || 1 + this.width = ops.media.width + this.height = ops.media.height + this.x = ops.x || 0 + this.y = ops.y || 0 + this.z = ops.z || 0 + this.rotationX = ops.rotationX || 0 + this.rotationY = ops.rotationY || 0 + this.rotationZ = ops.rotationZ || 0 + + ops.className && this.el.classList.add(ops.className) + this.backface && this.el.classList.add("backface-visible") + this.el.classList.add("mx-text") + this.el.classList.add("mx-scenery") + + this.inner = document.createElement("div") + this.inner.classList.add("inner") + this.el.appendChild(this.inner) + + this.load(ops) + }, + + load: function(ops){ + var media = ops.media + if (media.font) this.setFont(media.font) - this.children.forEach(function (c, i) { - if (ops.classname) { - c.el.classList.add(ops.classname) - } - else { - } - c.el.style.backgroundRepeat = 'no-repeat' - }) + this.setText( media.description ) + }, + + setFont: function(font){ + if (! font.color || font.color[0] == "#") { font.color = [0,0,0] } - this.dirty = true - this.updateChildren = true - this.update() - } + this.inner.style.fontFamily = "'" + font.family + "',sans-serif" + this.el.style.fontSize = (font.size / devicePixelRatio) + "pt" + this.el.style.textAlign = font.align + this.el.style.color = rgb_string(font.color) + }, + + setText: function(text){ + this.inner.innerHTML = marked( text || "" ) + }, }) diff --git a/public/assets/javascripts/mx/primitives/mx.video.js b/public/assets/javascripts/mx/primitives/mx.video.js index 12d3dcb..53ccf2e 100644 --- a/public/assets/javascripts/mx/primitives/mx.video.js +++ b/public/assets/javascripts/mx/primitives/mx.video.js @@ -21,6 +21,7 @@ MX.Video = MX.Object3D.extend({ this.el.classList.add("video") this.el.classList.add("mx-scenery") this.paused = !! this.media.autoplay + this.playing = false this.muted = app.muted || !! this.media.mute }, @@ -31,8 +32,8 @@ MX.Video = MX.Object3D.extend({ this.player.addEventListener("loadedmetadata", this.ready.bind(this)) this.player.addEventListener("error", this.error.bind(this)) this.player.addEventListener("ended", this.finished.bind(this)) - this.player.width = this.width - this.player.height = this.height + this.player.width = "100%" + this.player.height = "100%" this.player.src = this.media.url this.player.load() @@ -45,6 +46,9 @@ MX.Video = MX.Object3D.extend({ if (this.media.mute) { this.mute() } + else { + this.unmute() + } if (this.media.autoplay) { this.play() @@ -57,11 +61,13 @@ MX.Video = MX.Object3D.extend({ play: function(){ this.paused = false + this.playing = true this.player.play() }, pause: function(){ this.paused = true + this.playing = false this.player.pause() }, @@ -74,14 +80,21 @@ MX.Video = MX.Object3D.extend({ mute: function(){ this.player.muted = true + this.player.volume = 0 this.muted = true }, unmute: function(){ this.player.muted = false + this.player.volume = 0.8 this.muted = false }, + setVolume: function(n){ + if (this.muted || ! this.player) return + this.player.volume = n + }, + setLoop: function(state){ this.media.loop = state }, diff --git a/public/assets/javascripts/mx/primitives/mx.vimeo.js b/public/assets/javascripts/mx/primitives/mx.vimeo.js index 4922519..af138ae 100644 --- a/public/assets/javascripts/mx/primitives/mx.vimeo.js +++ b/public/assets/javascripts/mx/primitives/mx.vimeo.js @@ -20,6 +20,7 @@ MX.Vimeo = MX.Object3D.extend({ this.backface && this.el.classList.add("backface-visible") this.el.classList.add("video") this.el.classList.add("mx-scenery") + this.playing = false this.paused = !! this.media.autoplay this.muted = app.muted || !! this.media.mute this.started = false @@ -32,8 +33,8 @@ MX.Vimeo = MX.Object3D.extend({ preload.id = uid preload.setAttribute("src", "//player.vimeo.com/video/" + this.media.token + "?api=1&badge=0&controls=0branding=0&byline=0&portrait=0&title=0&" + loop + "&player_id=" + uid) preload.style.backgroundImage = "url(" + this.media.thumbnail + ")" - preload.style.width = this.media.width + "px" - preload.style.height = this.media.height + "px" + preload.style.width = "100%" + preload.style.height = "100%" preload.style.border = "0" preload.style.pointerEvents = "none" preload.className = "preload" @@ -62,6 +63,9 @@ MX.Vimeo = MX.Object3D.extend({ if (this.media.mute) { this.mute() } + else { + this.unmute() + } this.seek( this.media.keyframe || 0 ) @@ -96,7 +100,7 @@ MX.Vimeo = MX.Object3D.extend({ return } - if (! this.started || n === 0) { + if (! this.started) { return } @@ -127,6 +131,11 @@ MX.Vimeo = MX.Object3D.extend({ this.player.api('setVolume', 0.8) this.muted = false }, + + setVolume: function(n){ + if (this.muted || ! this.player) return + this.player.api('setVolume', n) + }, setLoop: function(state){ this.media.loop = state @@ -137,19 +146,26 @@ MX.Vimeo = MX.Object3D.extend({ if (this.paused) { this.pause() } + else { + this.playing = true + } }, onPause: function(){ if (! this.paused) { this.play() } + else { + this.playing = false + } }, finished: function(){ -// if (this.media.loop) { -// this.seek(0) -// this.play() -// } + console.log("vimeo finished") + if (this.media.loop) { + this.seek(0) + this.play() + } // else if (this.bound) { if (! this.media.loop && this.bound) { $(".playButton").removeClass('playing') diff --git a/public/assets/javascripts/mx/primitives/mx.youtube.js b/public/assets/javascripts/mx/primitives/mx.youtube.js index 873348f..8cd9f59 100644 --- a/public/assets/javascripts/mx/primitives/mx.youtube.js +++ b/public/assets/javascripts/mx/primitives/mx.youtube.js @@ -21,6 +21,7 @@ MX.Youtube = MX.Object3D.extend({ this.el.classList.add("video") this.el.classList.add("mx-scenery") this.paused = !! this.media.autoplay + this.playing = false this.muted = app.muted || !! this.media.mute }, @@ -31,12 +32,25 @@ MX.Youtube = MX.Object3D.extend({ preload.id = uid preload.style.backgroundImage = "url(" + this.media.thumbnail + ")" preload.style.backgroundSize = "cover" - preload.style.width = this.media.width + "px" - preload.style.height = this.media.height + "px" + preload.style.width = "100%" + preload.style.height = "100%" preload.style.pointerEvents = "none" + preload.style.position = "absolute" + preload.style.top = "0" + preload.style.left = "0" + preload.style.zIndex = "1" preload.className = "preload" this.el.appendChild(preload) + var overlay = this.overlay = document.createElement("div") + overlay.style.width = "100%" + overlay.style.height = "100%" + overlay.style.position = "absolute" + overlay.style.top = "0" + overlay.style.left = "0" + overlay.style.zIndex = "2" + overlay.className = "overlay" + this.el.appendChild(overlay) this.defer(uid) }, @@ -96,6 +110,9 @@ MX.Youtube = MX.Object3D.extend({ if (this.media.mute) { this.mute() } + else { + this.unmute() + } this.seek( this.media.keyframe || 0 ) }, @@ -127,11 +144,13 @@ MX.Youtube = MX.Object3D.extend({ play: function(){ this.paused = false + this.playing = true this.player.playVideo() }, pause: function(){ this.paused = true + this.playing = false this.player.pauseVideo() }, @@ -157,6 +176,11 @@ MX.Youtube = MX.Object3D.extend({ this.player.setVolume(80) this.muted = false }, + + setVolume: function(n){ + if (this.muted || ! this.player || ! this.player.setVolume) return + this.player.setVolume( floor(n * 100) ) + }, setLoop: function(state){ this.media.loop = state |
