你们给自己写请柬?

效果

需求

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

实现

搭建结构

  • 搭建过程与上一篇时钟类似,这里不过多赘述。
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>
相关推荐
黄毛火烧雪下7 分钟前
React Native (RN)项目在web、Android和IOS上运行
android·前端·react native
fruge12 分钟前
前端正则表达式实战合集:表单验证与字符串处理高频场景
前端·正则表达式
baozj17 分钟前
🚀 手动改 500 个文件?不存在的!我用 AST 撸了个 Vue 国际化神器
前端·javascript·vue.js
用户40993225021226 分钟前
为什么Vue 3的计算属性能解决模板臃肿、性能优化和双向同步三大痛点?
前端·ai编程·trae
海云前端126 分钟前
Vue首屏加速秘籍 组件按需加载真能省一半时间
前端
蛋仔聊测试28 分钟前
Playwright 中route 方法模拟测试数据(Mocking)详解
前端·python·测试
零号机39 分钟前
使用TRAE 30分钟极速开发一款划词中英互译浏览器插件
前端·人工智能
molly cheung1 小时前
FetchAPI 请求流式数据 基本用法
javascript·fetch·请求取消·流式·流式数据·流式请求取消
疯狂踩坑人1 小时前
结合400行mini-react代码,图文解说React原理
前端·react.js·面试
Mintopia1 小时前
🚀 共绩算力:3分钟拥有自己的文生图AI服务-容器化部署 StableDiffusion1.5-WebUI 应用
前端·人工智能·aigc