首页 教程 Web前端 前端练习小项目——包变脸的,老弟 !

前端练习小项目——包变脸的,老弟 !

前言:在学习完HTML、CSS、JavaScript之后,我们就可以开始做一些小项目了,本篇文章所讲的小项目为——包变脸的,老弟。

前端练习小项目——包变脸的,老弟 !

✨✨✨这里是秋刀鱼不做梦的BLOG

✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客

先让我们看一下效果:

前端练习小项目——包变脸的,老弟 !

那么我们如何去实现这样的小案例呢?在下文中我们对每一段重要的代码都进行了解释,读者可以根据注释对代码进行理解。

1.骨架 —— HTML代码

HTML代码:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>秋刀鱼不做梦</title> <!-- 引入外部样式表 --> <link rel="stylesheet" href="./表情.css"> </head> <body> <!-- 表情图标的列表 --> <ul id="emoji"> <!-- 第一层,深度为0.2 --> <li class="layer" data-depth="0.2"> <!-- 面部 --> <div class="face"></div> </li> <!-- 第二层,深度为0.3 --> <li class="layer" data-depth="0.3"> <!-- 光泽 --> <div class="shine"></div> </li> <!-- 第三层,深度为0.8 --> <li class="layer" data-depth="0.8"> <!-- 左眼 --> <div class="eye left"></div> </li> <!-- 第三层,深度为0.8 --> <li class="layer" data-depth="0.8"> <!-- 右眼 --> <div class="eye right"></div> </li> <!-- 第三层,深度为0.8 --> <li class="layer" data-depth="0.8"> <!-- 嘴巴 --> <div class="mouth"></div> </li> </ul> </body> </html>

 当然,当我们搭建好HTML骨架之后,我们现在还是看不到任何的结果的,接下来然我们对其进行修饰。

2.修饰 —— CSS代码

CSS代码:

