工具栏--旋转动画代码:
<!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>工具栏-旋转动画</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;
justify-content: space-between;
}
/* 设置背景图中左右按钮的大小 */
.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" style="width: 70px;margin-left: -35px;">开启AR</span>
<i></i>
<div class="tool-img">
<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 = "开启旋转";
}
}
</script>
</body>
</html>
工具栏-旋转动画效果:
原创作者:吴小糖
创作时间:2022.11.3