你们给自己写请柬?

效果

需求

鼠标按下能翻开,右边小卡片能弹出,且带有阴影

实现

搭建结构

  • 搭建过程与上一篇时钟类似,这里不过多赘述。
xml 复制代码
<div class="book p3d">
        <!-- 右半本 -->
        <div class="book-cover p3d">
            <div class="page back flip"></div>
            <div class="page front p3d">
                <div class="shadow"></div>
                <div class="pic"></div>
            </div>
        </div>
        <!-- 左半本 -->
        <div class="front-cover p3d">
            <div class="page front flip p3d">
                <p>
                    亲爱的丁社长和铁锤:

                    恭喜你们迎来人生新的旅程,结婚是爱情的圆满,是幸福的开始。愿你们携手共度人生的每一刻,相互扶持,相互理解,相互包容。

                    在这个特别的日子里,愿你们的爱情如同新婚的阳光一样灿烂,如同甜蜜的蜜蜂一样温暖。愿你们的爱情,如同永恒的星辰,照耀着彼此的人生。

                    愿你们的婚姻充满欢笑与快乐,百年好合,幸福美满!

                    祝福语:
                    丁社长和铁锤,祝你们于2024年5月1日结婚纪念日快乐!

                    祝福你们永结同心,白头偕老!
                </p>
            </div>
            <!-- 外壳 -->
            <div class="page back"></div>
        </div>
    </div>

css

  • background: linear-gradient(to bottom, #444, #999);背景色调成渐变
  • 除了上一篇讲的translate平移的方式,我们还可以通过margin-left: -150px;调整外边距的方式往回走半个身位,确保位置居中
  • cursor: pointer;小手点击图标
  • user-select: none;禁止用户选中
  • transform: rotateX(60deg);饶X轴旋转
  • text-indent: 2em;缩进两个字符
  • transform-origin: 0 50%;调整坐标起始位置
  • transform-style: preserve-3d;设置元素的子元素是位于 3D 空间中还是平面中。
css 复制代码
* {
    margin: 0;
    padding: 0;
    border: 0;
    box-sizing: border-box;
}

html {
    height: 100%;
}

body {
    height: 100%;
    font: 100%/1.25 Helvetica, arial, helvetica;
    color: #fff;
    perspective: 1000px;
    background: linear-gradient(to bottom, #444, #999);
}

.book {
    width: 300px;
    height: 300px;
    position: absolute;
    left: 50%;
    margin-left: -150px;
    top: 50%;
    margin-top: -150px;
    cursor: pointer;
    user-select: none;
    transform: rotateX(60deg);
}

.page {
    width: 300px;
    height: 300px;
    padding: 1em;
    position: absolute;
    left: 0;
    top: 0;
    text-indent: 2em;
}

.front {
    background-color: #d93e2b;

}

.back {
    background-color: #fff;

}

.front-cover {
    transform-origin: 0 50%;
    transform: rotateY(0deg);

}

.p3d {
    transform-style: preserve-3d;
}

.front-cover .back {
    background-image: url(https://img2.baidu.com/it/u=2368431681,4265369131&fm=253&fmt=auto&app=138&f=JPEG?w=595&h=500);
    background-size: cover;
    transform: translateZ(3px);
}

.flip {
    transform: rotateY(180deg);
}

.shadow,
.pic {
    width: 196px;
    height: 132px;
    position: absolute;
    left: 60px;
    top: 60px;
    transform-origin: 0 100%;
}

.pic {
    background: url(https://q4.itc.cn/q_70/images03/20240405/39ec09deda3a41d79e03897b0fdf68a0.jpeg);
    background-size: cover;
}

.shadow {
    background-color: rgba(0, 0, 0, 0.5);
}

JS

  • document.querySelector类名方式获取元素
  • var hold = false提前设置好标记,后续鼠标点住外壳移动时需要改变状态
  • var clamp = function (val, min, max) { return Math.max(min, Math.min(val, max)) }自己设计一个大概的鼠标拉动时请柬翻转角度
  • 计算好角度后frontCover.style.transform = rotateY(${angle}deg)`js更改css样式
  • 以此类推另外的阴影和pic元素
xml 复制代码
<script>
        var hold = false
        var frontCover = document.querySelector('.front-cover')
        var shadow = document.querySelector('.shadow')
        var pic = document.querySelector('.pic')
        var clamp = function (val, min, max) {
            return Math.max(min, Math.min(val, max))
        }
        //鼠标摁住事件
        //摁住为ture
        frontCover.onmousedown = function () {
            hold = true
        }
        //摁住为false
        window.onmouseup = function () {
            hold = false
        }
        //鼠标移动事件
        window.onmousemove = function (e) {
            //摁住才能执行
            if (hold == true) {
                var angle = clamp((window.innerWidth / 2 - e.pageX + 300) / 300 * -90, -180, 0)

                frontCover.style.transform = `rotateY(${angle}deg)`
                //pic 要立起来 绕x轴旋转(angle/2)
                pic.style.transform = `rotateX(${angle / 2}deg)`
                //shadow 要沿x轴倾斜(angle/8)
                shadow.style.transform = `skewX(${angle / 8}deg)`
            }

        }
    </script>
相关推荐
程序员黑豆6 分钟前
鸿蒙应用开发中的单位详解:px、vp、fp、lpx
前端·harmonyos
像我这样帅的人丶你还35 分钟前
MCP + npm:给五年前的老系统接上AI
前端·javascript·agent
南一Nanyi41 分钟前
依赖注入和控制反转
前端·设计模式·nestjs
小村儿41 分钟前
连载14-实战篇--一个半月,我一个人和 Claude Code 搭出一套数字人工程
前端·后端·ai编程
愚公移码1 小时前
蓝凌EKP18产品:流程虚拟机(PVM)
java·开发语言·前端
promiseThen1 小时前
5 分钟上手 Markdown:标题到表格、代码块与简历实战
前端
web66liang1 小时前
webpack4+vue2项目使用 sass-embedded 导致的 DockerfIle 构建失败的问题
前端
Strayer1 小时前
拓扑管网 3D 可视化大屏demo:科技感(地图 + 拓扑 + 3D 空间)
前端·three.js·数据可视化
葬送的代码人生1 小时前
从 Vue 到 React:Tailwind CSS 布局 + BFF 代理实战
前端·react.js·架构
摸鱼老王不带81 小时前
不用后端,纯前端读出"网站眼里你的真实出口 IP"——聊聊 Cloudflare 的 cdn-cgi/trace
前端