:root { --shine: rgb(251, 136, 200); /* 定义自定义属性:光泽颜色 */ --primary-color: rgb(248, 175, 40); /* 定义自定义属性:主色 */ --secondary-color: rgb(230, 63, 2); /* 定义自定义属性:次色 */ --accent-color: rgb(58, 25, 25); /* 定义自定义属性:强调色 */ --black-fade: rgb(120, 40, 6); /* 定义自定义属性:淡化的黑色 */ --dark-blue: rgb(84, 84, 174); /* 定义自定义属性:深蓝色 */ } * { padding: 0; /* 重置所有元素的内边距为0 */ margin: 0; /* 重置所有元素的外边距为0 */ list-style: none; /* 去掉列表项的默认样式 */ } body { display: flex; /* 采用flex布局 */ align-items: center; /* 垂直方向居中 */ justify-content: center; /* 水平方向居中 */ height: 100vh; /* 高度设为视口高度 */ overflow: hidden; /* 隐藏超出视口的内容 */ background-color: #9197f1; /* 设置背景颜色为淡紫色 */ } #emoji { position: relative; /* 相对定位 */ width: 450px; /* 宽度设为450像素 */ height: 400px; /* 高度设为400像素 */ transform: translate3d(0, 0, 0); /* 启用3D转换,保持默认值 */ } .layer { position: absolute; /* 绝对定位 */ width: 100%; /* 宽度设为父元素的100% */ height: 100%; /* 高度设为父元素的100% */ } .face { position: absolute; /* 绝对定位 */ top: 0; right: 0; bottom: 0; left: 0; /* 四边都设为0以居中 */ margin: auto; /* 自动计算外边距,以保证居中 */ width: 230px; /* 宽度设为230像素 */ height: 230px; /* 高度设为230像素 */ background-color: #FECA32; /* 设置背景颜色为黄色 */ border-radius: 100%; /* 圆形边框 */ box-shadow: inset rgba(0, 0, 0, 0.4) 0 0 30px; /* 内部投影,制造深度感 */ transition: .3s; /* 设置过渡效果时间为0.3秒 */ } .shine { position: absolute; /* 绝对定位 */ top: 0; right: 0; bottom: 0; left: 0; /* 四边都设为0以居中 */ margin: auto; /* 自动计算外边距,以保证居中 */ width: 194px; /* 宽度设为194像素 */ height: 206px; /* 高度设为206像素 */ background: linear-gradient(to bottom, #FFFFFF, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0)); /* 设置线性渐变背景 */ border-radius: 100%; /* 圆形边框 */ opacity: 0.8; /* 设置不透明度为0.8 */ } .eye { width: 24px; /* 眼睛的宽度 */ height: 38px; /* 眼睛的高度 */ background-color: #A1620F; /* 眼睛的背景颜色 */ border-radius: 100%; /* 圆形边框 */ box-shadow: inset rgba(0, 0, 0, 0.5) 0 6px 12px, rgba(255, 255, 255, 0.2) 0 2px 0 2px; /* 内部和外部的阴影 */ transition: .3s; /* 过渡效果时间为0.3秒 */ } .eye.left { position: absolute; /* 绝对定位 */ top: 0; right: 70px; bottom: 40px; left: 0; /* 通过设置边距实现眼睛的位置 */ margin: auto; /* 自动计算外边距,以保证居中 */ } .eye.right { position: absolute; /* 绝对定位 */ top: 0; right: 0; bottom: 40px; left: 70px; /* 通过设置边距实现眼睛的位置 */ margin: auto; /* 自动计算外边距,以保证居中 */ } .left::before { content: ""; /* 添加伪元素 */ position: absolute; /* 绝对定位 */ z-index: 3; /* 设置堆叠顺序 */ width: 100px; /* 宽度设为100像素 */ height: 85px; /* 高度设为85像素 */ border-radius: 50%; /* 边框半径设为50% */ background: radial-gradient(circle at 0 0, transparent 80%, var(--black-fade)80%, var(--black-fade)90%, transparent 90%); /* 径向渐变背景 */ bottom: 80px; /* 距底部80像素 */ right: 0px; /* 距右边0像素 */ transform: rotatez(25deg); /* 旋转25度 */ opacity: 0; /* 不透明度设为0 */ } .right::before { content: ""; /* 添加伪元素 */ position: absolute; /* 绝对定位 */ z-index: 3; /* 设置堆叠顺序 */ width: 100px; /* 宽度设为100像素 */ height: 85px; /* 高度设为85像素 */ border-radius: 50%; /* 边框半径设为50% */ background: radial-gradient(circle at 100% 0, transparent 80%, var(--black-fade)80%, var(--black-fade)90%, transparent 90%); /* 径向渐变背景 */ bottom: 80px; /* 距底部80像素 */ left: 0px; /* 距左边0像素 */ transform: rotatez(-25deg); /* 旋转-25度 */ opacity: 0; /* 不透明度设为0 */ } .mouth { position: absolute; /* 绝对定位 */ top: 88px; /* 距顶部88像素 */ right: 0; bottom: 0; left: 0; /* 左右和底部设为0以居中 */ margin: auto; /* 自动计算外边距,以保证居中 */ overflow: hidden; /* 隐藏超出元素范围的内容 */ width: 94px; /* 宽度设为94像素 */ height: 48px; /* 高度设为48像素 */ transition: .3s; /* 过渡效果时间为0.3秒 */ } .mouth:before { position: absolute; /* 绝对定位 */ top: 0; right: 0; bottom: 10px; left: 0; /* 设置上下左右距离居中 */ margin: auto; /* 自动计算外边距,以保证居中 */ content: ""; /* 伪元素内容为空 */ width: 100%; /* 宽度设为父元素的100% */ height: 100%; /* 高度设为父元素的100% */ background-color: #6E440B; /* 背景颜色设为深棕色 */ border-radius: 100%; /* 圆形边框 */ box-shadow: rgba(255, 255, 255, 0.25) 0 3px 0; /* 阴影效果 */ transform: scale(1); /* 缩放比例设为1 */ } .mouth:after { position: absolute; /* 绝对定位 */ top: 0; right: 0; bottom: 26px; left: 0; /* 设置上下左右距离居中 */ margin: auto; /* 自动计算外边距,以保证居中 */ content: ""; /* 伪元素内容为空 */ width: calc(100% - 20px); /* 宽度设为父元素宽度减20像素 */ height: 100%; /* 高度设为父元素的100% */ background-color: #FECA32; /* 背景颜色设为黄色 */ border-radius: 100%; /* 圆形边框 */ box-shadow: rgba(0, 0, 0, 0.8) 0 4px 4px -4px; /* 阴影效果 */ transform-origin: 50% 100%; /* 设置变换的原点为元素的底部中心 */ transform: scale(1.6); /* 缩放比例设为1.6 */ } /* hover 状态 */ #emoji:hover .face { background-color: rgb(230, 80, 7); /* 当鼠标悬停时,改变面部背景颜色为橙红色 */ } #emoji:hover .eye { height: 30px; /* 当鼠标悬停时,改变眼睛的高度为30像素 */ box-shadow: inset rgba(0, 0, 0, 0.5) 0 6px 12px, rgba(250, 160, 55, .3) 0 2px 0 2px; /* 当鼠标悬停时,改变眼睛的阴影效果 */ } #emoji:hover .left, #emoji:hover .right { top: 45px; /* 当鼠标悬停时,调整眼睛的上边距为45像素 */ bottom: 40px; /* 当鼠标悬停时,调整眼睛的下边距为40像素 */ } #emoji:hover .left::before, #emoji:hover .right::before { opacity: 1; /* 当鼠标悬停时,显示眼睛的光效 */ bottom: 40px; /* 当鼠标悬停时,调整光效的底部距离为40像素 */ transition: .3s; /* 设置过渡效果时间为0.3秒 */ } #emoji:hover .mouth { overflow: visible; /* 当鼠标悬停时,显示超出元素范围的内容 */ top: 120px; /* 当鼠标悬停时,调整嘴巴的顶部距离为120像素 */ width: 84px; /* 当鼠标悬停时,调整嘴巴的宽度为84像素 */ height: 35px; /* 当鼠标悬停时,调整嘴巴的高度为35像素 */ transform: translate3d(0, 0, 0); /* 重置3D转换 */ background: var(--black-fade); /* 背景颜色设为淡化的黑色 */ border-radius: 60%/80%; /* 当鼠标悬停时,调整嘴巴的边框半径 */ box-shadow: inset 0 0 10px 1px black; /* 当鼠标悬停时,设置内部阴影效果 */ } #emoji:hover .mouth:before { opacity: 0; /* 当鼠标悬停时,隐藏嘴巴的前景内容 */ } #emoji:hover .mouth:after { transform: scale(1); /* 当鼠标悬停时,将嘴巴后景内容缩放至原始大小 */ width: 68px; /* 当鼠标悬停时,调整后景内容的宽度为68像素 */ height: 75px; /* 当鼠标悬停时,调整后景内容的高度为75像素 */ background: linear-gradient(90deg, transparent 45%, var(--black-fade)50%, transparent 55%), radial-gradient(circle at 50% 10%, rgb(240, 40, 115), var(--shine)55%); /* 设置渐变背景颜色 */ background-repeat: no-repeat; /* 禁止背景图案的重复 */ background-size: 100% 50%, 100% 100%; /* 设置背景图案的大小 */ top: 15px; /* 当鼠标悬停时,调整后景内容的顶部距离为15像素 */ bottom: auto; /* 当鼠标悬停时,禁用底部对齐 */ left: 50%; /* 当鼠标悬停时,将后景内容水平居中 */ margin: auto -34px; /* 当鼠标悬停时,调整后景内容的外边距 */ border-radius: 7px 7px 50% 50%/10% 10% 50% 50%; /* 当鼠标悬停时,调整后景内容的边框半径 */ filter: blur(2px); /* 当鼠标悬停时,应用2像素的模糊滤镜 */ box-shadow: inset 0 -2px 3px 0 mediumvioletred, inset 0 -5px 10px 7px rgb(240, 40, 115), 0 5px 10px 1px black; /* 当鼠标悬停时,设置阴影效果 */ }

        希望读者可以静下心来阅读一下上述代码,并且可以使用编译器一步一步的查看各行代码的效果!这里我们在对上述的代码进行总结:

这段CSS代码实现了以下功能和效果:

  1. 定义颜色变量

    • 使用CSS自定义属性(变量)定义了一组颜色,如亮度(shine)、主要颜色、次要颜色、强调色、淡化的黑色和深蓝色。这些变量用于后续样式的统一管理和应用。

  2. 全局样式设置

    • 设置了全局的paddingmargin为0,并去除了列表的默认样式。这是为了确保页面元素的初始样式统一,避免默认样式影响设计。

  3. 页面布局

    • 通过body标签的样式,设置页面为flex布局,内容垂直和水平居中显示。并使用height: 100vh将页面高度设置为视口高度,同时隐藏了滚动条以固定页面。

  4. 表情符号结构和布局

    • 使用#emoji容器定义表情符号的整体尺寸和位置,并且启用了3D转换,以优化后续动画效果。

    • layer类用于定义表情符号各层的基础样式。

  5. 面部基础样式

    • 定义了face类用于绘制表情符号的脸部,包括其位置、大小、背景颜色、圆形边框和阴影效果。

  6. 面部细节

    • shine类创建了脸部的光泽效果,通过渐变和透明度的应用,模拟光影。

    • eye类定义了眼睛的样式,使用位置、大小、圆形边框、阴影等属性进行美化。左右眼分别使用.eye.left.eye.right定位。

    • left::beforeright::before伪元素添加了眼睛的反光效果。

  7. 嘴巴样式

    • mouth类用于定义嘴巴的外观,包括位置、尺寸、背景颜色、边框半径和阴影效果。使用::before::after伪元素添加了嘴巴的额外细节。

  8. 鼠标悬停效果

    • 使用:hover伪类为表情符号添加了鼠标悬停时的动画效果。包括脸部颜色变化、眼睛形状和阴影的调整、嘴巴位置和形状的变化、以及嘴巴内部的复杂光影效果。

  9. 过渡效果

    • 为大多数动画和样式变化设置了平滑的过渡效果,通常为0.3秒,使得动画更加流畅和自然。

现在再让我们看一下效果:

前端练习小项目——包变脸的,老弟 !

——我们会发现,笑脸不会跟随着鼠标的移动发生变化,这时候我们就需要加上一些交互效果了!

3.交互 —— JavaScript代码

JavaScript代码:

<!-- 导入Parallax视差插件 --> <script src="https://cdnjs.cloudflare.com/ajax/libs/parallax/2.1.3/parallax.min.js"></script> <script> var options = { invertX: false, // 水平方向反转 invertY: false, // 垂直方向反转 limitX: 40, // 水平方向限制 limitY: 40// 垂直方向限制 } var emoji = document.getElementById('emoji'); // 获取元素id为emoji的DOM对象 var parallax = new Parallax(emoji, options); // 创建新的视差对象并传入emoji和options参数 </script>

——编写好上述代码之后,我们就可以实现文章开始时的效果了!!!(效果如下)

前端练习小项目——包变脸的,老弟 !


以上就是本篇文章的全部内容了!!!

评论(0)条

提示:请勿发布广告垃圾评论,否则封号处理!!

    猜你喜欢
    【MySQL】用户管理

    【MySQL】用户管理

     服务器/数据库  4个月前  3.7k

    我们推荐使用普通用户对数据的访问。而root作为管理员可以对普通用户对应的权限进行设置和管理。如给张三和李四这样的普通用户权限设定后。就只能操作给你权限的库了。

    Cursor Rules 让开发效率变成10倍速

    Cursor Rules 让开发效率变成10倍速

     服务器/数据库  4个月前  2.16k

    在AI与编程的交汇点上,awesome-cursorrules项目犹如一座灯塔,指引着开发者们驶向更高效、更智能的编程未来。无论你是经验丰富的老手,还是刚入行的新人,这个项目都能为你的编程之旅增添一抹亮色。这些规则文件就像是你私人定制的AI助手,能够根据你的项目需求和个人偏好,精确地调教AI的行为。突然间,你会发现AI不仅能理解Next.js的最佳实践,还能自动应用TypeScript的类型检查,甚至主动提供Tailwind CSS的类名建议。探索新的应用场景,推动AI辅助编程的边界。

    探索Django 5: 从零开始,打造你的第一个Web应用

    探索Django 5: 从零开始,打造你的第一个Web应用

     服务器/数据库  4个月前  1.97k

    Django 是一个开放源代码的 Web 应用程序框架,由 Python 写成。它遵循 MVT(Model-View-Template)的设计模式,旨在帮助开发者高效地构建复杂且功能丰富的 Web 应用程序。随着每个版本的升级,Django 不断演变,提供更多功能和改进,让开发变得更加便捷。《Django 5 Web应用开发实战》集Django架站基础、项目实践、开发经验于一体,是一本从零基础到精通Django Web企业级开发技术的实战指南《Django 5 Web应用开发实战》内容以。

    MySQL 的mysql_secure_installation安全脚本执行过程介绍

    MySQL 的mysql_secure_installation安全脚本执行过程介绍

     服务器/数据库  4个月前  1.96k

    mysql_secure_installation 是 MySQL 提供的一个安全脚本,用于提高数据库服务器的安全性

    【MySQL基础篇】概述及SQL指令:DDL及DML

    【MySQL基础篇】概述及SQL指令:DDL及DML

     服务器/数据库  4个月前  778

    数据库是长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。数据库不仅仅是数据的简单堆积,而是遵循一定的规则和模式进行组织和管理的。数据库中的数据可以包括文本、数字、图像、音频等各种类型的信息。

    Redis中的哨兵(Sentinel)

    Redis中的哨兵(Sentinel)

     服务器/数据库  4个月前  649

    ​ 上篇文章我们讲述了Redis中的主从复制(Redis分布式系统中的主从复制-CSDN博客),本篇文章针对主从复制中的问题引出Redis中的哨兵,希望本篇文章会对你有所帮助。