< drag to rotate >
loading
Go to angle
0°
30°
80°
120°
240°
270°
Ease360 is a 360° image spin sequencer, designed for a better feel. Utilizing HTML5 canvas and JavaScript, Ease360 offers greater performance and control than other methods. Responsive layouts, retina images, event handling, and smart preloading are all supported. Basic setup only requires 3 parameters, but you can do much more.
Features
Physics-based solution for 360 spin
Responsive design options
Modern HTML5 canvas implementation
Multiple callbacks and animation methods
Mobile and tablet support
Smart loading for optimize file weight
Download
Get it on GitHub
Settings
Option
Type
Default
Description
frames
array
null
Ordered list of string paths for animation frames — required
width
int
null
Pixel width of the provided frames — required
height
int
null
Pixel height of the provided frames — required
framesHighDPI
array
—
Retina frames — ordered paths at 2× the dimensions of the frames array.
frameDirection
int
1
Set -1 to reverse the frame sequence.
startAngle
int
—
Starting angle on initialization. Must match an angle present in the provided frames.
backgroundSize
enum
"stretch"
"stretch" sizes images to fit the element. "cover" renders at the largest size contained within or covering the background area.
backgroundOffsetY
float
0
Pixel offset in Y when backgroundSize is "cover".
backgroundOffsetX
float
0
Pixel offset in X when backgroundSize is "cover".
preloadSmart
boolean
false
When true, every other frame loads initially (50%), with the remaining frames loading on user interaction. Requires an even-length frames array.
flex
object
{"w": false}
Set {"w": true} when the element uses a percentage-based width.
eventDirection
enum
"left-right"
"left-right" captures horizontal drag/touch. "up-down" captures vertical. "none" disables interaction.
responsive
array
—
Set of breakpoints with their own options. breakpoint parameter is required in each entry.
breakpoint
int
—
Max-width value where a responsive feature set applies. Must be declared inside the responsive array.
Properties
Property
Type
Default
Description
angle()
int
—
Returns the current angle (0–359). getter
progress
float
0
Loading progress of the frame set as a 0–1 value. getter
physics.damping
float
0.95
Range 0.85–0.98 controls feel from firm to fluid. A value of 1.0 creates a continuous spin. setter-getter
Methods / Events
Method
Parameters
Default
Description
angle(angle)
int
—
Sets angle position when an argument is provided. setter
angleTo(angle, time)
int, float (optional)
0, 1.0
Animates to the specified angle. Duration defaults to 1s.
angleStep(angle)
int
0
Adjusts angle relative to current position — positive or negative offset.
spinOver(speed)
float
1.0
Continuous playthrough of the frame set. Speed can be positive or negative. Intended for hover/rollover effects.
spinOut()
none
—
Cancels spinOver().
changeFrame()
array, array (required if High-DPI was set)
—
Replaces the current frame set. If initialized with framesHighDPI, a second High-DPI array is required.
Callbacks
Callback
Description
progressUpdate
Triggered when the progress property changes.
angleUpdate
Triggered when the angle property changes.
responsiveUpdate
Triggered when the active responsive breakpoint changes.
stateUpdate
Triggered on engine status change. Values: "init", "start", "active", "stop".
Example
Below is the initialization code used for the Genesis G90 demo above.
"use strict";
var myEase360;
var G90lg = [], G90Retinalg = [];
var G90md = [], G90Retinamd = [];
var G90sm = [], G90Retinasm = [];
var G90xs = [], G90Retinaxs = [];
var pathG90lg = "./examples/images/G90_LondonGray_lg-360/";
var pathG90md = "./examples/images/G90_LondonGray_md-360/";
var pathG90sm = "./examples/images/G90_LondonGray_sm-360/";
var pathG90xs = "./examples/images/G90_LondonGray_xs-360/";
for (var i = 0; i < 36; i++) {
G90lg.push(pathG90lg + "G90_LondonGray_lg_" + (i * 10) + ".jpg");
G90Retinalg.push(pathG90lg + "G90_LondonGray_lg@2x_" + (i * 10) + ".jpg");
G90md.push(pathG90md + "G90_LondonGray_md_" + (i * 10) + ".jpg");
G90Retinamd.push(pathG90md + "G90_LondonGray_md@2x_" + (i * 10) + ".jpg");
G90sm.push(pathG90sm + "G90_LondonGray_sm_" + (i * 10) + ".jpg");
G90Retinasm.push(pathG90sm + "G90_LondonGray_sm@2x_" + (i * 10) + ".jpg");
G90xs.push(pathG90xs + "G90_LondonGray_xs_" + (i * 10) + ".jpg");
G90Retinaxs.push(pathG90xs + "G90_LondonGray_xs@2x_" + (i * 10) + ".jpg");
}
$(function () {
myEase360 = $('#myEase360').ease360({
frames: G90lg, // required
framesHighDPI: G90Retinalg,
frameDirection: -1, // sequence is reversed
width: 1442, // required
height: 950, // required
backgroundSize: "cover",
preloadSmart: true,
flex: { "w": true },
responsive: [
{
breakpoint: 962,
frames: G90md,
framesHighDPI: G90Retinamd,
width: 962,
height: 634,
flex: { "w": true }
},
{
breakpoint: 660,
frames: G90sm,
framesHighDPI: G90Retinasm,
width: 668,
height: 440,
flex: { "w": true }
},
{
breakpoint: 340,
frames: G90xs,
framesHighDPI: G90Retinaxs,
width: 342,
height: 225,
flex: { "w": true }
}
],
angleUpdate: function () { myAngleUpdate(); },
progressUpdate: function () { myProgress(); },
responsiveUpdate: function () { myResponsiveUpdate(); }
});
myEase360.physics.damping = 0.94;
});
var $instructions = $('.instructions');
function myAngleUpdate() {
if (myEase360 == null) return;
if ($instructions.hasClass('opacity1')) $instructions.removeClass('opacity1');
}
function myProgress() {
var multiplier = myEase360.preloadSmart ? 2 : 1;
var percent = Math.floor(myEase360.progress * 100) * multiplier;
$('.loading h4').html(percent + "%");
if (percent === 100) {
$('#myEase360 canvas').addClass('opacity1');
$('.loading').addClass('opacity0').delay(2000).queue(function () {
$(this).css({ "z-index": 0 });
$('#ease360Layout h3.instructions').addClass('opacity1');
$('.loading h4').html("loading");
$(this).dequeue();
});
}
}
function myResponsiveUpdate() {
$('.loading').removeClass('opacity0');
$('#myEase360 canvas').removeClass('opacity1');
$(".loading").css({ "z-index": 1000 });
}
function goto(angle) {
myEase360.angleTo(angle, 0.75); // time is optional, defaults to 1s
}