css3+js实现旋转木马视图切换(3d相册)

218 阅读3分钟

效果图

微信截图_20231019024238.png 点击按钮,实现图片和对应文案的切换

需要用到的属性和方法:

图片显示区:

  • position: relative;//相对定位

  • perspective:1000px;//CSS3景深

  • transform-style: preserve-3d;//实现3d效果

  • transition: transform 2s;//实现动画效果

  • box-shadow: 0px 0px 1px #fff;//配合transform-style: preserve-3d;可以忽略层级问题

  • transform:rotateX(0deg) rotateY(360/n deg) rotateZ(350px);设置图片位置:x轴方向不变,y轴方向每张分别相差的度数=360/图片数量,沿z轴平移350px(即设置圆的半径,需大于200*9/2Π=286px)

文案区:

  • display: flex;//弹性布局,以便设置水平、垂直居中
  • display:none;//隐藏元素
  • display:block;//显示元素
  • %:取余,大于0则选择该余数的文案;小于0则余数+总数

代码

html代码

图片换成本地图片路径即可

        <div id="contain">
            <img class="img" src="./img/1.jpg" /> 
            <img class="img" src="./img/2.jpg" /> 
            <img class="img" src="./img/3.jpg" /> 
            <img class="img" src="./img/4.jpg" /> 
            <img class="img" src="./img/5.jpg" /> 
            <img class="img" src="./img/6.jpg" /> 
            <img class="img" src="./img/7.jpg" /> 
            <img class="img" src="./img/8.jpg" /> 
            <img class="img" src="./img/9.jpg" /> 
       </div>
    </div>
    <div class="btnAndarea">
        <button id="previous">上一张</button>
        <div class="area">
            <!-- 预设置只显示一个文案,其他文案先隐藏 -->
            <p class="area_p">
                2010.9-2014.6<br>
                重庆工商大学设计专业学习</br>
                全日制
            </p>
            <p class="area_p" style="display: none;">
                2012.10-2015.10<br>
                NED设计工作室</br>
                在职
            </p>
            <p class="area_p" style="display: none;">
                2015.11-2016.2<br>
                燃烧吧少年</br>
                选秀
            </p>
            <p class="area_p" style="display: none;">
                2016.4-2014.6<br>
                超星星学园</br>
                网剧
            </p>
            <p class="area_p" style="display: none;">
                2017.9-2017.11<br>
                《哦!我的皇帝陛下》</br>
                古装奇幻剧
            </p>
            <p class="area_p" style="display: none;">
                2018.4-2018.8<br>
                《陈情令》</br>
                古装仙侠剧
            </p>
            <p class="area_p" style="display: none;">
                2018.9-2019.1<br>
                《诛仙》</br>
                仙侠电影
            </p>
            <p class="area_p" style="display: none;">
                2020.1-2020.1<br>
                《喜欢你,喜欢我》</br>
                春晚小品
            </p>
            <p class="area_p" style="display: none;">
                2021.4-2023.5<br>
                《如梦之梦》</br>
                话剧
            </p>
        </div>
        <button id="next">下一张</button>
    </div>

css代码

            margin: 0;
            padding: 0;
        }
        #view{
            /* 场景景深 产生空间上的距离/延伸感 */
            perspective: 1000px;
        }
        #contain {
            position: relative;
            margin: 100px auto;
            width: 200px;
            height: 200px;
            /* 实现3d效果 */
            transform-style: preserve-3d;
            /* 实现动画效果 */
            transition: transform 2s;
            /* 设置水平倾斜角度 */
            transform: rotateX(-15deg) rotateY(0deg) ;
        }
        #contain img {
            position: absolute;
            width: 200px;
            height: 200px;
            /* 用box-shadow配合transform-style: preserve-3d;可以忽略层级问题 */
            box-shadow: 0px 0px 1px #fff;
        }
        
        .btnAndarea {
            margin-inline: auto;
            margin-top: 180px;
            width: 600px;
            height: 150px;
            display: flex;
            justify-content: center;
            align-items: center;
            text-align: center;
        }
        .btnAndarea  .area{
            width: 300px;
            height: 70px;
            font: 20px 'FangSong';
            color: #52b193 ;
            font-weight: 700;
        }
        #previous,
        #next {
            width: 80px;
            height: 40px;
            font-size: 16px;
            background: #7dcdb4;
            border: 0;
        }

js代码

     // window.onload() 方法用于在网页加载完毕后立刻执行的操作,即当 HTML 文档加载完毕后,立刻执行某个方法。
     window.onload = function(){
            var contain = document.getElementById("contain");
            var imgs = document.getElementsByTagName('img');
            var l = imgs.length;
            var Deg = 360/l;
            
            // 点击按钮时,图片和文字皆发生改变
            var contents = document.getElementsByClassName('area_p');
            var previous = document.getElementById("previous");
            var next = document.getElementById("next");
            var n = 0,
            total = 0;

            // prototype:它是一个给类的对象添加方法的方法
            // Array.prototype 属性表示 Array 构造函数的原型,并允许我们向所有Array对象添加新的属性和方法。
            // call():调用一个对象的一个方法,以另一个对象替换当前对象。
            Array.prototype.forEach.call(imgs,function(el,index){
                // 设置每张图片的位置:x轴方向不变,y轴方向分别相差Deg角度,同时沿z轴平移350px(需大于200*9/2Π=286px)
                el.style.transform = 'rotateX(-15deg)'+'rotateY(' +Deg*index + 'deg) translateZ(350px)';
            })

            // 按钮点击事件
            next.addEventListener(
            "click",
            function () {
                n++;
                total = n * Deg;
                contain.style.transform = "rotateY(" + -total + "deg)" ;
                // 先隐藏文案区域所有文案
                for(var i = 0; i < contents.length; i++){
                contents[i].style.display = "none";
                }
                // 找到与图片对应的文案的容器
                // %:取余,大于0则选择该余数的文案;小于0则余数+总数
                var m = n%l>=0 ? n%l : n%l+l;
                // 显示该文案
                contents[m].style.display = 'block'
            },
            false
            );
            previous.addEventListener(
            "click",
            function () {
                n--;
                total = n * Deg;
                contain.style.transform = 'rotateX(-15deg)'+"rotateY(" + -total + "deg)";
                for(var i = 0; i < contents.length; i++){
                contents[i].style.display = "none";
                }
                var m = n%l>=0 ? n%l : n%l+l;
                contents[m].style.display = 'block'
            },
            false
            );
        }