日期:2012-3-26 来源:GBin1.com
360度的全景图片效果常常可以用到给客户做产品展示,今天这里我们推荐一个非常不错的来自Robert Pataki的360全景幻灯实现教程,这里教程中将使用javascript来打造一个超酷的全景幻灯实现,相信大家一定会喜欢的!
在这个教程中没有使用到任何插件,我们将使用HTML,css和javascript来实现,当然,也使用是jQuery这个框架!
如何实现?
我们将使用预先按照360生成的图片进行轮播来实现动画展示效果。包含了180个图片。所以加载时间可能比较长。
代码实现
我们将在css代码中添加media queries,来使得这个效果可以同时在ipad和iphone上实现。
1. 代码文件
我们添加js,css,图片目录。css目录中包含了reset.css。js中包含了jQuery。代码文件如下:
2. 新的项目
创建一个HTML文件index.html。在<head>中我们设置了移动设备的viewport,使得内容不支持缩放。添加俩个文件
reset.css和threesixty.css。包含了自定义的css样式。
...
...
使用Javascript来创建一个响应式的超酷360度全景图片查看幻灯效果
日期:2012-3-26 来源:GBin1.com
360度的全景图片效果常常可以用到给客户做产品展示,今天这里我们推荐一个非常不错的来自Robert Pataki的360全景幻灯实现教程,这里教程中将使用javascript来打造一个超酷的全景幻灯实现,相信大家一定会喜欢的!
在这个教程中没有使用到任何插件,我们将使用HTML,css和javascript来实现,当然,也使用是jQuery这个框架!
如何实现?
我们将使用预先按照360生成的图片进行轮播来实现动画展示效果。包含了180个图片。所以加载时间可能比较长。
代码实现
我们将在css代码中添加media queries,来使得这个效果可以同时在ipad和iphone上实现。
1. 代码文件
我们添加js,css,图片目录。css目录中包含了reset.css。js中包含了jQuery。代码文件如下:
2. 新的项目
创建一个HTML文件index.html。在<head>中我们设置了移动设备的viewport,使得内容不支持缩放。添加俩个文件
reset.css和threesixty.css。包含了自定义的css样式。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" /> <title>360</title> <link rel="stylesheet" href="css/reset.css" media="screen" type="text/css" /> <link rel="stylesheet" href="css/threesixty.css" media="screen" type="text/css" /> </head> <body> </body> </html>
3. 加载进度条
创建一个<div>来容纳幻灯。其中包含一个<ol>,用来包含图片序列<li>,同时也包含了一个<span>来显示进度条。我们将使用javascript来动态加载图片。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" /> <title>360</title> <link rel="stylesheet" href="css/reset.css" media="screen" type="text/css" /> <link rel="stylesheet" href="css/threesixty.css" media="screen" type="text/css" /> </head> <body> <div id="threesixty"> <div id="spinner"> <span>0%</span> </div> <ol id="threesixty_images"></ol> </div> </body> </html>
4. 添加互动
代码最后,我们添加jQuery用来处理互动,threesixity.js用来处理图片幻灯。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" /> <title>360</title> <link rel="stylesheet" href="css/reset.css" media="screen" type="text/css" /> <link rel="stylesheet" href="css/threesixty.css" media="screen" type="text/css" /> </head> <body> <div id="threesixty"> <div id="spinner"> <span>0%</span> </div> <ol id="threesixty_images"></ol> </div> <script src="js/heartcode-canvasloader-min.js"></script> <script src="js/jquery-1.7.min.js"></script> <script src="js/threesixty.js"></script> </body> </html>
5. 样式
我们添加threesixty.css文件。reset.css用来设置缺省的样式。首先定义#threesixty包装。缺省的图片幻灯是960x450。水平垂直居中。
#threesixty { position:absolute; overflow:hidden; top:50%; left:50%; width:960px; height:540px; margin-left:-480px; margin-top:-270px; } #threesixty_images { display: none; }
6. 设置显示
为了幻灯针对不同的设备都能有完美显示。我们这里添加media queries。使用max-device-width和orientataion属性并且联合使用and操作。
@media screen and (max-device-width: 1024px) and (orientation:portrait) { #threesixty { width:720px; height:450px; margin-left:-360px; margin-top:-225px; } } @media screen and (max-device-width: 480px) and (orientation:landscape), screen and (-webkit-min-device-pixel-ratio: 2) and (orientation:landscape) { #threesixty { width:360px; height:225px; margin-left:-180px; margin-top:-113px; } } @media screen and (max-device-width: 480px) and (orientation:portrait), screen and (-webkit-min-device-pixel-ratio: 2) and (orientation:portrait) { #threesixty { width:320px; height:200px; margin-left:-160px; margin-top:-100px; } }
7. 图片
所有的图片都被存放在<ol>中。我们不希望都显示,所以定义current-image和previous-image来控制显示。
#threesixty img { position:absolute; top:0; width:100%; height:auto; } .current-image { visibility:visible; width:100%; } .previous-image { visibility:hidden; width:0; }
8. 预加载样式
#spinner { position:absolute; left:50%; top:50%; width:90px; height:90px; margin-left:-45px; margin-top:-50px; display:none; } #spinner span { position:absolute; top:50%; width:100%; color:#333; font:0.8em Arial, Verdana, sans; text-align:center; line-height:0.6em; margin-top:-0.3em; }
9. document准备处理
创建一个threesixty.js在js文件夹中。添加jQuery document ready方法。
拖放可以告诉我们用户是否使用pointer。 使用speedMultiplier我们可以设置图片幻灯速度。同时我们使用变量来保存pointer位置。timer将会跟踪pointer变化。我们定义变量来保存并且跟踪变化来计算图片加载。
$(document).ready(function () { var ready = false, dragging = false, pointerStartPosX = 0, pointerEndPosX = 0, pointerDistance = 0, monitorStartTime = 0, monitorInt = 10, ticker = 0, speedMultiplier = 10, spinner, totalFrames = 180, currentFrame = 0, frames = [], endFrame = 0, loadedImages = 0; });
10. Spinner
我们创建addSpinner方法来在#spinner中添加CanvasLoader实例。如下:
function addSpinner () { spinner = new CanvasLoader("spinner"); spinner.setShape("spiral"); spinner.setDiameter(90); spinner.setDensity(90); spinner.setRange(1); spinner.setSpeed(4); spinner.setColor("#333333"); spinner.show(); $("#spinner").fadeIn("slow"); };
11. 图片加载和帧数组
加载图片方法创建了包含<img>的<li>。 loadedimages变量生成图片名字,每次图片加载后自动添加,成功后,调用imageLoaded方法。
function loadImage() { var li = document.createElement("li"); var imageName = "img/threesixty_" + (loadedImages + 1) + ".jpg"; var image = $('<img>').attr('src', imageName).addClass("previous-image").appendTo(li); frames.push(image); $("#threesixty_images").append(li); $(image).load(function() { imageLoaded(); }); };
12. 图片过载
这里加载的图片太多,因此我们循环调用loadImage。图片加载处理将加载进度写到#spiner <span>。一旦加载完毕,我们将显示第一个张图片,并且加载进度条消失。
function imageLoaded() { loadedImages++; $("#spinner span").text(Math.floor(loadedImages / totalFrames * 100) + "%"); if (loadedImages == totalFrames) { frames[0].removeClass("previous-image").addClass("current-image"); $("#spinner").fadeOut("slow", function(){ spinner.hide(); showThreesixty(); }); } else { loadImage(); } };
13. 顺畅的过渡效果
使用showThreesixty方法来顺畅的显示图片幻灯过渡效果。
function imageLoaded() { loadedImages++; $("#spinner span").text(Math.floor(loadedImages / totalFrames * 100) + "%"); if (loadedImages == totalFrames) { frames[0].removeClass("previous-image").addClass("current-image"); $("#spinner").fadeOut("slow", function(){ spinner.hide(); showThreesixty(); }); } else { loadImage(); } }; function showThreesixty () { $("#threesixty_images").fadeIn("slow"); ready = true; }; addSpinner(); loadImage();
14. 帧数值
function render () { if(currentFrame !== endFrame) { var frameEasing = endFrame < currentFrame ? Math.floor((endFrame - currentFrame) * 0.1) : Math.ceil((endFrame - currentFrame) * 0.1); hidePreviousFrame(); currentFrame += frameEasing; showCurrentFrame(); } else { window.clearInterval(ticker); ticker = 0; } };
15. Ticker记数器
使用setInerval生成一个计数器。设置FPS为60。这样我们得到一个顺畅的效果
function refresh () { if (ticker === 0) { ticker = self.setInterval(render, Math.round(1000 / 60)); } };
16. 正常处理值
function hidePreviousFrame() { frames[getNormalizedCurrentFrame()].removeClass("current-image").addClass("previous-image"); }; function showCurrentFrame() { frames[getNormalizedCurrentFrame()].removeClass("previous-image").addClass("current-image"); }; function getNormalizedCurrentFrame() { var c = -Math.ceil(currentFrame % totalFrames); if (c < 0) c += (totalFrames - 1); return c; };
17. 测试
function showThreesixty () { $("#threesixty_images").fadeIn("slow"); ready = true; endFrame = -720; refresh(); };
18.用户互动
function getPointerEvent(event) { return event.originalEvent.targetTouches ? event.originalEvent.targetTouches[0] : event; }; $("#threesixty").mousedown(function (event) { event.preventDefault(); pointerStartPosX = getPointerEvent(event).pageX; dragging = true; }); $(document).mouseup(function (event){ event.preventDefault(); dragging = false; }); $(document).mousemove(function (event){ event.preventDefault(); trackPointer(event); });
19. 触摸操作
$("#threesixty").live("touchstart", function (event) { event.preventDefault(); pointerStartPosX = getPointerEvent(event).pageX; dragging = true; }); $("#threesixty").live("touchmove", function (event) { event.preventDefault(); trackPointer(event); }); $("#threesixty").live("touchend", function (event) { event.preventDefault(); dragging = false; });
20. 跟踪移动
function trackPointer(event) { if (ready && dragging) { pointerEndPosX = getPointerEvent(event).pageX; if(monitorStartTime < new Date().getTime() - monitorInt) { pointerDistance = pointerEndPosX - pointerStartPosX; endFrame = currentFrame + Math.ceil((totalFrames - 1) * speedMultiplier * (pointerDistance / $("#threesixty").width())); refresh(); monitorStartTime = new Date().getTime(); pointerStartPosX = getPointerEvent(event).pageX; } } };
21. 搞定,希望大家喜欢
via netmagazine.com