用代码做一个浪漫的“3D照片墙”

本文介绍了如何利用Python爬虫从某手获取图片素材,并结合HTML代码创建一个炫酷的3D旋转照片墙效果。通过拖动鼠标可实现照片墙的滚动,适合展示个人照片或作为礼物。代码包括图片下载和HTML布局,同时提供了音频播放功能。
摘要由CSDN通过智能技术生成

前言:

最近抖音上3D照片墙突然火了起来,一个动态的视频加上一个照片墙的弧形轮播,非常的炫酷。
抖音上的3D照片墙有的是用AE软件制作的,有的是通过软件生成的
那么今天就用代码做一个这种炫酷3D照片墙。         

  快来给你女朋友做一个吧~

  • 我们需要将自己女朋友照片或者女神照片素材放在img目录里,我这里没有素材,所以我用Python写了个脚本来提取某手的图集照片作为素材。
  • 打开浏览器开发者工具,定位到图片标签上,使用xpath表达式对标签进行匹配:
  • //img[@class="long-mode-item"]
    

可以看到匹配到了28个对象,这说明xpath表达式写的没问题,再把xpath表达式复制

在pycharm中编写代码进行图片素材的获取:

import requests,re
from lxml import etree

if __name__ == '__main__':
    url = input('输入快手图集链接:')
    url = re.findall("(https://\w.\w+.\w.\w/\w+)",url)[0]
    print(url)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36'
    }
    response = requests.get(url, headers=headers)
    html = response.text
    etr = etree.HTML(html)
    imgs = etr.xpath('//img[@class="long-mode-item"]/@src')
    for img in imgs:
        index = list(imgs).index(img) + 1
        req = requests.get(img)
        with open(f'img/{index}.webp', 'wb') as f:
            f.write(req.content)
        print(f'{index}.webp ---下载成功!')

运行代码,提取图片素材:

可以看到img目录已经下载好了图片素材

然后我们将img目录拷贝覆盖至hbuilder中的img目录即可。

 

如图所示,在项目中加入女朋友或女神照片:

然后就是html代码了,复制如下html代码:

index.html

