Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 152 additions & 32 deletions jquery.cyclotron.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,177 @@
(function ($) {
$.fn.cyclotron = function (options) {
var settings = $.extend({
dampingFactor: 0.93,
historySize: 5
}, options);
(function (jQuery) {
jQuery.fn.cyclotron = function (options) {
return this.each(function () {
var container, sx, dx = 0, armed, offset = 0, tick, prev, h = [];
container = $(this);

container.mousedown(function (e) {
sx = e.pageX - offset;
var container=jQuery(this), sx, dx = 0, armed, offset = 0, tick, prev, h = [], max=0, min=0;
var settings = jQuery.extend({
dampingFactor: 0.93,
historySize: 5,
autorotation: 0,
continuous: 1
}, options);
var checkOffset = function () {
if(settings.continuous===0) {
if (-offset<min) {
dx=(settings.autorotation===1?-dx:0);
offset=-min;
}
if (-offset>max) {
dx=(settings.autorotation===1?-dx:0);
offset=-max;
}
}
}
var tick = function () {
if (!armed && dx!==0) {
dx *= settings.dampingFactor;
offset -= dx;
checkOffset();
container.css('background-position', offset);
if (Math.abs(dx) < 0.001) {
dx = 0;
}
}
};
// check for dampingFactor in range
if((settings.dampingFactor>1 || settings.dampingFactor<0)) {
if (typeof console==='object') {
console.log('dampingFactor out of range '+settings.dampingFactor);
}
settings.dampingFactor=0.93;
}
// check for nonContinuous class to set continuous to 0 if existing
if(settings.continuous===1 && container.hasClass('nonContinuous')) {
settings.continuous=0;
}
// check size of image if not continuous image
if(settings.continuous===0) {
var image = new Image(),
src=container.css('background-image').replace(/url\((['"])?(.*?)\1\)/gi, '$2'),
cssSize = container.css('background-size').split(' '),
elemDim = [container.width(),container.height()],
imagesize = [],
ratio=1;
// Load the image with the extracted URL.
// Should be in cache already.
jQuery(image).one('load',function () {
// Determine the 'ratio'
ratio = image.width > image.height ? image.width / image.height : image.height / image.width;
// First property is width. It is always set to something.
imagesize[0] = cssSize[0];
// If height not set, set it to auto
imagesize[1] = cssSize.length > 1 ? cssSize[1] : 'auto';
// If both values are set to auto, return image's
// original width and height
if(imagesize[0] === 'auto' && imagesize[1] === 'auto') {
imagesize[0] = image.width;
} else {
if(cssSize[0] === 'cover') {
if(elemDim[0] > elemDim[1]) {
// Elem's ratio greater than or equal to img ratio
if(elemDim[0] / elemDim[1] >= ratio) {
return elemDim[0];
} else {
imagesize[0] = 'auto';
imagesize[1] = elemDim[1];
}
} else {
imagesize[0] = 'auto';
imagesize[1] = elemDim[1];
}
} else if(cssSize[0] === 'contain') {
// Width is less than height
if(elemDim[0] < elemDim[1]) {
imagesize[0] = elemDim[0];
} else {
// elem's ratio is greater than or equal to img ratio
if(elemDim[0] / elemDim[1] >= ratio) {
imagesize[0] = 'auto';
imagesize[1] = elemDim[1];
} else {
imagesize[1] = 'auto';
imagesize[0] = elemDim[0];
}
}
} else {
// If not 'cover' or 'contain', loop through the values
for(var i = cssSize.length; i--;) {
// Check if values are in pixels or in percentage
if (cssSize[i].indexOf('px') > -1) {
// If in pixels, just remove the 'px' to get the value
imagesize[i] = cssSize[i].replace('px', '');
} else if (cssSize[i].indexOf('%') > -1) {
// If percentage, get percentage of elem's dimension
// and assign it to the computed dimension
imagesize[i] = elemDim[i] * (cssSize[i].replace('%', '') / 100);
}
}
}
// Depending on whether width or height is auto,
// calculate the value in pixels of auto.
// ratio in here is just getting proportions.
ratio = imagesize[0] === 'auto' ? image.height / imagesize[1] : image.width / imagesize[0];
imagesize[0] = (imagesize[0] === 'auto' ? image.width / ratio : imagesize[0]);
}
max=imagesize[0]-container.width();
});
image.src = src;
}
// set autorotation
if(settings.autorotation!=0) {
armed=false;
dx=settings.autorotation;
}
container.on('touchstart mousedown', function (e) {
var px = (e.pageX>0?e.pageX:e.originalEvent.touches[0].pageX);
sx = px - offset;
armed = true;
e.preventDefault();
});
container.mousemove(function (e) {
var px;
container.on('touchmove mousemove', function (e) {
if (armed) {
px = e.pageX;
if (prev === undefined) {
var px = (e.pageX>0?e.pageX:e.originalEvent.touches[0].pageX);
if (typeof prev==='undefined') {
prev = px;
}
offset = px - sx;
if (h.length > settings.historySize) {
h.shift();
}
h.push(prev - px);

checkOffset();
container.css('background-position', offset);

prev = px;
}
});
container.bind('mouseleave mouseup', function () {
container.on('mouseleave mouseup touchend', function () {
if (armed) {
var i, len = h.length, v = h[len - 1];
for (i = 0; i < len; i++) {
var len = h.length, v = h[len - 1];
for (var i = 0; i < len; i++) {
v = (v * len + (h[i])) / (len + 1);
}
dx = v;
}
armed = false;
});
tick = function () {
if (!armed && dx) {
dx *= settings.dampingFactor;
offset -= dx;
container.css('background-position', offset);
if (Math.abs(dx) < 0.001) {
dx = 0;
}
}
};
setInterval(tick, 16);
// shim layer with setTimeout fallback
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
// use 16.666 ms for better performance in older browsers
window.setTimeout(callback, 100/6);
};
})();
// the equivalent of setInterval(tick, 16);
(function animloop(){
requestAnimFrame(animloop);
tick();
})();
});
};
}(jQuery));
}(jQuery));
jQuery(document).ready(function(){
jQuery('.cyclotron').cyclotron();
});
11 changes: 11 additions & 0 deletions jquery.cyclotron.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 24 additions & 9 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
# jquery.cyclotron.js ([Demo](http://kaioa.com/k/test/cyclotron/index.html))
# jquery.cyclotron.js

## 1. You need some element with a background image. E.g.:
You can see how it works at the [demo page](http://quelbs.github.com/cyclotron/).

## Option 1: Create an element with a background image and class cyclotron.

```html
<div class="cycle" style="background:url(panorama.jpg);height:512px"></div>
<div class="cyclotron" style="background:url(panorama.jpg);height:512px"></div>
```

## 2. Cyclotronify:
## Option 2: Cyclotronify existing objects with additional options

```javascript
$(document).ready(function ($) {
$('.cycle').cyclotron();
$(document).ready(function() {
$('.cycle').cyclotron({dampingFactor:1,autorotation:2});
});
```

## 3. Options:
## Options

`dampingFactor`
*default*: 0.93
Thit is the factor of slowing down rotation (0:immideate stop, 1:continuous rotation). **Hint:** Choose a value around 0.9
If the value is out of range (0..1) it is reset to the default value

`historySize`
*default*: 5
The size of the array which stores the deltas

`dampingFactor` - should be somewhere around 0.9, should be > 0 and < 1 (default: 0.93)
`autorotation`
*default*:0
The value of autorotation will be used for rotation after the image is loaded. **Hint:** You have to set dampingFactor to 1 to prevent slowdown

`historySize` - size of the array which stores the deltas (default: 5)
`continuous`
*default*: 1
If continuous is set 0 the rotation is stopped at the border of the image. This is useful if your image is not a 360° image. **Hint:** continuous also can be set to 0 by adding the class "nonContinuous"