PhotoTilt
by HYEONGJINKIM
HTML
<!-- access to the HEAD element -->
<meta name='viewport' content='initial-scale=1.0, width=device-width' />
CSS
html,
body {
overflow:hidden;
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
.mask {
position: absolute;
top:0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
.mask img {
position: absolute;
left: 0;
top: 0;
}
.tilt-bar {
position: fixed;
top: 30px;
left: 10px;
right: 10px;
height: 3px;
z-index: 1;
background-color: rgba(255,255,255,0.3);
}
.tilt-indicator {
background-color: rgba(255,255,255,0.8);
height: 3px;
position: absolute;
}
.mask img,
.tilt-indicator {
-webkit-transition: -webkit-transform 0.2s linear;
-moz-transition: -moz-transform 0.2s linear;
-ms-transition: -ms-transform 0.2s linear;
transition: transform 0.2s linear;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-perspective: 1000;
-moz-perspective: 1000;
-ms-perspective: 1000;
perspective: 1000;
-webkit-transform: translatez(0);
-moz-transform: translatez(0);
-ms-transform: translatez(0);
transform: translatez(0);
}
JavaScript
var PhotoTilt = function(options) {
'use strict';
var imgUrl = options.url,
lowResUrl = options.lowResUrl,
container = options.container || document.body,
latestTilt = 0,
viewport,
imgData,
img,
imgLoader,
delta,
centerOffset,
tiltBarWidth,
tiltCenterOffset,
tiltBarIndicatorWidth,
tiltBarIndicator,
config;
config = {
maxTilt: options.maxTilt || 20,
twoPhase: options.lowResUrl || false,
reverseTilt: options.reverseTilt || false
};
window.requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
var init = function() {
var url = config.twoPhase ? lowResUrl : imgUrl;
generateViewPort();
preloadImg(url, function() {
img = imgLoader.cloneNode(false);
generateImgData();
imgLoader = null;
if (config.twoPhase) {
preloadImg(imgUrl, function() {
img.src = imgLoader.src;
imgLoader = null;
});
}
render();
addEventListeners();
});
};
var updatePosition = function() {
var tilt = latestTilt,
pxToMove;
if (tilt > 0) {
tilt = Math.min(tilt, config.maxTilt);
} else {
tilt = Math.max(tilt, config.maxTilt * -1);
}
if (!config.reverseTilt) {
tilt = tilt * -1;
}
pxToMove = (tilt * centerOffset) / config.maxTilt;
updateImgPosition(imgData, (centerOffset + pxToMove) * -1);
updateTiltBar(tilt);
window.requestAnimationFrame(updatePosition);
};
var updateTiltBar = function(tilt) {
var pxToMove = (tilt * ((tiltBarWidth - tiltBarIndicatorWidth) / 2)) / config.maxTilt;
setTranslateX(tiltBarIndicator, (tiltCenterOffset + pxToMove) );
};
var updateImgPosition = function(imgData, pxToMove) {
setTranslateX(img, pxToMove);
};
var addEventListeners = function() {
if (window.DeviceOrientationEvent) {
var averageGamma = [];
window.addEventListener('deviceorientation', function(eventData) {
if...