Created
May 29, 2013 10:05
-
-
Save linmic/5669280 to your computer and use it in GitHub Desktop.
A CodePen by linmic. CSS Panorama Viewer - Since chrome has some weird buggy issues on css 3d transform/transition, I would suggest use safari to enjoy this.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="pano_viewer"> | |
<div id="cube_box"> | |
<div id="cube"> | |
<img class="front" src="http://s.cdpn.io/19243/front.JPG" width="3000" height="3000"> | |
<img class="left" src="http://s.cdpn.io/19243/left.JPG" width="3000" height="3000"> | |
<img class="right" src="http://s.cdpn.io/19243/right.JPG" width="3000" height="3000"> | |
<img class="back" src="http://s.cdpn.io/19243/back.JPG" width="3000" height="3000"> | |
<img class="top" src="http://s.cdpn.io/19243/up.JPG" width="3000" height="3000"> | |
<img class="bottom" src="http://s.cdpn.io/19243/down.JPG" width="3000" height="3000"> | |
</div> | |
</div> | |
</div> | |
<section id="control_panel"> | |
<button id="btn_animation" class="animation">auto</button> | |
<button class="boundary">disable boundary</button> | |
</section> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
var x1, | |
y1, | |
moving = false, | |
$viewer = $('#pano_viewer'), | |
$cube = $('#cube'), | |
w_v = $viewer.width(), // width of viewer | |
h_v = $viewer.height(), // height of viewer | |
c_x_deg = 0, // current x | |
c_y_deg = 0, | |
perspective = 450; // current y | |
$viewer.on('mousedown', function(e) { | |
x1 = e.pageX - $(this).offset().left; | |
y1 = e.pageY - $(this).offset().top; | |
moving = true; | |
e.preventDefault(); | |
}); | |
$(document).on('mousemove', function(e) { | |
if( moving === true ) { | |
x2 = e.pageX - $viewer.offset().left; | |
y2 = e.pageY - $viewer.offset().top; | |
var dist_x = x2 - x1, | |
dist_y = y2 - y1, | |
perc_x = dist_x / w_v, | |
perc_y = dist_y / h_v, | |
deg_x = Math.atan2(dist_y, perspective) / Math.PI * 180, | |
deg_y = -Math.atan2(dist_x, perspective) / Math.PI * 180, | |
i, | |
vendors = ['-webkit-', '-moz-', '']; | |
c_x_deg += deg_x; | |
c_y_deg += deg_y; | |
c_x_deg = Math.min(90, c_x_deg); | |
c_x_deg = Math.max(-90, c_x_deg); | |
c_y_deg %= 360; | |
deg_x = c_x_deg; | |
deg_y = c_y_deg; | |
for(i in vendors) { | |
$cube.css(vendors[i] + 'transform', 'rotateX(' + deg_x + 'deg) rotateY(' + deg_y + 'deg)'); | |
} | |
x1 = x2; | |
y1 = y2; | |
} | |
e.preventDefault(); | |
}).on('mouseup', function(e) { | |
moving = false; | |
e.preventDefault(); | |
}); | |
$('#control_panel > button').on('click', function() { | |
$(this).toggleClass('active'); | |
}).parent() | |
.find('.animation').on('click', function() { | |
$('#cube').toggleClass('animate'); | |
}).parent() | |
.find('.boundary').on('click', function() { | |
$('#pano_viewer').toggleClass('no-boundary'); | |
}); | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import "compass"; | |
@import "compass/css3"; | |
$piece_radius: 3000px; | |
$overlap_offset: 2px; | |
$z_offset: $piece_radius / 2 - $overlap_offset; | |
$viewer_width: 700px; | |
$viewer_height: 400px; | |
$viewer_perspective: 750px; | |
// keyframes {{{ | |
@-webkit-keyframes roll { | |
0% { | |
-webkit-transform: rotateX(0) rotateY(0); | |
} | |
50% { | |
-webkit-transform: rotateX(0) rotateY(360deg); | |
} | |
100% { | |
-webkit-transform: rotateX(360deg) rotateY(360deg); | |
} | |
} | |
@-moz-keyframes roll { | |
0% { | |
-moz-transform: rotateX(0) rotateY(0); | |
} | |
50% { | |
-moz-transform: rotateX(0) rotateY(360deg); | |
} | |
100% { | |
-moz-transform: rotateX(360deg) rotateY(360deg); | |
} | |
} | |
@keyframes roll { | |
0% { | |
transform: rotateX(0) rotateY(0); | |
} | |
50% { | |
transform: rotateX(0) rotateY(360deg); | |
} | |
100% { | |
transform: rotateX(360deg) rotateY(360deg); | |
} | |
} | |
@-webkit-keyframes loading { | |
from { | |
-webkit-transform: rotate(0deg); | |
} | |
to { | |
-webkit-transform: rotate(360deg); | |
} | |
} | |
@-moz-keyframes loading { | |
from { | |
-moz-transform: rotate(0deg); | |
} | |
to { | |
-moz-transform: rotate(360deg); | |
} | |
} | |
@keyframes loading { | |
from { | |
transform: rotate(0deg); | |
} | |
to { | |
transform: rotate(360deg); | |
} | |
} | |
// }}} | |
html { | |
width: 100%; | |
height: 100%; | |
} | |
body { | |
min-width: $viewer_width + 40px; | |
font-family: Verdana, Sans-serif; | |
-webkit-font-smoothing: antialiased; | |
width: 100%; | |
height: 100%; | |
@include background-image(radial-gradient(ellipse, #666, #333 90%)); | |
} | |
#control_panel { | |
padding: 10px; | |
> button { | |
background: #7FB2F0; | |
display: inline-block; | |
color: white; | |
font: normal 18px/40px Verdana, Sans-serif; | |
text-align: center; | |
left: 10px; | |
top: 10px; | |
border: none; | |
padding: 0 20px; | |
cursor: pointer; | |
opacity: 0.8; | |
&:hover, | |
&.active { | |
opacity: 1; | |
} | |
} | |
} | |
#pano_viewer { | |
position: absolute; | |
width: $viewer_width; | |
height: $viewer_height; | |
left: 50%; | |
top: 50%; | |
margin-left: -1 * $viewer_width / 2; | |
margin-top: -1 * $viewer_height / 2; | |
cursor: move; | |
overflow: hidden; | |
&.no-boundary { | |
overflow: visible; | |
} | |
&.show { | |
outline: 1px solid #FFBE00; | |
overflow: visible; | |
} | |
&:focus { | |
cursor: move; | |
} | |
} | |
#cube_box { | |
@include perspective($viewer_perspective); | |
@include transform-origin($piece_radius $piece_radius 0); | |
@include transform-style(preserve-3d); | |
width: $piece_radius * 2; | |
height: $piece_radius * 2; | |
margin-left: ( $viewer_width - $piece_radius * 2 ) / 2; | |
margin-top: ( $viewer_height - $piece_radius * 2 ) / 2; | |
} | |
#cube { | |
@include transform-style(preserve-3d); | |
@include transform(rotate3d(0, 0, 0)); | |
cursor: move; | |
position: relative; | |
width: $piece_radius * 2; | |
height: $piece_radius * 2; | |
&.animate { | |
-webkit-animation: roll 30s linear infinite; | |
-moz-animation: roll 30s linear infinite; | |
animation: roll 30s linear infinite; | |
} | |
img { | |
position: absolute; | |
opacity: 1; | |
top: $piece_radius / 2; | |
left: $piece_radius / 2; | |
width: $piece_radius; | |
height: $piece_radius; | |
@include backface-visibility(hidden); | |
@include box-shadow(0px 0px 1px transparent); | |
} | |
} | |
img.front { | |
@include transform(translate3d(0, 0, -$z_offset)); | |
} | |
img.left { | |
@include transform(rotate3d(0, 1, 0, 90deg) translate3d(0, 0, -$z_offset)); | |
} | |
img.right { | |
@include transform(rotate3d(0, 1, 0, -90deg) translate3d(0, 0, -$z_offset)); | |
} | |
img.back { | |
@include transform(rotate3d(0, 1, 0, 180deg) translate3d(0, 0, -$z_offset)); | |
} | |
// depends on how we make the cut of panorama | |
img.top { | |
@include transform(rotateY(0deg) rotateX(-90deg) translate3d(0, 0, -$z_offset)); | |
} | |
img.bottom { | |
@include transform(rotate3d(1, 0, 0, 90deg) translate3d(0, 0, -$z_offset)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment