aframe-lerp-component
Advanced tools
Comparing version
@@ -45,3 +45,3 @@ /******/ (function(modules) { // webpackBootstrap | ||
/* 0 */ | ||
/***/ function(module, exports) { | ||
/***/ (function(module, exports, __webpack_require__) { | ||
@@ -55,3 +55,3 @@ /* global AFRAME THREE */ | ||
var degToRad = THREE.Math.degToRad; | ||
var almostEqual = __webpack_require__(1); | ||
/** | ||
@@ -62,3 +62,2 @@ * Linear Interpolation component for A-Frame. | ||
schema: { | ||
duration: { type: 'int', default: 100 }, // milliseconds (ms) | ||
properties: { default: ['position', 'rotation', 'scale']}, | ||
@@ -71,2 +70,7 @@ }, | ||
init: function () { | ||
var el = this.el; | ||
this.lastPosition = el.getAttribute('position'); | ||
this.lastRotation = el.getAttribute('rotation'); | ||
this.lastScale = el.getAttribute('scale'); | ||
this.lerpingPosition = false; | ||
@@ -76,3 +80,3 @@ this.lerpingRotation = false; | ||
this.el.addEventListener('componentchanged', this.changedListener.bind(this)); | ||
this.timeOfLastUpdate = 0; | ||
}, | ||
@@ -88,6 +92,9 @@ | ||
this.checkForComponentChanged(); | ||
// Lerp position | ||
if (this.lerpingPosition) { | ||
progress = (now - this.startLerpTimePosition) / this.data.duration; | ||
progress = (now - this.startLerpTimePosition) / this.duration; | ||
obj3d.position.lerpVectors(this.startPosition, this.targetPosition, progress); | ||
// console.log("new position", obj3d.position); | ||
if (progress >= 1) { | ||
@@ -100,3 +107,3 @@ this.lerpingPosition = false; | ||
if (this.lerpingRotation) { | ||
progress = (now - this.startLerpTimeRotation) / this.data.duration; | ||
progress = (now - this.startLerpTimeRotation) / this.duration; | ||
THREE.Quaternion.slerp(this.startRotation, this.targetRotation, obj3d.quaternion, progress); | ||
@@ -110,3 +117,3 @@ if (progress >= 1) { | ||
if (this.lerpingScale) { | ||
progress = (now - this.startLerpTimeScale) / this.data.duration; | ||
progress = (now - this.startLerpTimeScale) / this.duration; | ||
obj3d.scale.lerpVectors(this.startScale, this.targetScale, progress); | ||
@@ -119,20 +126,43 @@ if (progress >= 1) { | ||
changedListener: function(event) { | ||
var name = event.detail.name; | ||
var oldData = event.detail.oldData; | ||
var newData = event.detail.newData; | ||
checkForComponentChanged: function() { | ||
var el = this.el; | ||
if (this.data.properties.indexOf(name) == -1) { | ||
return; | ||
var hasChanged = false; | ||
var newPosition = el.getAttribute('position'); | ||
if (this.isLerpable('position') && !this.almostEqualVec3(this.lastPosition, newPosition)) { | ||
this.toPosition(this.lastPosition, newPosition); | ||
this.lastPosition = newPosition; | ||
hasChanged = true; | ||
} | ||
if (name == 'position') { | ||
this.toPosition(oldData, newData); | ||
} else if (name == 'rotation') { | ||
this.toRotation(oldData, newData); | ||
} else if (name == 'scale') { | ||
this.toScale(oldData, newData); | ||
var newRotation = el.getAttribute('rotation'); | ||
if (this.isLerpable('rotation') && !this.almostEqualVec3(this.lastRotation, newRotation)) { | ||
this.toRotation(this.lastRotation, newRotation); | ||
this.lastRotation = newRotation; | ||
hasChanged = true; | ||
} | ||
var newScale = el.getAttribute('scale'); | ||
if (this.isLerpable('scale') && !this.almostEqualVec3(this.lastScale, newScale)) { | ||
this.toScale(this.lastScale, newScale); | ||
this.lastScale = newScale; | ||
hasChanged = true; | ||
} | ||
if (hasChanged) { | ||
this.updateDuration(); | ||
} | ||
}, | ||
isLerpable: function(name) { | ||
return this.data.properties.indexOf(name) != -1 | ||
}, | ||
updateDuration: function() { | ||
var now = this.now(); | ||
this.duration = now - this.timeOfLastUpdate; | ||
this.timeOfLastUpdate = now; | ||
}, | ||
/** | ||
@@ -172,2 +202,6 @@ * Start lerp to position (vec3) | ||
almostEqualVec3: function(a, b) { | ||
return almostEqual(a.x, b.x) && almostEqual(a.y, b.y) && almostEqual(a.z, b.z); | ||
}, | ||
/** | ||
@@ -182,3 +216,33 @@ * Returns the current time in milliseconds (ms) | ||
/***/ } | ||
/***/ }), | ||
/* 1 */ | ||
/***/ (function(module, exports) { | ||
"use strict" | ||
var abs = Math.abs | ||
, min = Math.min | ||
function almostEqual(a, b, absoluteError, relativeError) { | ||
var d = abs(a - b) | ||
if (absoluteError == null) absoluteError = almostEqual.DBL_EPSILON; | ||
if (relativeError == null) relativeError = absoluteError; | ||
if(d <= absoluteError) { | ||
return true | ||
} | ||
if(d <= relativeError * min(abs(a), abs(b))) { | ||
return true | ||
} | ||
return a === b | ||
} | ||
almostEqual.FLT_EPSILON = 1.19209290e-7 | ||
almostEqual.DBL_EPSILON = 2.2204460492503131e-16 | ||
module.exports = almostEqual | ||
/***/ }) | ||
/******/ ]); |
@@ -1,1 +0,1 @@ | ||
!function(t){function i(o){if(e[o])return e[o].exports;var n=e[o]={exports:{},id:o,loaded:!1};return t[o].call(n.exports,n,n.exports,i),n.loaded=!0,n.exports}var e={};return i.m=t,i.c=e,i.p="",i(0)}([function(t,i){if("undefined"==typeof AFRAME)throw new Error("Component attempted to register before AFRAME was available.");var e=THREE.Math.degToRad;AFRAME.registerComponent("lerp",{schema:{duration:{type:"int",default:100},properties:{default:["position","rotation","scale"]}},init:function(){this.lerpingPosition=!1,this.lerpingRotation=!1,this.lerpingScale=!1,this.el.addEventListener("componentchanged",this.changedListener.bind(this))},tick:function(t,i){var e,o=this.now(),n=this.el.object3D;this.lerpingPosition&&(e=(o-this.startLerpTimePosition)/this.data.duration,n.position.lerpVectors(this.startPosition,this.targetPosition,e),e>=1&&(this.lerpingPosition=!1)),this.lerpingRotation&&(e=(o-this.startLerpTimeRotation)/this.data.duration,THREE.Quaternion.slerp(this.startRotation,this.targetRotation,n.quaternion,e),e>=1&&(this.lerpingRotation=!1)),this.lerpingScale&&(e=(o-this.startLerpTimeScale)/this.data.duration,n.scale.lerpVectors(this.startScale,this.targetScale,e),e>=1&&(this.lerpingScale=!1))},changedListener:function(t){var i=t.detail.name,e=t.detail.oldData,o=t.detail.newData;this.data.properties.indexOf(i)!=-1&&("position"==i?this.toPosition(e,o):"rotation"==i?this.toRotation(e,o):"scale"==i&&this.toScale(e,o))},toPosition:function(t,i){this.lerpingPosition=!0,this.startLerpTimePosition=this.now(),this.startPosition=new THREE.Vector3(t.x,t.y,t.z),this.targetPosition=new THREE.Vector3(i.x,i.y,i.z)},toRotation:function(t,i){this.lerpingRotation=!0,this.startLerpTimeRotation=this.now(),this.startRotation=new THREE.Quaternion,this.startRotation.setFromEuler(new THREE.Euler(e(t.x),e(t.y),e(t.z),"YXZ")),this.targetRotation=new THREE.Quaternion,this.targetRotation.setFromEuler(new THREE.Euler(e(i.x),e(i.y),e(i.z),"YXZ"))},toScale:function(t,i){this.lerpingScale=!0,this.startLerpTimeScale=this.now(),this.startScale=new THREE.Vector3(t.x,t.y,t.z),this.targetScale=new THREE.Vector3(i.x,i.y,i.z)},now:function(){return Date.now()}})}]); | ||
!function(t){function i(o){if(e[o])return e[o].exports;var s=e[o]={exports:{},id:o,loaded:!1};return t[o].call(s.exports,s,s.exports,i),s.loaded=!0,s.exports}var e={};return i.m=t,i.c=e,i.p="",i(0)}([function(t,i,e){if("undefined"==typeof AFRAME)throw new Error("Component attempted to register before AFRAME was available.");var o=THREE.Math.degToRad,s=e(1);AFRAME.registerComponent("lerp",{schema:{properties:{default:["position","rotation","scale"]}},init:function(){var t=this.el;this.lastPosition=t.getAttribute("position"),this.lastRotation=t.getAttribute("rotation"),this.lastScale=t.getAttribute("scale"),this.lerpingPosition=!1,this.lerpingRotation=!1,this.lerpingScale=!1,this.timeOfLastUpdate=0},tick:function(t,i){var e,o=this.now(),s=this.el.object3D;this.checkForComponentChanged(),this.lerpingPosition&&(e=(o-this.startLerpTimePosition)/this.duration,s.position.lerpVectors(this.startPosition,this.targetPosition,e),e>=1&&(this.lerpingPosition=!1)),this.lerpingRotation&&(e=(o-this.startLerpTimeRotation)/this.duration,THREE.Quaternion.slerp(this.startRotation,this.targetRotation,s.quaternion,e),e>=1&&(this.lerpingRotation=!1)),this.lerpingScale&&(e=(o-this.startLerpTimeScale)/this.duration,s.scale.lerpVectors(this.startScale,this.targetScale,e),e>=1&&(this.lerpingScale=!1))},checkForComponentChanged:function(){var t=this.el,i=!1,e=t.getAttribute("position");this.isLerpable("position")&&!this.almostEqualVec3(this.lastPosition,e)&&(this.toPosition(this.lastPosition,e),this.lastPosition=e,i=!0);var o=t.getAttribute("rotation");this.isLerpable("rotation")&&!this.almostEqualVec3(this.lastRotation,o)&&(this.toRotation(this.lastRotation,o),this.lastRotation=o,i=!0);var s=t.getAttribute("scale");this.isLerpable("scale")&&!this.almostEqualVec3(this.lastScale,s)&&(this.toScale(this.lastScale,s),this.lastScale=s,i=!0),i&&this.updateDuration()},isLerpable:function(t){return this.data.properties.indexOf(t)!=-1},updateDuration:function(){var t=this.now();this.duration=t-this.timeOfLastUpdate,this.timeOfLastUpdate=t},toPosition:function(t,i){this.lerpingPosition=!0,this.startLerpTimePosition=this.now(),this.startPosition=new THREE.Vector3(t.x,t.y,t.z),this.targetPosition=new THREE.Vector3(i.x,i.y,i.z)},toRotation:function(t,i){this.lerpingRotation=!0,this.startLerpTimeRotation=this.now(),this.startRotation=new THREE.Quaternion,this.startRotation.setFromEuler(new THREE.Euler(o(t.x),o(t.y),o(t.z),"YXZ")),this.targetRotation=new THREE.Quaternion,this.targetRotation.setFromEuler(new THREE.Euler(o(i.x),o(i.y),o(i.z),"YXZ"))},toScale:function(t,i){this.lerpingScale=!0,this.startLerpTimeScale=this.now(),this.startScale=new THREE.Vector3(t.x,t.y,t.z),this.targetScale=new THREE.Vector3(i.x,i.y,i.z)},almostEqualVec3:function(t,i){return s(t.x,i.x)&&s(t.y,i.y)&&s(t.z,i.z)},now:function(){return Date.now()}})},function(t,i){"use strict";function e(t,i,n,a){var r=o(t-i);return null==n&&(n=e.DBL_EPSILON),null==a&&(a=n),r<=n||(r<=a*s(o(t),o(i))||t===i)}var o=Math.abs,s=Math.min;e.FLT_EPSILON=1.1920929e-7,e.DBL_EPSILON=2.220446049250313e-16,t.exports=e}]); |
@@ -7,7 +7,6 @@ var def = document.querySelector('#default'); | ||
var updateRate = 5; | ||
var timeToChangeDirection = 1500; | ||
var timeToChangeDirection = 1000; | ||
var moveInDirection = function() { | ||
var defPosition = def.getAttribute('position'); | ||
var lerpPosition = lerp.getAttribute('position'); | ||
var x = defPosition.x; | ||
@@ -17,6 +16,11 @@ var newX = x + direction * speed; | ||
defPosition.x = newX; | ||
lerpPosition.x = newX; | ||
def.setAttribute('position', defPosition); | ||
def.setAttribute('position', defPosition); | ||
lerp.setAttribute('position', lerpPosition); | ||
var lerpPosition = lerp.getAttribute('position'); | ||
var newLerpPos = { | ||
x: newX, | ||
y: lerpPosition.y, | ||
z: lerpPosition.z | ||
}; | ||
lerp.setAttribute('position', newLerpPos); | ||
}; | ||
@@ -23,0 +27,0 @@ |
@@ -1,2 +0,1 @@ | ||
require('aframe'); | ||
require('../index.js'); |
70
index.js
@@ -8,3 +8,3 @@ /* global AFRAME THREE */ | ||
var degToRad = THREE.Math.degToRad; | ||
var almostEqual = require('almost-equal'); | ||
/** | ||
@@ -15,3 +15,2 @@ * Linear Interpolation component for A-Frame. | ||
schema: { | ||
duration: { type: 'int', default: 100 }, // milliseconds (ms) | ||
properties: { default: ['position', 'rotation', 'scale']}, | ||
@@ -24,2 +23,7 @@ }, | ||
init: function () { | ||
var el = this.el; | ||
this.lastPosition = el.getAttribute('position'); | ||
this.lastRotation = el.getAttribute('rotation'); | ||
this.lastScale = el.getAttribute('scale'); | ||
this.lerpingPosition = false; | ||
@@ -29,3 +33,3 @@ this.lerpingRotation = false; | ||
this.el.addEventListener('componentchanged', this.changedListener.bind(this)); | ||
this.timeOfLastUpdate = 0; | ||
}, | ||
@@ -41,6 +45,9 @@ | ||
this.checkForComponentChanged(); | ||
// Lerp position | ||
if (this.lerpingPosition) { | ||
progress = (now - this.startLerpTimePosition) / this.data.duration; | ||
progress = (now - this.startLerpTimePosition) / this.duration; | ||
obj3d.position.lerpVectors(this.startPosition, this.targetPosition, progress); | ||
// console.log("new position", obj3d.position); | ||
if (progress >= 1) { | ||
@@ -53,3 +60,3 @@ this.lerpingPosition = false; | ||
if (this.lerpingRotation) { | ||
progress = (now - this.startLerpTimeRotation) / this.data.duration; | ||
progress = (now - this.startLerpTimeRotation) / this.duration; | ||
THREE.Quaternion.slerp(this.startRotation, this.targetRotation, obj3d.quaternion, progress); | ||
@@ -63,3 +70,3 @@ if (progress >= 1) { | ||
if (this.lerpingScale) { | ||
progress = (now - this.startLerpTimeScale) / this.data.duration; | ||
progress = (now - this.startLerpTimeScale) / this.duration; | ||
obj3d.scale.lerpVectors(this.startScale, this.targetScale, progress); | ||
@@ -72,20 +79,43 @@ if (progress >= 1) { | ||
changedListener: function(event) { | ||
var name = event.detail.name; | ||
var oldData = event.detail.oldData; | ||
var newData = event.detail.newData; | ||
checkForComponentChanged: function() { | ||
var el = this.el; | ||
if (this.data.properties.indexOf(name) == -1) { | ||
return; | ||
var hasChanged = false; | ||
var newPosition = el.getAttribute('position'); | ||
if (this.isLerpable('position') && !this.almostEqualVec3(this.lastPosition, newPosition)) { | ||
this.toPosition(this.lastPosition, newPosition); | ||
this.lastPosition = newPosition; | ||
hasChanged = true; | ||
} | ||
if (name == 'position') { | ||
this.toPosition(oldData, newData); | ||
} else if (name == 'rotation') { | ||
this.toRotation(oldData, newData); | ||
} else if (name == 'scale') { | ||
this.toScale(oldData, newData); | ||
var newRotation = el.getAttribute('rotation'); | ||
if (this.isLerpable('rotation') && !this.almostEqualVec3(this.lastRotation, newRotation)) { | ||
this.toRotation(this.lastRotation, newRotation); | ||
this.lastRotation = newRotation; | ||
hasChanged = true; | ||
} | ||
var newScale = el.getAttribute('scale'); | ||
if (this.isLerpable('scale') && !this.almostEqualVec3(this.lastScale, newScale)) { | ||
this.toScale(this.lastScale, newScale); | ||
this.lastScale = newScale; | ||
hasChanged = true; | ||
} | ||
if (hasChanged) { | ||
this.updateDuration(); | ||
} | ||
}, | ||
isLerpable: function(name) { | ||
return this.data.properties.indexOf(name) != -1 | ||
}, | ||
updateDuration: function() { | ||
var now = this.now(); | ||
this.duration = now - this.timeOfLastUpdate; | ||
this.timeOfLastUpdate = now; | ||
}, | ||
/** | ||
@@ -125,2 +155,6 @@ * Start lerp to position (vec3) | ||
almostEqualVec3: function(a, b) { | ||
return almostEqual(a.x, b.x) && almostEqual(a.y, b.y) && almostEqual(a.z, b.z); | ||
}, | ||
/** | ||
@@ -127,0 +161,0 @@ * Returns the current time in milliseconds (ms) |
{ | ||
"name": "aframe-lerp-component", | ||
"version": "1.0.3", | ||
"version": "1.1.0", | ||
"description": "A linear interpolation component for A-Frame.", | ||
@@ -39,4 +39,6 @@ "main": "index.js", | ||
"homepage": "https://github.com/haydenjameslee/aframe-lerp-component#readme", | ||
"dependencies": { | ||
"almost-equal": "^1.1.0" | ||
}, | ||
"devDependencies": { | ||
"aframe": "^0.4.0", | ||
"browserify": "^13.0.0", | ||
@@ -43,0 +45,0 @@ "budo": "^8.2.2", |
@@ -12,2 +12,3 @@ ## aframe-lerp-component | ||
Try on Glitch: https://aframe-lerp-component.glitch.me/ | ||
@@ -14,0 +15,0 @@ ### API |
@@ -0,0 +0,0 @@ /* global sinon, setup, teardown */ |
@@ -0,0 +0,0 @@ /* global suite */ |
@@ -113,45 +113,2 @@ /* global assert, setup, suite, test */ | ||
suite('changedListener', function () { | ||
test('toPosition called', sinon.test(function() { | ||
var from = { x: 0, y: 0, z: 0 }; | ||
var to = { x: 1, y: 1, z: 1 }; | ||
this.spy(component, 'toPosition'); | ||
el.setAttribute('position', to); | ||
assert.isTrue(component.toPosition.calledWith(from, to)); | ||
})); | ||
test('toRotation called', sinon.test(function() { | ||
var from = { x: 0, y: 0, z: 0 }; | ||
var to = { x: 0, y: 90, z: 0 }; | ||
this.spy(component, 'toRotation'); | ||
el.setAttribute('rotation', to); | ||
assert.isTrue(component.toRotation.calledWith(from, to)); | ||
})); | ||
test('toScale called', sinon.test(function() { | ||
var from = { x: 1, y: 1, z: 1 }; | ||
var to = { x: 2, y: 2, z: 2 }; | ||
this.spy(component, 'toScale'); | ||
el.setAttribute('scale', to); | ||
assert.isTrue(component.toScale.calledWith(from, to)); | ||
})); | ||
test('not included property', sinon.test(function () { | ||
component.data.properties = ['position', 'rotation']; | ||
var to = { x: 2, y: 2, z: 2 }; | ||
this.spy(component, 'toScale'); | ||
el.setAttribute('scale', to); | ||
assert.isFalse(component.toScale.called); | ||
})); | ||
}); | ||
suite('tick', function () { | ||
@@ -158,0 +115,0 @@ |
@@ -0,0 +0,0 @@ // Karma configuration. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
37161
11.19%23
-4.17%646
8.03%66
1.54%1
Infinity%+ Added
+ Added