var mouseDown = false; var mousePosition = {x: 0, y: 0}; var gimbleRotation = {x: 0, y: 0}; $(document).ready(function(){ $('.block').mouseenter(function(){ $('#debug').text('hovering over: #' + $(this).attr('id') + '.block'); }); $('.block').mouseleave(function(){ $('#debug').text(''); }); $('#stage').mousedown(function(ev){ mouseDown = true; mousePosition['x'] = ev.pageX; mousePosition['y'] = ev.pageY; return false; }); $('#stage').mouseup(function(ev){ mouseDown = false; mousePosition = {x: 0, y: 0}; return false; }); $('#stage').mouseleave(function(ev){ $('#stage').trigger('mouseup'); }); $('#stage').mousemove(function(ev){ if (mouseDown) { var x = ev.pageX; var y = ev.pageY; var dx = mousePosition['x'] - x; var dy = mousePosition['y'] - y; gimbleRotation['x'] -= dx/2; gimbleRotation['y'] += dy/2; var newTransformRotateXY = "rotateY(" + gimbleRotation['x'] + "deg) rotateX(" + gimbleRotation['y'] + "deg)"; $('#gimble').css({ '-webkit-transform': newTransformRotateXY, '-webkit-transition-duration': '0ms' }); mousePosition['x'] = ev.pageX; mousePosition['y'] = ev.pageY; } return false; }); $('.block').click(function(){ $('#gimble').css({ '-webkit-transform': 'rotateX('+$(this).data('rx')+'deg) rotateY('+$(this).data('ry')+'deg)', '-webkit-transition-duration': '150ms' }); // not sure why this needs to be reversed to work... gimbleRotation = {x: $(this).data('ry'), y: $(this).data('rx')}; }); })
<div id="stage"> <div id="debug"></div> <div id="gimble"> <div id="a" class="block" data-rx="0" data-ry="0">the quick</div> <div id="b" class="block" data-rx="0" data-ry="-90">brown fox</div> <div id="c" class="block" data-rx="0" data-ry="90">jumps over</div> <div id="d" class="block" data-rx="90" data-ry="0">the lazy</div> <div id="e" class="block" data-rx="-90" data-ry="0">fox hound</div> <div id="f" class="block" data-rx="0" data-ry="180">endlessly</div> </div> </div>
#stage { -webkit-transform-origin: center center; -webkit-transform-style: preserve-3d; -webkit-perspective: 500px; position: absolute; top: 0; left: 0; height: 300px; width: 300px; display: block; border: 1px dotted #CCC; } #debug { font-family: 'helvetica neue', helvetica, arial, sans-serif; font-weight: 200; position: absolute; top: 0; left: 0; } #gimble { -webkit-transform-style: preserve-3d; position: absolute; top: 0; left: 0; height: 300px; width: 300px; position: relative; display: block; border: 1px solid #EEE; } .block { -webkit-transform-style: preserve-3d; position: absolute; top: 0; left: 0; display: block; opacity: .5; border: 1px solid #F00; height: 100px; width: 100px; text-align: left; color: #FFF; font-weight: 200; font-family: 'Helvetica Neue', Helvetica, Arial, Sans-Serif; } #a.block { background: #900; top: 100px; left: 100px; -webkit-transform: translate3d(0px,0px,50px) rotateY(0deg); } #b.block { background: #090; top: 100px; left: 100px; -webkit-transform: translate3d(50px,0px,0px) rotateY(90deg); } #c.block { background: #009; top: 100px; left: 100px; -webkit-transform: translate3d(-50px,0px,0px) rotateY(-90deg); } #d.block { background: #990; top: 100px; left: 100px; -webkit-transform: translate3d(0px,50px,0px) rotateX(-90deg); } #e.block { background: #099; top: 100px; left: 100px; -webkit-transform: translate3d(0px,-50px,0px) rotateX(90deg); } #f.block { background: #999; top: 100px; left: 100px; -webkit-transform: translate3d(0px,0px,-50px) rotatey(180deg); } .block:hover { background: #CCC !important; }