mirror of
https://github.com/dataarts/dat.gui.git
synced 2024-12-12 04:08:27 +00:00
919 lines
19 KiB
JavaScript
919 lines
19 KiB
JavaScript
GUI.Scrubber = function(controller, timer) {
|
|
|
|
var _this = this;
|
|
|
|
|
|
this.points = [];
|
|
this.timer = timer;
|
|
this.timer.scrubbers.push(this);
|
|
this.controller = controller;
|
|
this.controller.scrubber = this;
|
|
this.playing = false;
|
|
|
|
var previouslyHandled;
|
|
this.position = null;
|
|
|
|
this.getJSON = function() {
|
|
|
|
var pointArray = [];
|
|
for (var i in this.points) {
|
|
pointArray.push(this.points[i].getJSON());
|
|
}
|
|
var obj = {'points': pointArray};
|
|
|
|
return obj;
|
|
|
|
};
|
|
|
|
this.sort = function() {
|
|
this.points.sort(function(a,b) {
|
|
return a.time - b.time;
|
|
});
|
|
};
|
|
|
|
this.add = function(p) {
|
|
this.points.push(p);
|
|
this.sort();
|
|
};
|
|
|
|
var lastDown = 0;
|
|
|
|
this.controller.addChangeListener(function(newVal) {
|
|
|
|
if (!_this.playing) {
|
|
|
|
var v = newVal;
|
|
|
|
if (_this.controller.type == 'boolean') {
|
|
v = !v; // Couldn't tell you why I have to do this.
|
|
}
|
|
|
|
if (_this.timer.activePoint == null) {
|
|
_this.timer.activePoint = new GUI.ScrubberPoint(_this, _this.timer.playhead, v);
|
|
_this.add(_this.timer.activePoint);
|
|
_this.render();
|
|
} else {
|
|
_this.timer.activePoint.value = v;
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this.domElement = document.createElement('div');
|
|
this.domElement.setAttribute('class', 'guidat-scrubber');
|
|
|
|
this.canvas = document.createElement('canvas');
|
|
this.domElement.appendChild(this.canvas);
|
|
|
|
this.g = this.canvas.getContext('2d');
|
|
|
|
var width;
|
|
var height;
|
|
|
|
var mx, pmx;
|
|
|
|
this.__defineGetter__('width', function() {
|
|
return width;
|
|
});
|
|
|
|
this.__defineGetter__('height', function() {
|
|
return height;
|
|
});
|
|
|
|
controller.domElement.insertBefore(this.domElement, controller.propertyNameElement.nextSibling);
|
|
|
|
this.render = function() {
|
|
|
|
// TODO: if visible ...
|
|
|
|
_this.g.clearRect(0, 0, width, height);
|
|
|
|
// Draw 0
|
|
if (_this.timer.windowMin < 0) {
|
|
var x = GUI.map(0, _this.timer.windowMin, _this.timer.windowMin+_this.timer.windowWidth, 0, width);
|
|
_this.g.fillStyle = '#000';
|
|
_this.g.fillRect(0, 0, x, height-1);
|
|
}
|
|
|
|
// Draw ticks
|
|
if (_this.timer.useSnap) {
|
|
_this.g.lineWidth = 1;
|
|
// TODO: That's just a damned nasty for loop.
|
|
for (var i = _this.timer.snap(_this.timer.windowMin); i < _this.timer.windowMin+_this.timer.windowWidth; i+= _this.timer.snapIncrement) {
|
|
if (i == 0) continue;
|
|
var x = Math.round(GUI.map(i, _this.timer.windowMin, _this.timer.windowMin+_this.timer.windowWidth, 0, width))+0.5;
|
|
if (i < 0) {
|
|
_this.g.strokeStyle = '#111111';
|
|
} else {
|
|
_this.g.strokeStyle = '#282828';
|
|
}
|
|
_this.g.beginPath();
|
|
_this.g.moveTo(x, 0);
|
|
_this.g.lineTo(x, height-1);
|
|
_this.g.stroke();
|
|
}
|
|
}
|
|
|
|
// Draw points
|
|
for (var i in _this.points) {
|
|
_this.points[i].update();
|
|
}
|
|
|
|
for (var i in _this.points) {
|
|
_this.points[i].render();
|
|
}
|
|
|
|
// Draw playhead
|
|
_this.g.strokeStyle = '#ff0024';
|
|
_this.g.lineWidth = 1;
|
|
var t = Math.round(GUI.map(_this.timer.playhead, _this.timer.windowMin, _this.timer.windowMin+_this.timer.windowWidth, 0, width))+0.5;
|
|
_this.g.beginPath();
|
|
_this.g.moveTo(t, 0);
|
|
_this.g.lineTo(t, height);
|
|
_this.g.stroke();
|
|
|
|
}
|
|
|
|
this.render();
|
|
|
|
var onResize = function() {
|
|
_this.canvas.width = width = _this.domElement.offsetWidth;
|
|
_this.canvas.height = height = _this.domElement.offsetHeight;
|
|
_this.position = GUI.getOffset(_this.canvas);
|
|
_this.render();
|
|
};
|
|
|
|
window.addEventListener('resize', function(e) {
|
|
onResize();
|
|
}, false);
|
|
|
|
|
|
var scrubPan = function() {
|
|
|
|
var t = _this.timer.playhead;
|
|
var tmin = _this.timer.windowMin + _this.timer.windowWidth/5;
|
|
var tmax = _this.timer.windowMin + _this.timer.windowWidth - _this.timer.windowWidth/5;
|
|
|
|
if (t < tmin) {
|
|
_this.timer.windowMin += GUI.map(t, _this.timer.windowMin, tmin, -_this.timer.windowWidth/50, 0);
|
|
}
|
|
|
|
if (t > tmax) {
|
|
_this.timer.windowMin += 0;
|
|
_this.timer.windowMin += GUI.map(t, tmax, _this.timer.windowMin+_this.timer.windowWidth, 0,_this.timer.windowWidth/50);
|
|
}
|
|
|
|
}
|
|
|
|
var scrub = function(e) {
|
|
var t = GUI.map(e.pageX, _this.position.left, _this.position.left+width, _this.timer.windowMin, _this.timer.windowMin+_this.timer.windowWidth);
|
|
_this.timer.playhead = _this.timer.snap(t);
|
|
scrubPan();
|
|
}
|
|
|
|
var pan = function(e) {
|
|
mx = e.pageX;
|
|
var t = GUI.map(mx - pmx, 0, width, 0, _this.timer.windowWidth);
|
|
_this.timer.windowMin -= t;
|
|
pmx = mx;
|
|
}
|
|
|
|
this.canvas.addEventListener('mousedown', function(e) {
|
|
|
|
// TODO: Detect right click and prevent that menu?
|
|
if (false) {
|
|
e.preventDefault();
|
|
document.addEventListener('mousemove', pan, false);
|
|
return false;
|
|
}
|
|
|
|
var thisDown = GUI.millis();
|
|
|
|
// Double click creates a keyframe
|
|
// TODO: You can double click to create a keyframe right on top of an existing keyframe.
|
|
// TODO: Make 300 a constant of some sort.
|
|
if (thisDown - lastDown < 300) {
|
|
|
|
var val = _this.controller.getValue();
|
|
|
|
if (_this.controller.type == 'boolean') {
|
|
val = !val;
|
|
}
|
|
|
|
_this.timer.activePoint = new GUI.ScrubberPoint(_this, _this.timer.playhead, val);
|
|
_this.timer.activePoint.update(); // Grab x and y
|
|
_this.timer.activePoint.onSelect();
|
|
_this.add(_this.timer.activePoint);
|
|
_this.render();
|
|
|
|
// A regular click COULD select a point ...
|
|
} else if (_this.timer.hoverPoint != null) {
|
|
|
|
if (_this.timer.activePoint != _this.timer.hoverPoint) {
|
|
if (_this.timer.activePoint != null) _this.timer.activePoint.onBlur();
|
|
_this.timer.activePoint = _this.timer.hoverPoint;
|
|
_this.timer.activePoint.onSelect();
|
|
}
|
|
_this.timer.playhead = _this.timer.snap(_this.timer.activePoint.time);
|
|
|
|
pmx = mx = e.pageX;
|
|
document.addEventListener('mousemove', _this.timer.activePoint.onDrag, false);
|
|
|
|
|
|
|
|
// Or we could just be trying to place the playhead/scrub.
|
|
} else {
|
|
|
|
if (_this.timer.activePoint != null) {
|
|
_this.timer.activePoint.onBlur();
|
|
}
|
|
|
|
_this.timer.activePoint = null;
|
|
_this.timer.hoverPoint = null;
|
|
scrub(e);
|
|
document.body.style.cursor = 'text';
|
|
_this.timer.pause();
|
|
pmx = mx = e.pageX;
|
|
document.addEventListener('mousemove', scrub, false);
|
|
_this.render();
|
|
|
|
}
|
|
|
|
lastDown = thisDown;
|
|
|
|
}, false);
|
|
|
|
this.canvas.addEventListener('mousewheel', function(e) {
|
|
e.preventDefault();
|
|
|
|
var dx = e.wheelDeltaX*4;
|
|
|
|
var dy = e.wheelDeltaY*4;
|
|
_this.timer.windowWidth -= dy;
|
|
_this.timer.windowMin += dy/2 - dx;
|
|
|
|
|
|
return false;
|
|
}, false);
|
|
|
|
this.canvas.addEventListener('mousemove', function(e) {
|
|
_this.timer.hoverPoint = null;
|
|
for (var i in _this.points) {
|
|
var cur = _this.points[i];
|
|
if (cur.isHovering(e.pageX-_this.position.left)) {
|
|
_this.timer.hoverPoint = cur;
|
|
}
|
|
}
|
|
if (_this.timer.hoverPoint == null) {
|
|
document.body.style.cursor = 'pointer';
|
|
} else {
|
|
document.body.style.cursor = 'auto';
|
|
}
|
|
_this.render();
|
|
});
|
|
|
|
document.addEventListener('mouseup', function() {
|
|
document.body.style.cursor = 'auto';
|
|
if (_this.timer.activePoint != null) {
|
|
document.removeEventListener('mousemove', _this.timer.activePoint.onDrag, false);
|
|
}
|
|
document.removeEventListener('mousemove', scrub, false);
|
|
document.removeEventListener('mousemove', pan, false);
|
|
}, false);
|
|
|
|
onResize();
|
|
|
|
this.timer.addPlayListener(this.render);
|
|
|
|
var handlePoint = function(point) {
|
|
if (point != previouslyHandled) {
|
|
previouslyHandled = point;
|
|
_this.controller.setValue(point.value);
|
|
}
|
|
};
|
|
|
|
var onPlayChange = function(curTime, prevTime) {
|
|
|
|
if (_this.points.length == 0) return;
|
|
|
|
_this.playing = true;
|
|
|
|
if (_this.controller.type == 'function') {
|
|
|
|
for (var i = 0; i < _this.points.length; i++) {
|
|
var t = _this.points[i].time;
|
|
if ((curTime > prevTime && prevTime < t && t < curTime) ||
|
|
(curTime < prevTime && prevTime > t && t > curTime)) {
|
|
_this.controller.getValue().call(this);
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
var prev = undefined, next = undefined;
|
|
|
|
// Find 'surrounding' points.
|
|
|
|
for (var i = 0; i < _this.points.length; i++) {
|
|
var t = _this.points[i].time;
|
|
|
|
if (t > curTime) {
|
|
|
|
if (i == 0) {
|
|
|
|
prev = null;
|
|
next = _this.points[i];
|
|
break;
|
|
|
|
} else {
|
|
|
|
prev = _this.points[i-1];
|
|
next = _this.points[i];
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (next == undefined) {
|
|
prev = _this.points[_this.points.length-1];
|
|
next = null;
|
|
}
|
|
|
|
|
|
if (next != null & prev != null) {
|
|
|
|
if (_this.controller.type == 'number') {
|
|
|
|
var t = prev.tween(GUI.map(curTime, prev.time, next.time, 0, 1));
|
|
|
|
_this.controller.setValue(GUI.map(t, 0, 1, prev.value, next.value));
|
|
|
|
|
|
} else {
|
|
handlePoint(prev);
|
|
}
|
|
|
|
} else if (next != null) {
|
|
|
|
handlePoint(next);
|
|
|
|
} else if (prev != null) {
|
|
|
|
handlePoint(prev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_this.playing = false;
|
|
|
|
};
|
|
|
|
this.timer.addPlayListener(onPlayChange);
|
|
this.timer.addWindowListener(this.render);
|
|
|
|
// Load saved points!!!!
|
|
|
|
if (timer.gui.json) {
|
|
var json = timer.gui.json.timer.scrubbers.splice(0, 1)[0];
|
|
for (var i in json.points) {
|
|
var p = json.points[i];
|
|
var pp = new GUI.ScrubberPoint(this, p.time, p.value);
|
|
if (p.tween) {
|
|
pp.tween = GUI.Easing[p.tween];
|
|
}
|
|
this.add(pp);
|
|
}
|
|
}
|
|
|
|
|
|
};
|
|
|
|
GUI.ScrubberPoint = function(scrubber, time, value) {
|
|
|
|
var _this = this;
|
|
|
|
var g = scrubber.g;
|
|
var timer = scrubber.timer;
|
|
var type = scrubber.controller.type;
|
|
var x, y;
|
|
|
|
this.hold = false;
|
|
|
|
var val;
|
|
|
|
this.__defineSetter__('value', function(v) {
|
|
val = v;
|
|
scrubber.render();
|
|
});
|
|
|
|
this.value = value;
|
|
|
|
this.__defineGetter__('value', function() {
|
|
return val;
|
|
});
|
|
|
|
this.__defineGetter__('x', function() {
|
|
return x;
|
|
});
|
|
|
|
this.__defineGetter__('y', function() {
|
|
return y;
|
|
});
|
|
|
|
var barSize = 4;
|
|
var rectSize = 5;
|
|
|
|
var c1 = '#ffd800';
|
|
var c2 = '#ff9000';
|
|
|
|
var positionTweenSelector = function() {
|
|
var tweenSelectorLeft = (scrubber.position.left + timer.activePoint.x) - timer.tweenSelector.offsetWidth/2;
|
|
var tweenSelectorTop = GUI.getOffset(scrubber.canvas, timer.gui.domElement).top + timer.activePoint.y - 25;
|
|
timer.tweenSelector.style.left = tweenSelectorLeft+'px';
|
|
timer.tweenSelector.style.top = tweenSelectorTop+'px';
|
|
}
|
|
|
|
this.onSelect = function() {
|
|
|
|
if (type == 'number') {
|
|
|
|
timer.showTweenSelector();
|
|
positionTweenSelector();
|
|
var tweenName;
|
|
for (var i in GUI.Easing) {
|
|
if (this.tween == GUI.Easing[i]) {
|
|
tweenName = i;
|
|
}
|
|
}
|
|
timer.tweenSelector.value = tweenName;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
this.onBlur = function() {
|
|
if (type == 'number') {
|
|
timer.hideTweenSelector();
|
|
}
|
|
}
|
|
|
|
this.onDrag = function(e) {
|
|
var t = GUI.map(e.pageX, scrubber.position.left, scrubber.position.left+scrubber.canvas.width, timer.windowMin, timer.windowMin+timer.windowWidth);
|
|
_this.time = timer.snap(t);
|
|
timer.playhead = timer.snap(t);
|
|
scrubber.sort();
|
|
_this.update();
|
|
if (type == 'number') {
|
|
positionTweenSelector();
|
|
}
|
|
}
|
|
|
|
this.getJSON = function() {
|
|
var obj = { 'value': _this.value, 'time': GUI.roundToDecimal(time,4) };
|
|
|
|
// TODO: save tweens
|
|
|
|
if (this.tween != GUI.Easing.Linear) {
|
|
for (var i in GUI.Easing) {
|
|
if (this.tween == GUI.Easing[i]) {
|
|
obj.tween = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
return obj;
|
|
|
|
};
|
|
|
|
this.tween = GUI.Easing.Linear;
|
|
|
|
this.remove = function() {
|
|
scrubber.points.splice(scrubber.points.indexOf(this), 1);
|
|
scrubber.render();
|
|
};
|
|
|
|
this.isHovering = function(xx) {
|
|
return xx >= x-rectSize/2 && xx <= x+rectSize/2;
|
|
};
|
|
|
|
this.__defineGetter__('next', function() {
|
|
if (scrubber.points.length <= 1) {
|
|
return null;
|
|
}
|
|
|
|
var i = scrubber.points.indexOf(this);
|
|
if (i + 1 >= scrubber.points.length) {
|
|
return null;
|
|
}
|
|
|
|
return scrubber.points[i+1];
|
|
|
|
});
|
|
|
|
this.__defineGetter__('prev', function() {
|
|
if (scrubber.points.length <= 1) {
|
|
return null;
|
|
}
|
|
|
|
var i = scrubber.points.indexOf(this);
|
|
if (i - 1 < 0) {
|
|
return null;
|
|
}
|
|
|
|
return scrubber.points[i-1];
|
|
|
|
});
|
|
|
|
this.__defineGetter__('time', function() {
|
|
return time;
|
|
});
|
|
|
|
this.__defineSetter__('time', function(s) {
|
|
time = s;
|
|
});
|
|
|
|
this.update = function() {
|
|
|
|
x = GUI.map(time, timer.windowMin, timer.windowMin+timer.windowWidth, 0, 1);
|
|
x = Math.round(GUI.map(x, 0, 1, 0, scrubber.width));
|
|
|
|
y = scrubber.height/2;
|
|
|
|
if (scrubber.controller.type == 'number') {
|
|
y = GUI.map(_this.value, scrubber.controller.min, scrubber.controller.max, scrubber.height, 0);
|
|
}
|
|
|
|
}
|
|
|
|
this.render = function() {
|
|
|
|
if (x < 0 || x > scrubber.width) {
|
|
return;
|
|
}
|
|
|
|
if (GUI.hidden) {
|
|
return;
|
|
}
|
|
|
|
// TODO: if hidden because of scroll top.
|
|
|
|
if (scrubber.timer.activePoint == this) {
|
|
g.fillStyle = '#ffd800'; //
|
|
} else if (scrubber.timer.hoverPoint == this) {
|
|
g.fillStyle = '#999';
|
|
} else {
|
|
g.fillStyle = '#ccc';
|
|
}
|
|
|
|
switch (type) {
|
|
|
|
case 'boolean':
|
|
|
|
g.save();
|
|
g.translate(x, y-0.5);
|
|
|
|
if (this.value) {
|
|
|
|
g.strokeStyle = g.fillStyle;
|
|
g.lineWidth = barSize;
|
|
g.beginPath();
|
|
g.arc(0, 0, barSize, 0, Math.PI*2, false);
|
|
g.stroke();
|
|
|
|
} else {
|
|
|
|
g.rotate(Math.PI/4);
|
|
g.fillRect(-barSize/2, -barSize*3.5/2, barSize, barSize*3.5);
|
|
g.rotate(Math.PI/2);
|
|
g.fillRect(-barSize/2, -barSize*3.5/2, barSize, barSize*3.5);
|
|
}
|
|
|
|
g.restore();
|
|
|
|
break;
|
|
|
|
case 'number':
|
|
|
|
g.save();
|
|
|
|
var p = this.prev;
|
|
|
|
g.lineWidth = 3;
|
|
g.strokeStyle='#222';
|
|
|
|
if (p != null && p.time < timer.windowMin) {
|
|
console.log(p.time, timer.windowMin);
|
|
var t = GUI.map(timer.windowMin, p.time, this.time, 0, 1);
|
|
var yy = GUI.map(p.tween(t), 0, 1, p.y, y);
|
|
|
|
g.beginPath();
|
|
g.moveTo(0, yy);
|
|
|
|
if (p.tween == GUI.Easing.Linear) {
|
|
|
|
g.lineTo(x, y);
|
|
|
|
} else {
|
|
|
|
for (var i = t; i < 1; i+=0.01) {
|
|
var tx = GUI.map(i, 0, 1, p.x, x);
|
|
var ty = p.tween(i);
|
|
ty = GUI.map(ty, 0, 1, p.y, y);
|
|
g.lineTo(tx, ty);
|
|
}
|
|
|
|
}
|
|
|
|
g.stroke();
|
|
|
|
}
|
|
|
|
var n = this.next;
|
|
|
|
if (n != null) {
|
|
|
|
g.beginPath();
|
|
|
|
g.moveTo(x, y);
|
|
|
|
|
|
if (_this.tween == GUI.Easing.Linear) {
|
|
g.lineTo(n.x, n.y);
|
|
} else {
|
|
for (var i = 0; i < 1; i+=0.01) {
|
|
var tx = GUI.map(i, 0, 1, x, n.x);
|
|
var ty = _this.tween(i);
|
|
ty = GUI.map(ty, 0, 1, y, n.y);
|
|
g.lineTo(tx, ty);
|
|
}
|
|
}
|
|
|
|
g.stroke();
|
|
|
|
}
|
|
|
|
g.translate(x, y);
|
|
g.rotate(Math.PI/4);
|
|
// g.fillStyle = c1;
|
|
g.fillRect(-rectSize/2, -rectSize/2, rectSize, rectSize);
|
|
g.restore();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g.save();
|
|
g.translate(x-barSize/2, 0);
|
|
//g.fillStyle = c1;
|
|
g.fillRect(0, 0, barSize/2, scrubber.height-1);
|
|
//g.fillStyle = c2;
|
|
g.fillRect(barSize/2, 0, barSize/2, scrubber.height-1);
|
|
g.restore();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
GUI.Easing = {}
|
|
|
|
GUI.Easing.Linear = function ( k ) {
|
|
return k;
|
|
};
|
|
|
|
GUI.Easing.Hold = function(k) {
|
|
return 0;
|
|
}
|
|
|
|
GUI.Easing.QuadraticEaseIn = function ( k ) {
|
|
|
|
return k * k;
|
|
|
|
};
|
|
|
|
GUI.Easing.QuadraticEaseOut = function ( k ) {
|
|
|
|
return - k * ( k - 2 );
|
|
|
|
};
|
|
|
|
GUI.Easing.QuadraticEaseInOut = function ( k ) {
|
|
|
|
if ( ( k *= 2 ) < 1 ) return 0.5 * k * k;
|
|
return - 0.5 * ( --k * ( k - 2 ) - 1 );
|
|
|
|
};
|
|
|
|
GUI.Easing.CubicEaseIn = function ( k ) {
|
|
|
|
return k * k * k;
|
|
|
|
};
|
|
|
|
GUI.Easing.CubicEaseOut = function ( k ) {
|
|
|
|
return --k * k * k + 1;
|
|
|
|
};
|
|
|
|
GUI.Easing.CubicEaseInOut = function ( k ) {
|
|
|
|
if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k;
|
|
return 0.5 * ( ( k -= 2 ) * k * k + 2 );
|
|
|
|
};
|
|
|
|
GUI.Easing.QuarticEaseIn = function ( k ) {
|
|
|
|
return k * k * k * k;
|
|
|
|
};
|
|
|
|
GUI.Easing.QuarticEaseOut = function ( k ) {
|
|
|
|
return - ( --k * k * k * k - 1 );
|
|
|
|
}
|
|
|
|
GUI.Easing.QuarticEaseInOut = function ( k ) {
|
|
|
|
if ( ( k *= 2 ) < 1) return 0.5 * k * k * k * k;
|
|
return - 0.5 * ( ( k -= 2 ) * k * k * k - 2 );
|
|
|
|
};
|
|
|
|
//
|
|
|
|
GUI.Easing.QuinticEaseIn = function ( k ) {
|
|
|
|
return k * k * k * k * k;
|
|
|
|
};
|
|
|
|
GUI.Easing.QuinticEaseOut = function ( k ) {
|
|
|
|
return ( k = k - 1 ) * k * k * k * k + 1;
|
|
|
|
};
|
|
|
|
GUI.Easing.QuinticEaseInOut = function ( k ) {
|
|
|
|
if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k * k * k;
|
|
return 0.5 * ( ( k -= 2 ) * k * k * k * k + 2 );
|
|
|
|
};
|
|
|
|
GUI.Easing.SinusoidalEaseIn = function ( k ) {
|
|
|
|
return - Math.cos( k * Math.PI / 2 ) + 1;
|
|
|
|
};
|
|
|
|
GUI.Easing.SinusoidalEaseOut = function ( k ) {
|
|
|
|
return Math.sin( k * Math.PI / 2 );
|
|
|
|
};
|
|
|
|
GUI.Easing.SinusoidalEaseInOut = function ( k ) {
|
|
|
|
return - 0.5 * ( Math.cos( Math.PI * k ) - 1 );
|
|
|
|
};
|
|
|
|
GUI.Easing.ExponentialEaseIn = function ( k ) {
|
|
|
|
return k == 0 ? 0 : Math.pow( 2, 10 * ( k - 1 ) );
|
|
|
|
};
|
|
|
|
GUI.Easing.ExponentialEaseOut = function ( k ) {
|
|
|
|
return k == 1 ? 1 : - Math.pow( 2, - 10 * k ) + 1;
|
|
|
|
};
|
|
|
|
GUI.Easing.ExponentialEaseInOut = function ( k ) {
|
|
|
|
if ( k == 0 ) return 0;
|
|
if ( k == 1 ) return 1;
|
|
if ( ( k *= 2 ) < 1 ) return 0.5 * Math.pow( 2, 10 * ( k - 1 ) );
|
|
return 0.5 * ( - Math.pow( 2, - 10 * ( k - 1 ) ) + 2 );
|
|
|
|
};
|
|
|
|
GUI.Easing.CircularEaseIn = function ( k ) {
|
|
|
|
return - ( Math.sqrt( 1 - k * k ) - 1);
|
|
|
|
};
|
|
|
|
GUI.Easing.CircularEaseOut = function ( k ) {
|
|
|
|
return Math.sqrt( 1 - --k * k );
|
|
|
|
};
|
|
|
|
GUI.Easing.CircularEaseInOut = function ( k ) {
|
|
|
|
if ( ( k /= 0.5 ) < 1) return - 0.5 * ( Math.sqrt( 1 - k * k) - 1);
|
|
return 0.5 * ( Math.sqrt( 1 - ( k -= 2) * k) + 1);
|
|
|
|
};
|
|
|
|
GUI.Easing.ElasticEaseIn = function( k ) {
|
|
|
|
var s, a = 0.1, p = 0.4;
|
|
if ( k == 0 ) return 0; if ( k == 1 ) return 1; if ( !p ) p = 0.3;
|
|
if ( !a || a < 1 ) { a = 1; s = p / 4; }
|
|
else s = p / ( 2 * Math.PI ) * Math.asin( 1 / a );
|
|
return - ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
|
|
|
|
};
|
|
|
|
GUI.Easing.ElasticEaseOut = function( k ) {
|
|
|
|
var s, a = 0.1, p = 0.4;
|
|
if ( k == 0 ) return 0; if ( k == 1 ) return 1; if ( !p ) p = 0.3;
|
|
if ( !a || a < 1 ) { a = 1; s = p / 4; }
|
|
else s = p / ( 2 * Math.PI ) * Math.asin( 1 / a );
|
|
return ( a * Math.pow( 2, - 10 * k) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) + 1 );
|
|
|
|
};
|
|
|
|
GUI.Easing.ElasticEaseInOut = function( k ) {
|
|
|
|
var s, a = 0.1, p = 0.4;
|
|
if ( k == 0 ) return 0; if ( k == 1 ) return 1; if ( !p ) p = 0.3;
|
|
if ( !a || a < 1 ) { a = 1; s = p / 4; }
|
|
else s = p / ( 2 * Math.PI ) * Math.asin( 1 / a );
|
|
if ( ( k *= 2 ) < 1 ) return - 0.5 * ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
|
|
return a * Math.pow( 2, -10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) * 0.5 + 1;
|
|
|
|
};
|
|
|
|
GUI.Easing.BackEaseIn = function( k ) {
|
|
|
|
var s = 1.70158;
|
|
return k * k * ( ( s + 1 ) * k - s );
|
|
|
|
};
|
|
|
|
GUI.Easing.BackEaseOut = function( k ) {
|
|
|
|
var s = 1.70158;
|
|
return ( k = k - 1 ) * k * ( ( s + 1 ) * k + s ) + 1;
|
|
|
|
};
|
|
|
|
GUI.Easing.BackEaseInOut = function( k ) {
|
|
|
|
var s = 1.70158 * 1.525;
|
|
if ( ( k *= 2 ) < 1 ) return 0.5 * ( k * k * ( ( s + 1 ) * k - s ) );
|
|
return 0.5 * ( ( k -= 2 ) * k * ( ( s + 1 ) * k + s ) + 2 );
|
|
|
|
};
|
|
|
|
GUI.Easing.BounceEaseIn = function( k ) {
|
|
|
|
return 1 - GUI.Easing.BounceEaseOut( 1 - k );
|
|
|
|
};
|
|
|
|
GUI.Easing.BounceEaseOut = function( k ) {
|
|
|
|
if ( ( k /= 1 ) < ( 1 / 2.75 ) ) {
|
|
|
|
return 7.5625 * k * k;
|
|
|
|
} else if ( k < ( 2 / 2.75 ) ) {
|
|
|
|
return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
|
|
|
|
} else if ( k < ( 2.5 / 2.75 ) ) {
|
|
|
|
return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
|
|
|
|
} else {
|
|
|
|
return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
GUI.Easing.BounceEaseInOut = function( k ) {
|
|
|
|
if ( k < 0.5 ) return GUI.Easing.BounceEaseIn( k * 2 ) * 0.5;
|
|
return GUI.Easing.BounceEaseOut( k * 2 - 1 ) * 0.5 + 0.5;
|
|
|
|
};
|
|
|