工具栏-AR效果代码展示:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"> <title>工具栏-AR效果</title> <script src="./js/three.js"></script> <script src="./js/OBJLoader.js"></script> <script src="./js/OrbitControls.js"></script> <style> /* 初始化页面 */ * { margin: 0; padding: 0; box-sizing: border-box; } /* 设置渲染容器的大小 */ #webgl { width: 100%; height: 100vh; overflow: hidden; } /* 设置最大元素宽高 */ .content{ width: 100%; height: 100vh; position: relative; } /* 将工具栏定位到页面右下角 */ .tool{ position: absolute; bottom: 0; right: 0; margin-right: 20px; display: flex; user-select: none; } /* 设置每一个块的大小 */ .tool-item{ width: 35px; height: 35px; padding: 5px; position: relative; } /* 设置小图标黑色背景 */ .tool-img{ display: flex; justify-content: center; align-items: center; width: 25px; height: 25px; border-radius: 100%; background-color: rgba(0,0,0,0.8); } /* 设置小图标大小 */ .tool-img img{ width: 13px; height: 13px; } /* 设置小图标的提示文本 */ .tool-text{ display: block; line-height: 20px; padding: 6px 0px; border-radius: 5px; background-color: #000000; font-size: 12px; text-align: center; color: #FFFFFF; position: absolute; bottom: 40px; left: 50%; display: none; } /* 设置提示文本下边的小三角 */ .tool-item i{ display: none; width: 10px; height: 10px; background-color: #000000; position: absolute; bottom: 36px; left: 50%; margin-left: -5px; transform: rotate(45deg); } /* 鼠标放到每一块上显示提示文本 */ .tool-item:hover .tool-text{ display: block; } /* 鼠标放到每一块上显示小三角 */ .tool-item:hover i{ display: block; } /* 设置查看弹窗大小和位置 */ .popout{ width: 160px; position: absolute; bottom: 40px; background-color: #000000; padding: 6px 0; border-radius: 10px; font-size: 12px; color: #FFFFFF; right: -30px; z-index: 100; } /* 设置查看弹窗下边的小三角 */ .popout-arrow{ display: block; width: 10px; height: 10px; background-color: #000000; position: absolute; bottom: 36px; left: 50%; margin-left: -5px; transform: rotate(45deg); } /* 设置弹窗中每行的大小 */ .popout p{ width: 90%; height: 30px; margin-left: 5%; display: flex; justify-content: space-between; line-height: 30px; } /* 设置弹窗中每行箭头的大小 */ .popout>p img{ width: 12px; height: 12px; margin: 9px 0px; } /* 设置弹窗中的分界线 */ .popout em{ display: block; width: 100%; height: 1px; background-color: #525252; } /* 设置弹窗中背景图的那一行 */ .popout-list{ width: 90%; height: 30px; margin-left: 5%; padding: 5px 0; display: flex; } /* 设置背景图中左右按钮的大小 */ .popout-list>img{ width: 14px; height: 14px; margin: 3px; } /* 设置背景图列表 */ .popout-pic{ display: flex; justify-content: space-between; width: calc(100% - 40px); } /* 设置背景图大小 */ .popout-pic img{ width: 20px; height: 20px; } </style> </head> <body> <div class="content"> <!-- 渲染容器 --> <div id="webgl"></div> <!-- 工具栏 --> <div class="tool"> <div class="tool-item"> <span class="tool-text" id="rotate-text" style="width: 70px;margin-left: -35px;">开启旋转</span> <i></i> <div class="tool-img" onclick="rotates()"> <img src="./img/旋转.png" alt=""> </div> </div> <div class="tool-item"> <span class="tool-text" id="AR-text" style="width: 70px;margin-left: -35px;">开启AR</span> <i></i> <div class="tool-img" onclick="ARs()"> <img src="./img/AR.png" alt=""> </div> </div> <div class="tool-item"> <span class="tool-text" style="width: 50px;margin-left: -25px;">帮助</span> <i></i> <div class="tool-img"> <img src="./img/帮助.png" alt=""> </div> </div> <div class="tool-item"> <span class="tool-text" style="width: 70px;margin-left: -35px;">查看方式</span> <i></i> <div onclick="look()" class="tool-img"> <img src="./img/查看.png" alt=""> </div> <!-- 查看弹窗 --> <div class="popout" style="display: none;"> <p onclick="unfold(event)"><span>展示模式</span><img src="img/展开.png" alt=""></p> <p style="padding-left: 10px;display: none;"><span>允许缩放</span><img src="./img/对.png" alt=""></p> <em></em> <p onclick="unfold(event)"><span>背景切换</span><img src="./img/展开.png" alt=""></p> <div class="popout-list" style="display: none;"> <img onclick="picLeft()" src="./img/左箭头.png" alt=""> <div class="popout-pic"> <img src="./img/pic1.jpg" > <img src="./img/pic2.webp" > <img src="./img/pic3.webp" > <img src="./img/pic4.webp" > </div> <img onclick="picRight()" src="./img/右箭头.png" alt=""> </div> </div> <b class="popout-arrow" style="display: none;"></b> </div> <div class="tool-item"> <span class="tool-text" style="width: 70px;margin-left: -35px;">开启VR</span> <i></i> <div class="tool-img"> <img src="./img/VR.png" alt=""> </div> </div> <div class="tool-item"> <span class="tool-text" style="width: 70px;margin-left: -35px;">开启全屏</span> <i></i> <div class="tool-img"> <img src="./img/全屏.png" alt=""> </div> </div> </div> </div> <script> // 获取渲染容器 let webgl = document.getElementById("webgl"); // 获取渲染容器的宽高 let webglWidth = webgl.offsetWidth; let webglHeight = webgl.offsetHeight; // 创建场景 let scene = new THREE.Scene(); // 设置环境光(十六进制颜色) let ambient = new THREE.AmbientLight(0x444444); // 将环境光添加到场景中 scene.add(ambient); // 设置点光源(十六进制颜色) let point = new THREE.PointLight(0xffffff); // 设置点光源的位置(x轴, y轴, z轴) point.position.set(400, 200, 300); // 将点光源添加到场景中 scene.add(point); // 创建透视相机(角度, 宽高比, 最近距离, 最远距离) let camera = new THREE.PerspectiveCamera(60,webglWidth/webglHeight,0.1,2000); // 设置相机的位置(x轴, y轴, z轴) camera.position.set(100, 100, 100); // 将相机指向场景中心 camera.lookAt(scene.position); // 创建渲染器 let renderer = new THREE.WebGLRenderer(); // 设置渲染器的初始颜色(十六进制颜色, 透明度) renderer.setClearColor(0xEEEEEE,1); // 设置渲染器大小(标签宽度, 标签高度) renderer.setSize(webglWidth,webglHeight); // 将渲染器添加到渲染容器中(渲染器元素) webgl.appendChild(renderer.domElement); // 创建旋转状态 let rotateStatus = false; // 创建渲染函数 function render(){ // 渲染场景和相机(场景, 相机) renderer.render(scene,camera); // 判断旋转状态为 ture 则执行 if(rotateStatus){ // 设置场景旋转速度 scene.rotation.y += 0.002; } // 重复执行渲染函数 requestAnimationFrame(render); } // 调用渲染函数 render(); // 设置窗口变化自适应调整事件 window.onresize = function(){ // 重新获取渲染容器的宽高 webglWidth = webgl.offsetWidth; webglHeight = webgl.offsetHeight; // 重置渲染器canvas画布大小 renderer.setSize(webglWidth,webglHeight); // 重置相机显示范围的宽高比 camera.aspect = webglWidth/webglHeight; // 更新相机的投影矩阵 camera.updateProjectionMatrix(); // 重新调用渲染函数 render(); }; // 创建 OBJ 模型加载器 let loader = new THREE.OBJLoader(); // 加载 OBJ 文件 loader.load('./img/鹤.OBJ', function(obj) { // 加载纹理贴图 let texture = new THREE.TextureLoader().load('./img/he.png',function(){ render(); // 加载成功后重新调用渲染函数 }); // 给 OBJ 模型设置纹理贴图 obj.children[0].material = new THREE.MeshBasicMaterial({ map: texture }); // 将 OBJ 模型添加到场景中 scene.add(obj); // 设置 OBJ 模型居中 obj.children[0].geometry.center(); // 设置 OBJ 模型缩放大小 obj.children[0].scale.set(100, 100, 100); }) // 鼠标操作三维场景 let controls = new THREE.OrbitControls(camera,renderer.domElement); // 查看弹窗显示隐藏事件 function look(){ // 获取查看弹窗 let popout = document.getElementsByClassName("popout")[0]; // 获取查看弹窗下边的小三角 let arrow = document.getElementsByClassName("popout-arrow")[0]; // 判断弹窗是否隐藏 if(popout.style.display == "none"){ // 如果隐藏,显示弹窗和小三角 popout.style.display = "block"; arrow.style.display = "block"; }else{ // 如果显示,则隐藏弹窗和小三角 popout.style.display = "none"; arrow.style.display = "none"; } } // 查看弹窗功能展开事件 function unfold(e){ // 获取事件目标对象 e = e || window.event; let targets = e.target || e.srcElement; // 创建变量用于存储下一个同级元素 let nexts; // 创建变量用于存储当前 p 标签内的 img 标签 let pImg; // 当前目标元素是否为 p 标签 if(targets.nodeName == "P"){ // 如果为p标签,存储当前目标元素的下一个同级元素 nexts = targets.nextElementSibling; // 存储当前 p 标签内的 img 标签 pImg = targets.getElementsByTagName("img")[0]; }else{ // 如果不是p标签,存储当前目标元素的父元素的下一个同级元素 nexts = targets.parentElement.nextElementSibling; // 存储当前目标元素的父元素内的 img 标签 pImg = targets.parentElement.getElementsByTagName("img")[0]; } // 判断下一个同级元素是否隐藏 if(nexts.style.display == "none"){ // 如果隐藏则显示 nexts.style.display = "flex"; // 设置小图标箭头朝下 pImg.style.transform = "rotate(90deg)"; }else{ // 如果显示则隐藏 nexts.style.display = "none"; // 设置小图标箭头朝右 pImg.style.transform = "rotate(0deg)"; } } // 模拟背景图片数据 let arr = [ "./img/pic1.jpg", "./img/pic2.webp", "./img/pic3.webp", "./img/pic4.webp", "./img/pic5.jpg" ]; // 输出背景图数据 // 创建起始值,表示从第几张图片开始输出 let begin = 0; // 创建结束值,表示到第几张图片输出结束 // 并且判断图片数量是否大于等于4,如果大于设置为 4,否则设置为图片的数量 let record = arr.length >= 4 ? 4 : arr.length; // 创建背景图渲染函数 function picRender(){ // 创建变量,存储拼接的字符串 let picStr = ""; // 循环拼接数据,从 begin 开始,到 record 结束 for(let i = begin; i < record; i++){ picStr += `<img src="${arr[i]}" >`; } // 向页面输出数据 document.getElementsByClassName("popout-pic")[0].innerHTML = picStr; } // 调用背景图渲染函数 picRender(); // 背景图切换-左按钮事件 function picLeft(){ // 判断起始值是否大于 0 if(begin > 0){ // 如果大于 0 让 起始值 和 结束值 都减一 record--; begin--; // 重新调用背景图渲染函数 picRender(); } } // 背景图切换-右按钮事件 function picRight(){ // 判断图片数量减起始值是否大于 4 if(arr.length - begin > 4){ // 如果大于 4 让 起始值 和 结束值 都加一 record++; begin++; // 重新调用背景图渲染函数 picRender(); } } // 创建模型旋转点击事件 function rotates(){ // 获取旋转提问文本 let rotateText = document.getElementById("rotate-text"); // 取反旋转状态 rotateStatus = !rotateStatus; // 判断旋转状态是否为 true if(rotateStatus){ // 如果为 true,设置提示文本为停止旋转 rotateText.innerHTML = "停止旋转"; }else{ // 如果为 false,设置提示文本为开启旋转 rotateText.innerHTML = "开启旋转"; } } // 创建 AR 状态 let ARStatus = false; // 创建 AR 开关事件 function ARs(){ // 获取 AR 提示文本 let ARText = document.getElementById("AR-text"); // 取反 AR 状态 ARStatus = !ARStatus; // 判断 AR 状态是否为 true if(ARStatus){ // 如果为 true 设置渲染器背景色为黑色 renderer.setClearColor(0x000000,1); // 设置提示文本为关闭AR ARText.innerHTML = "关闭AR"; }else{ // 否则设置渲染器背景色为灰色 renderer.setClearColor(0xEEEEEE,1); // 设置提示文本为开启AR ARText.innerHTML = "开启AR"; } } </script> </body> </html>
工具栏-AR展示效果:
原创作者:吴小糖
创作时间:2022.11.6