首页 > 代码库 > 关于3D Panorama(全景)
关于3D Panorama(全景)
蟹蟹 https://aotu.io/notes/2016/08/24/2016-8-24-css-3d-panorama/
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=640, target-densitydpi=device-dpi, user-scalable=no"> <title>全景</title> <link rel="stylesheet" href="http://jdc.jd.com/lab/zaowu/dist/css/reset.min.css"> <style> html, body { width: 100%; height: 100%; } body { background-size: cover; -webkit-user-select: none; user-select: none; padding-top: 150px; overflow: hidden; } #view{ width: 800px; height: 500px; overflow: hidden; margin: 0 auto; perspective: 420px; } #bigCube{ width: 6000px; height: 6000px; margin-left: -2600px; margin-top: -2750px; transform-origin: 3000px 3000px; transform-style: preserve-3d; } #cube{ width: 6000px; height: 6000px; position: relative; transform-style: preserve-3d; } .stage{ width: 6000px; height: 6000px; transform-style: preserve-3d; } .container { width: 800px; height: 500px; position: absolute; transform-style: preserve-3d; } .container>div { width: 100%; height: 100%; position: absolute; } </style> </head> <body> <div id="view"> <div id="bigCube"> <div id="cube"> <div class="stage"> <div class="container"> </div> </div> </div> </div> </div> <script src="http://jdc.jd.com/lab/zaowu/dist/js/jquery-3.1.0.min.js"></script> <!-- <script src="http://www.mamicode.com/dist/js/zepto.min.js"></script> --> <script> //禁用微信的下拉 $(‘body‘).on(‘touchmove‘, function(event) { event.preventDefault(); }); var BG_WIDTH = 3000, BG_HEIGHT = 3000, BG_NUMBER = 4, PER_ANGLE = 360 / BG_NUMBER; var translateZ = (function calTranslateZ(opts) { return Math.round(opts.width / (2 * Math.tan(Math.PI / opts.number))) })({ width: BG_WIDTH, number: BG_NUMBER }) console.log(translateZ); var view = $("#bigCube") viewW = view.width(), viewH = view.height(); var container = $(".container"), bgItem; for (var i = 0; i < BG_NUMBER; i++) { $("<div></div>").css({ "background": "url(http://jdc.jd.com/lab/zaowu/dist/images/panorama/"+ i +".jpg) 0 0/cover no-repeat", "position": "absolute", "width": BG_WIDTH, "height": BG_HEIGHT, "left": (viewW - BG_WIDTH) / 2, "top": (viewH - BG_HEIGHT) / 2, "transform": "rotateY(" + (180 - i * PER_ANGLE) + "deg) translateZ("+ (-translateZ +10 ) +"px)", // translateZ + 10 是为了去掉模模块间的缝隙 // "backface-visibility": "hidden" }).appendTo(".container") } for(var j = 0; j < 2; j++){ $("<div></div>").css({ "background": "url(http://jdc.jd.com/lab/zaowu/dist/images/panorama/"+ (j + 4) +".jpg) 0 0/cover no-repeat", "position": "absolute", "width": BG_WIDTH, "height": BG_HEIGHT, "left": (viewW - BG_WIDTH) / 2, "top": (viewH - BG_HEIGHT) / 2, "transform": "rotateX("+ (j ? 1: -1) * 90 +"deg) rotateZ(90deg) translateZ("+ (-translateZ+10) +"px)" // translateZ + 10 是为了去掉模模块间的缝隙 }).appendTo(".container") } bgItem = container.find(‘div‘) var lastMouseX = 0, lastMouseY = 0, curMouseX = 0, curMouseY = 0, lastAngleX = 0, lastAngleY = 0, angleX = 0, angleY = 0; var initTranZ = -150, tranZDistance = 0; var temZ = 0; var slastMouseX = 0; var frameTimer; var timeoutTimer; var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || function(callback) { setTimeout(callback, 1000 / 60) } $(document).on("mousedown touchstart", mouseDownHandler) $(document).on("mouseup touchend", mouseUpHandler) function mouseDownHandler(evt) { // 由于移动设备支持多指触摸,因此与PC的鼠标不同,返回是一数组touches。 lastMouseX = evt.pageX || evt.touches[0].pageX; lastMouseY = evt.pageY || evt.touches[0].pageY; lastAngleX = aimAngleX; lastAngleY = aimAngleY; curMouseX = evt.pageX || evt.touches[0].pageX; curMouseY = evt.pageY || evt.touches[0].pageY; slastMouseX = evt.pageX || evt.touches[0].pageX; clearTimeout(timeoutTimer) $(document).on("mousemove touchmove", mouseMoveHandler) window.cancelAnimationFrame(frameTimer) frameTimer = requestAnimationFrame(go) } function mouseMoveHandler(evt) { curMouseX = evt.pageX || evt.touches[0].pageX; curMouseY = evt.pageY || evt.touches[0].pageY; dragRotate({ pageX: curMouseX, pageY: curMouseY }); } function mouseUpHandler(evt) { // touchend 不具有坐标信息,因此需以touchmove的最后一次点提供 // http://stackoverflow.com/questions/17957593/how-to-capture-touchend-coordinates // curMouseX = evt.pageX || evt.touches[0].pageX; // curMouseY = evt.pageY || evt.touches[0].pageY; $(document).unbind("mousemove touchmove") timeoutTimer = setTimeout(function(){ window.cancelAnimationFrame(frameTimer) }, 2500) } var aimAngleX = 0,aimAngleY = 0; var curBgAngleX = 0, curBgAngleY = 0; var curItemAngleX = 0, curItemAngleY = 0; function dragRotate(evtInfo) { // 注意:rotateX(Y) 与 鼠标(触摸)的X(Y)轴是交叉对应的 // aimAngleX(Y)的值是通过【拖拽位移换算为相应角度得到】 aimAngleX = ( 180 / Math.PI * (Math.atan((curMouseX - lastMouseX) / translateZ)) + lastAngleX ) // console.log((180 / Math.PI * Math.atan((curMouseY - lastMouseY) / (Math.sqrt(Math.pow(panoBgItemH / 2, 2) + Math.pow(translateZ, 2))*1.5)) + lastAngleY), 30) // 限制上下旋转监督在30°以内 aimAngleY = Math.max(-60, Math.min((180 / Math.PI * Math.atan((curMouseY - lastMouseY) / (Math.sqrt(Math.pow(BG_HEIGHT / 2, 2) + Math.pow(translateZ, 2))*1.5)) + lastAngleY), 60)) } // loop function go() { // bg 与 item 的位移增量速度的不一致,可形成视差运动 curBgAngleX += (aimAngleX - curBgAngleX) * 0.5; curBgAngleY += (aimAngleY - curBgAngleY) * 0.5; $("#cube").css({ transform: "rotateX(" + (curBgAngleY) + "deg) rotateY(" + -curBgAngleX + "deg) rotateZ(0)" }) frameTimer = requestAnimationFrame(go); } </script> </body> </html>
关于3D Panorama(全景)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。