summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid DeSandro <desandrocodes@gmail.com>2014-12-12 14:52:28 -0500
committerDavid DeSandro <desandrocodes@gmail.com>2014-12-12 14:52:28 -0500
commit4d8c5d58b78de0b222761a7961a179960458dd59 (patch)
tree1fc9f48539fe62a7c9d2f00438566b7b869b2457
parent31545d7aa0241c7e86cb6e554b4f62799cd0959b (diff)
downloadflickity-dev-4d8c5d58b78de0b222761a7961a179960458dd59.zip
flickity-dev-4d8c5d58b78de0b222761a7961a179960458dd59.tar.gz
flickity-dev-4d8c5d58b78de0b222761a7961a179960458dd59.tar.bz2
bounds3 demo
-rw-r--r--sandbox/bounds2/demo.js2
-rw-r--r--sandbox/bounds3/demo.js188
-rw-r--r--sandbox/bounds3/index.html26
-rw-r--r--sandbox/bounds3/slider.js45
4 files changed, 260 insertions, 1 deletions
diff --git a/sandbox/bounds2/demo.js b/sandbox/bounds2/demo.js
index 763445f..8f3e1d4 100644
--- a/sandbox/bounds2/demo.js
+++ b/sandbox/bounds2/demo.js
@@ -49,7 +49,7 @@ function animate() {
function applyBoundForce( boundX, direction ) {
// left force
var distance = boundX - particle.x;
- var force = distance * 0.03;
+ var force = distance * 0.05;
force = Math.max( force * direction, 0 ) * direction;
// prevent particle from bounds too far back
// don't apply force if particle is returning from outside bounds
diff --git a/sandbox/bounds3/demo.js b/sandbox/bounds3/demo.js
new file mode 100644
index 0000000..f245b06
--- /dev/null
+++ b/sandbox/bounds3/demo.js
@@ -0,0 +1,188 @@
+/*global Slider: false, rAF: false */
+
+// -------------------------- demo -------------------------- //
+
+var canvas, ctx;
+var canvasW, canvasH;
+var slider;
+var cells = [];
+var leftBound, rightBound;
+var cellWidths = [ 0.2, 0.2, 0.4, 0.2, 0.3 ];
+
+document.addEventListener( 'DOMContentLoaded', init, false );
+
+function init() {
+ canvas = document.querySelector('canvas');
+ ctx = canvas.getContext('2d');
+ // set size
+ canvasW = canvas.width = window.innerWidth - 20;
+ canvasH = canvas.height = 300;
+
+ // create cells
+ var cellX = 0;
+ var gutter = 40;
+ for ( var i=0, len = cellWidths.length; i < len; i++ ) {
+ var cellWidth = cellWidths[i];
+ var cell = {
+ width: canvasW * cellWidth,
+ height: canvasH - 40,
+ x: cellX,
+ index: i
+ };
+ cellX += cell.width + gutter;
+ cells.push( cell );
+ }
+
+ leftBound = 100;
+ rightBound = canvasW - 100;
+
+ canvas.addEventListener( 'mousedown', onMousedown, false );
+
+ slider = new Slider( leftBound, 0 );
+ slider.width = cellX - gutter;
+
+ animate();
+}
+
+// -------------------------- animate -------------------------- //
+
+function animate() {
+ if ( !isDragging ) {
+ applyLeftBoundForce();
+ applyRightBoundForce();
+ }
+
+ slider.update();
+
+ render();
+ rAF( animate );
+}
+
+function applyLeftBoundForce() {
+ var sliderX = slider.x;
+
+ var distance = leftBound - sliderX;
+ var force = distance * 0.05;
+ force = Math.min( force, 0 );
+ // prevent slider from bounds too far back
+ // don't apply force if slider is returning from outside bounds
+ if ( force && slider.velocity < 0 ) {
+ // resting position
+ var restPosition = slider.getRestingPosition();
+ if ( restPosition.x < leftBound ) {
+ force = ( leftBound - slider.x ) / restPosition.frictionSum - slider.velocity;
+ }
+ }
+ slider.applyForce( force );
+}
+
+function applyRightBoundForce() {
+ var sliderX = slider.x + slider.width;
+
+ var distance = rightBound - sliderX;
+ var force = distance * 0.05;
+ force = Math.max( force, 0 );
+ // prevent slider from bounds too far back
+ // don't apply force if slider is returning from outside bounds
+ if ( force && slider.velocity > 0 ) {
+ // resting position
+ var restPosition = slider.getRestingPosition();
+ if ( restPosition.x + slider.width > rightBound ) {
+ force = ( rightBound - sliderX ) / restPosition.frictionSum - slider.velocity;
+ }
+ }
+ slider.applyForce( force );
+}
+
+// -------------------------- render -------------------------- //
+
+function render() {
+ ctx.clearRect( 0, 0, canvasW, canvasH );
+
+ // bounds
+ ctx.lineWidth = 1;
+ ctx.strokeStyle = 'hsla(300, 100%, 40%, 1)';
+ line( leftBound, 0, leftBound, canvasH );
+ line( rightBound, 0, rightBound, canvasH );
+
+ // cells
+ ctx.save();
+ ctx.translate( slider.x, 0 );
+ for ( var i=0, len = cells.length; i < len; i++ ) {
+ var cell = cells[i];
+ var hue = i * 70;
+ ctx.fillStyle = 'hsla(' + hue + ', 100%, 40%, 0.5)';
+ ctx.fillRect( cell.x, 20, cell.width, cell.height );
+ // target line
+ ctx.strokeStyle = 'yellow';
+ line( cell.target, 40, cell.target, cell.height );
+ }
+
+ ctx.restore();
+}
+
+function line( x1, y1, x2, y2 ) {
+ ctx.beginPath();
+ ctx.moveTo( x1, y1 );
+ ctx.lineTo( x2, y2 );
+ ctx.stroke();
+ ctx.closePath();
+}
+
+function circle( x, y, radius ) {
+ ctx.beginPath();
+ ctx.arc( x, y, radius, 0, Math.PI * 2 );
+ ctx.fill();
+ ctx.closePath();
+}
+
+// -------------------------- mouse -------------------------- //
+
+var isDragging = false;
+
+var dragStartX;
+
+function onMousedown( event ) {
+ event.preventDefault();
+ isDragging = true;
+ window.addEventListener( 'mousemove', onMousemove, false );
+ window.addEventListener( 'mouseup', onMouseup, false );
+ dragStartX = event.pageX;
+ slider.dragStartX = slider.x;
+ slider.velocity = 0;
+}
+
+var previousX;
+var previousTime;
+var currentTime;
+
+function onMousemove( event ) {
+ // previous
+ previousX = slider.x;
+ previousTime = currentTime;
+ // current
+ var moveX = event.pageX - dragStartX;
+ slider.x = slider.dragStartX + moveX;
+ currentTime = new Date();
+}
+
+function onMouseup( event ) {
+ dragEnd();
+ window.removeEventListener( 'mousemove', onMousemove, false );
+ window.removeEventListener( 'mousemove', onMouseup, false );
+}
+
+function dragEnd() {
+ if ( previousX ) {
+ // set slider velocity
+ slider.velocity = ( slider.x - previousX ) / ( currentTime - previousTime );
+ slider.velocity *= 1000 / 60;
+ // reset previousX
+ previousX = null;
+ } else {
+ estimateX = slider.x;
+ }
+
+ isDragging = false;
+
+}
diff --git a/sandbox/bounds3/index.html b/sandbox/bounds3/index.html
new file mode 100644
index 0000000..c6b6e54
--- /dev/null
+++ b/sandbox/bounds3/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8">
+
+ <title>bounds3</title>
+
+ <style>
+ * { margin: 0; padding: 0; }
+ </style>
+
+</head>
+<body>
+
+ <h1>bounds3</h1>
+
+<canvas></canvas>
+
+<p></p>
+
+<script src="../request-animation-frame.js"></script>
+<script src="slider.js"></script>
+<script src="demo.js"></script>
+
+</body>
+</html>
diff --git a/sandbox/bounds3/slider.js b/sandbox/bounds3/slider.js
new file mode 100644
index 0000000..e245071
--- /dev/null
+++ b/sandbox/bounds3/slider.js
@@ -0,0 +1,45 @@
+( function() {
+
+function Slider( x, y ) {
+ this.x = x;
+ this.y = y;
+ this.velocity = 0;
+ this.accel = 0;
+ this.friction = 0.15;
+}
+
+Slider.prototype.update = function() {
+ this.velocity += this.accel;
+ this.velocity *= ( 1 - this.friction );
+ this.x += this.velocity;
+ this.accel = 0;
+};
+
+Slider.prototype.applyForce = function( force ) {
+ this.accel += force;
+};
+
+
+Slider.prototype.getRestingPosition = function() {
+
+ var fFriction = 1 - this.friction;
+ var restingVelo = 0.07;
+ var ticks = getBaseLog( fFriction, restingVelo / Math.abs( this.velocity ) );
+ var frictionSum = ( Math.pow( fFriction, ticks + 1 ) - 1 ) / ( fFriction - 1 );
+ var restX = this.x + this.velocity * fFriction * frictionSum;
+
+ return {
+ x: restX,
+ frictionSum: frictionSum
+ };
+};
+
+
+function getBaseLog( a, b ) {
+ return Math.log( b ) / Math.log( a );
+}
+
+
+window.Slider = Slider;
+
+})();