<!DOCTYPE html>
<html lang="en" ondragstart="return false">

    <head>
        <meta charset="UTF-8">
        <meta name="Keywords" content="">
        <meta name="Description" content="">
        <title>3D旋转照片墙</title>
        <!-- 如果我有天醒来 -->
        <!-- 层叠样式表 -->
        <style type="text/css">
            /* 去掉默认效果 */
            * {
                margin: 0;
                padding: 0;
            }

            body {
                background: #222;
                overflow: hidden;
                /* 取消选中 */
                user-select: none;

            }

            @keyframes rotate {
                100% {
                    transform: rotateY(360deg);
                }
            }

            .perspective {
                /*子元素透视 场景深度*/
                perspective: 600px;
            }

            .wrap {
                /* 3d */
                width: 135px;
                height: 240px;
                margin: 100px auto;
                position: relative;
                /* border: 1px solid red; */
                transform: rotateX(-20deg) rotateY(0deg);
                transform-style: preserve-3d;

            }

            .wrap img {
                display: block;
                /* 绝对定位 */
                position: absolute;
                width: 100%;
                height: 100%;
                transform: rotateY(0deg) translateZ(0px);
                background: transparent;
                box-shadow: 0 0 4px #fff;
                border-radius: 5px;

                /* webkit */
            }

            /* 照片底座 */
            .wrap p {
                width: 1200px;
                height: 1200px;
                background: -webkit-radial-gradient(center center, 600px 600px, rgba(122, 122, 122, .5), rgba(0, 0, 0, 0));
                position: absolute;
                border-radius: 50%;
                left: 50%;
                top: 100%;
                margin-left: -600px;
                margin-top: -600px;
                /* 沿着x轴按倒 */
                transform: rotateX(90deg);

            }
        </style>
    </head>

    <body>
        <!-- 盒子容器 -->
        <div class="perspective">
            <div class="wrap" id="imgwrap">
                <!-- 引入图片值页面 -->
                <img class="f1" src="img/12.webp" />
                <img class="f1" src="img/13.webp" />
                <img class="f1" src="img/14.webp" />
                <img class="f1" src="img/15.webp" />
                <img class="f1" src="img/16.webp" />
                <img class="f1" src="img/1.webp" />
                <img class="f1" src="img/2.webp" />
                <img class="f1" src="img/3.webp" />
                <img class="f1" src="img/4.webp" />
                <img class="f1" src="img/5.webp" />
                <img class="f1" src="img/6.webp" />
                <img class="f1" src="img/7.webp" />
                <img class="f1" src="img/5.webp" />
                <img class="f1" src="img/6.webp" />
                <img class="f1" src="img/7.webp" />
                <img class="f1" src="img/8.webp" />
                <img class="f1" src="img/9.webp" />
                <img class="f1" src="img/10.webp" />
                <img class="f1" src="img/11.webp" />

                <img class="f1" src="img/17.webp" />
                <img class="f1" src="img/18.webp" />
                <img class="f1" src="img/19.webp" />
                <img class="f1" src="img/20.webp" />
                <img class="f1" src="img/21.webp" />
                <img class="f1" src="img/22.webp" />
                <img class="f1" src="img/23.webp" />
                <img class="f1" src="img/24.webp" />
                <img class="f1" src="img/25.webp" />
                <img class="f1" src="img/26.webp" />
                <img class="f1" src="img/27.webp" />
                <img class="f1" src="img/28.webp" />
                <img class="f1" src="img/29.webp" />
                <img class="f1" src="img/30.webp" />

                <!-- 引入图片值页面 -->
                <img class="f2" src="img/1.webp" />
                <img class="f2" src="img/2.webp" />
                <img class="f2" src="img/3.webp" />
                <img class="f2" src="img/4.webp" />
                <img class="f2" src="img/5.webp" />

                <img class="f2" src="img/9.webp" />
                <img class="f2" src="img/10.webp" />
                <img class="f2" src="img/11.webp" />
                <img class="f2" src="img/12.webp" />
                <img class="f2" src="img/25.webp" />
                <img class="f2" src="img/26.webp" />
                <img class="f2" src="img/27.webp" />
                <img class="f2" src="img/28.webp" />
                <img class="f2" src="img/29.webp" />
                <img class="f2" src="img/30.webp" />
                <img class="f2" src="img/13.webp" />
                <img class="f2" src="img/14.webp" />
                <img class="f2" src="img/15.webp" />
                <img class="f2" src="img/16.webp" />
                <img class="f2" src="img/17.webp" />
                <img class="f2" src="img/18.webp" />
                <img class="f2" src="img/19.webp" />
                <img class="f2" src="img/20.webp" />
                <img class="f2" src="img/21.webp" />
                <img class="f2" src="img/22.webp" />
                <img class="f2" src="img/23.webp" />
                <img class="f2" src="img/24.webp" />
                <img class="f2" src="img/6.webp" />
                <img class="f2" src="img/7.webp" />
                <img class="f2" src="img/5.webp" />
                <img class="f2" src="img/6.webp" />
                <img class="f2" src="img/7.webp" />
                <img class="f2" src="img/8.webp" />
                <!-- 引入图片值页面 -->

                <img class="f3" src="img/1.webp" />
                <img class="f3" src="img/2.webp" />
                <img class="f3" src="img/11.webp" />
                <img class="f3" src="img/12.webp" />
                <img class="f3" src="img/25.webp" />
                <img class="f3" src="img/26.webp" />
                <img class="f3" src="img/27.webp" />
                <img class="f3" src="img/3.webp" />
                <img class="f3" src="img/4.webp" />
                <img class="f3" src="img/5.webp" />


                <img class="f3" src="img/16.webp" />
                <img class="f3" src="img/17.webp" />
                <img class="f3" src="img/18.webp" />
                <img class="f3" src="img/10.webp" />

                <img class="f3" src="img/28.webp" />
                <img class="f3" src="img/29.webp" />
                <img class="f3" src="img/30.webp" />
                <img class="f3" src="img/13.webp" />

                <img class="f3" src="img/19.webp" />
                <img class="f3" src="img/20.webp" />
                <img class="f3" src="img/21.webp" />
                <img class="f3" src="img/22.webp" />
                <img class="f3" src="img/23.webp" />
                <img class="f3" src="img/24.webp" />
                <img class="f3" src="img/9.webp" />
                <img class="f3" src="img/14.webp" />
                <img class="f3" src="img/15.webp" />
                <img class="f3" src="img/6.webp" />
                <img class="f3" src="img/7.webp" />
                <img class="f3" src="img/5.webp" />
                <img class="f3" src="img/6.webp" />
                <img class="f3" src="img/7.webp" />
                <img class="f3" src="img/8.webp" />


                <p></p>
            </div>
        </div>
        <!--  src="JS/photo.js" -->
        <script type="text/javascript">
            let mp3 = 'audio/再见.mp3'
            let audio = new Audio(mp3)
            audio.autoplay
            audio.play()


            var oImg = document.getElementsByClassName('f1')
            var oImg2 = document.getElementsByClassName('f2')
            var oImg3 = document.getElementsByClassName('f3')
            var len = oImg.length;
            console.log(len)
            var deg = 360 / len;

            var oWrap = document.getElementById("imgwrap");
            // var oWrap=document.querySelector('.wrap');

            //页面加载完毕在执行的代码
            window.onload = function() {
                Array.prototype.forEach.call(oImg, function(ele, index, self) {
                    // 旋转并沿Z轴平移
                    ele.style.transform = "rotateY(" + deg * index + "deg) translateZ(645.75px)";
                    //过渡时间1s
                    ele.style.transition = "1s " + (len - index) * 0.1 + "s";

                });
                Array.prototype.forEach.call(oImg2, function(ele, index, self) {
                    // 旋转并沿Z轴平移
                    ele.style.transform = "rotateY(" + deg * index + "deg) translateZ(645.75px) translateY(240px)";
                    //过渡时间1s
                    ele.style.transition = "1s " + (len - index) * 0.1 + "s";

                });
                Array.prototype.forEach.call(oImg3, function(ele, index, self) {
                    // 旋转并沿Z轴平移
                    ele.style.transform = "rotateY(" + deg * index + "deg) translateZ(645.75px) translateY(480px)";
                    //过渡时间1s
                    ele.style.transition = "1s " + (len - index) * 0.1 + "s";

                });
                // Array.prototype.forEach.call(oImg, function (ele, index, self) {
                //       // 旋转并沿Z轴平移
                //       ele.style.transform = "rotateY(" + deg * index + "deg) translateZ(350px)";
                //       //过渡时间1s
                //       ele.style.transition = "1s " + (len - index) * 0.1 + "s";

                // });

            }
            //翻动3D相册
            var newX, newY, lastX, lastY, minusX, minusY, rotX = -20,
                rotY = 0;

            document.onmousedown = function(e) {
                // 点击设置初值
                lastX = e.clientX;
                lastY = e.clientY;

                this.onmousemove = function(e) {
                    newX = e.clientX;
                    newY = e.clientY;
                    minusX = newX - lastX;
                    minusY = newY - lastY;

                    rotX -= minusY * 0.2;
                    rotY += minusX * 0.1;
                    oWrap.style.transform = "rotateX(" + rotX + "deg) rotateY(" + rotY + "deg)";
                    lastX = newX;
                    lastY = newY;

                }
                this.onmouseup = function(e) {
                    //鼠标松开
                    this.onmousemove = null; //清除鼠标移动
                }
            }
        </script>
    </body>

</html>

注意事项 

  • 我这里播放了音频,项目中有音频文件,如果你没有会报异常
  •  如果你不想网页中播放音频,可以将如下代码删除或者注释。

这样一个炫酷的3D照片墙效果就有了,效果图如下:

 

ps:拖动鼠标可滚动照片墙哟~

获取更多实用技巧,请关注公众号:

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值