<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<div class="card">
<img src="http://images.ticiz.com/1992285_w640_h640_original23574925460.jpg" class="card-image" draggable="false">
</div>
html,
body {
height: 100%;
}
body {
background: #000;
cursor: url(https://tebm.files.wordpress.com/2010/02/arge-proje-egitim-esnasc4b1nda-hallerim-1.jpg?w=1000&h=) 10 2, auto;
overflow: hidden;
&:active {
cursor: url(https://tebm.files.wordpress.com/2010/02/arge-proje-egitim-esnasc4b1nda-hallerim-1.jpg?w=1000&h=) 10 2, auto;
}
&:after {
background-color: #000;
background-image: url(https://tebm.files.wordpress.com/2010/02/arge-proje-egitim-esnasc4b1nda-hallerim-1.jpg?w=1000&h=);
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
bottom: 0;
content: '';
filter: blur( 8px );
left: 0;
opacity: 0.8;
position: absolute;
right: 0;
top: 0;
will-change: transform;
z-index: -1;
}
}
.card {
left: 0;
top: 0;
perspective: 400px;
position: absolute;
transform-style: preserve-3d;
will-change: transform;
width: 250px;
user-drag: none;
user-select: none;
-moz-user-select: none;
-webkit-user-drag: none;
-webkit-user-select: none;
-ms-user-select: none;
&:active {
cursor: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/836/hearthstone-grab.png) 10 2, auto;
}
}
.card-image {
display: block;
pointer-events: none;
transform-style: preserve-3d;
width: 100%;
will-change: transform;
user-drag: none;
user-select: none;
-moz-user-select: none;
-webkit-user-drag: none;
-webkit-user-select: none;
-ms-user-select: none;
}
var card,
image,
cardw,
cardh,
cardx,
cardy,
ocardx,
ocardy,
pinx,
piny,
pinxperc,
pinyperc,
targetx,
targety,
rx,
ry,
targetrx,
targetry,
scale,
targetscale,
ww,
wh,
md,
mx,
my,
whoosh,
whooshvol,
whooshvoltarget,
majesty,
majestyvol,
majestyvoltarget,
audioloaded;
function audioload() {
audioloaded++;
if( audioloaded == 2 ) {
document.body.classList.add( 'loaded' );
majesty.play();
whoosh.play();
bindevents();
loop();
}
}
function init() {
onresize();
card = document.querySelector( '.card' );
image = document.querySelector( '.card-image' );
cardw = image.width;
cardh = image.height;
cardx = ww / 2 - cardw / 2;
cardy = wh / 2 - cardh / 2;
ocardx = cardx;
ocardy = cardy;
pinx = 0;
piny = 0;
pinxperc = 0;
pinyperc = 0;
targetx = cardx;
targety = cardy;
rx = 0;
ry = 0;
targetrx = 0;
targetry = 0;
scale = 1;
targetscale = scale;
md = false;
mx = cardx;
my = cardy;
audioloaded = 0;
whooshvol = 0;
whooshvoltarget = 0;
whoosh = new Audio();
whoosh.addEventListener( 'canplaythrough', audioload );
whoosh.src = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/836/hs-whoosh.ogg';
whoosh.volume = 0;
whoosh.loop = true;
majestyvol = 0;
majestyvoltarget = 0;
majesty = new Audio();
majesty.addEventListener( 'canplaythrough', audioload );
majesty.src = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/836/hs-majesty.ogg';
majesty.volume = 0;
majesty.loop = true;
}
function bindevents() {
card.addEventListener( 'mousedown', onmousedown );
window.addEventListener( 'mouseup', onmouseup );
window.addEventListener( 'mousemove', onmousemove );
window.addEventListener( 'resize', onresize );
}
function onmousedown( e ) {
md = true;
mx = e.pageX;
my = e.pageY;
pinx = cardw / 2; // pin to center
piny = cardh / 2; // pin to center
//pinx = mx - cardx; // pin to click point
//piny = my - cardy; // pin to click point
pinxperc = 100 - ( pinx / cardw ) * 100; // transform based on the pin position
pinyperc = 100 - ( piny / cardh ) * 100; // transform based on the pin position
}
function onmouseup() {
md = false;
}
function onmousemove( e ) {
if( md ) {
mx = e.pageX;
my = e.pageY;
}
}
function onresize() {
ww = window.innerWidth;
wh = window.innerHeight;
}
function loop() {
requestAnimationFrame( loop )
// set new target position
targetx = mx - cardx - pinx;
targety = my - cardy - piny;
// lerp to new position
cardx += targetx * 0.25;
cardy += targety * 0.25;
// contain card to window bounds
if( cardx < -cardw / 2 ) {
cardx = -cardw / 2;
}
if( cardx > ww - cardw / 2 ) {
cardx = ww - cardw / 2;
}
if( cardy < -cardh / 2 ) {
cardy = -cardh / 2;
}
if( cardy > wh - cardh / 2 ) {
cardy = wh - cardh / 2;
}
// get rotation based on how much card moved
targetrx = ( ocardy - cardy - rx ) * 3;
targetry = ( cardx - ocardx - ry ) * 3;
// lock rotation so things don't get too crazy
targetrx = Math.min( targetrx, 90 );
targetrx = Math.max( targetrx, -90 );
targetry = Math.min( targetry, 90 );
targetry = Math.max( targetry, -90 );
// lerp to new rotation
rx += targetrx * 0.1;
ry += targetry * 0.1;
// scale up when the mouse is pressed
targetscale = md ? 1.2 - scale : 1 - scale;
scale += targetscale * 0.2;
// apply the transform
card.style[ 'transform' ] = 'translate3d(' + cardx + 'px, ' + cardy + 'px, 0)';
image.style[ 'transform-origin' ] = pinxperc + '% ' + pinyperc + '%';
image.style[ 'transform' ] = 'scale(' + scale + ') rotateY(' + ry + 'deg) rotateX(' + rx + 'deg)';
majestyvoltarget = md ? 0.2 : 0;
majestyvol += ( majestyvoltarget - majestyvol ) * 0.1;
majesty.volume = majestyvol;
whooshvoltarget = ( Math.abs( ( ocardy - cardy ) ) + Math.abs( ( ocardx - cardx ) ) ) * 0.003;
whooshvol += ( whooshvoltarget - whooshvol ) * 0.1;
whoosh.volume = Math.min( whooshvol, 1 );
// store the old card position
ocardx = cardx;
ocardy = cardy;
}
// pull up a chair by the hearth!
window.onload = init;