CSS 之 图片九宫格变幻效果

一、简介

​ 本篇博客用于讲解如何实现图片九宫格变幻的样式效果,将图片分为九块填充在3×3的的九宫格子元素中,并结合gridhovertransition等CSS属性,实现元素hover时,九宫格子元素合并为一张完整图片的动画效果。

​ 为了简化代码,demo中通过JS设置CSS变量的方法,优化了元素背景的设置过程,减少了代码的繁杂度。

​ 最后还结合js的点击事件实现了一个简易的点击拼图demo。

效果示意图:

在这里插入图片描述

二、具体实现

1、九宫格子元素显示部分图片,然后从外向内组合变幻成完整图片
页面效果:

在这里插入图片描述

实现思路:

​ ① 首先在一个父元素内,创建九个子元素,并通过display: grid;实现3×3的九宫格布局,使其聚集在父元素中间,此时子元素之间无间隙。

​ ② 给这九个子元素通过background的相关属性,分别设置各个子元素的背景图片为总图片的一部分(1/9),其聚集在一起时,正好能够组成一张完成的图片。

​ ③ 在设置子元素背景时,可以通过依次设置九个子元素的背景样式来实现,但是代码过于繁琐。为了优化代码,可以通过js获取相应元素,然后遍历获取到的元素设置CSS变量,最后再统一通过子级选择器+CSS变量的形式,统一设置元素背景。

​ ④ 设置好背景后,利用父元素grid布局的gap属性,统一设置子元素之间的间距,使九个子元素按照固定间距,形成九宫格布局。

​ ⑤ 父元素hover时,修改gap属性的值,使子元素再次聚集在一起,并通过transition实现缓动动画。

核心思路为:变化主体为父元素,子元素不改变,改变父元素控制间隙的属性。

具体代码:
<style>.d1 {/* 设置grid布局 */display: grid;grid-template-columns: 100px 100px 100px;grid-template-rows: 100px 100px 100px;/* 设置子元素间隔 */gap: 20px;width: 340px;height: 340px;/* 设置子元素居中在父元素中心 */justify-content: center;align-content: center;cursor: pointer;/* 设置缓动动画 */transition: all 0.3s linear;border: 2px solid red;}/* hover时消除子元素间隔 */.d1:hover {gap: 0;}/* 统一设置子元素的背景 */.d1>div {background: url(../image/test.jpg) no-repeat;/* 设置背景图片大小 这个大小等于后面拼接成的完成图片的大小 */background-size: 300px 300px;/* 利用JS设置的CSS变量控制子元素的背景 */background-position: var(--bgx, 0) var(--bgy, 0);}
</style><div class="d1"><div class="d1-1"></div><div class="d1-2"></div><div class="d1-3"></div><div class="d1-4"></div><div class="d1-5"></div><div class="d1-6"></div><div class="d1-7"></div><div class="d1-8"></div><div class="d1-9"></div>
</div><script>// 获取所有子元素const d1List = document.querySelectorAll('.d1 > div');// 遍历所有子元素d1List.forEach((item, index) => {// 计算当前子元素所在行 0~2const row = Math.floor(index / 3);// 计算当前子元素所在列 0~2const col = index % 3;console.log(row, col);// 根据子元素所在行和列 设置CSS变量 决定显示的背景图片的偏移量 从而决定背景图片的内容item.style.setProperty('--bgx', `${-col * 100}px`);item.style.setProperty('--bgy', `${-row * 100}px`);})
</script>
2、九宫格子元素显示部分图片,然后从内向外组合变幻成完整图片
页面效果:

在这里插入图片描述

实现思路:

​ ① 首先在一个父元素内,创建九个子元素,并通过display: grid;实现3×3的九宫格布局,初始设置子元素的宽高小于grid布局设置的单元格宽高,然后通过相关属性设置子元素在对应单元格内水平垂直居中。

​ ② 给这九个子元素通过background的相关属性,分别设置背景图片为总图片的一部分。

​ ③ 在设置子元素背景时,可以通过依次设置九个子元素的背景样式来实现,但是代码过于繁琐。为了优化代码,可以通过js获取相应元素,然后遍历获取到的元素设置CSS变量,最后再统一通过子级选择器+CSS变量的形式,统一设置元素背景,使九个子元素各自占据背景图片的一部分。但由于此时子元素的宽高小于grid布局设置的单元格宽高,所以此时子元素之间存在间隙,而且所有子元素组合拼接的背景图片并不完整。

​ ④ 设置父元素hover时,改变子元素的宽高,使其充满单元格宽高,承载的背景图片比例也相应变大,此时子元素之间紧密连接,并组合拼接为一张完整的图片。

核心思路为:变化主体为子元素,子元素改变宽高属性,父元素不变。

具体代码:
<style>.d2 {/* 设置grid布局 */display: grid;grid-template-columns: 100px 100px 100px;grid-template-rows: 100px 100px 100px;width: 300px;height: 300px;cursor: pointer;border: 2px solid red;}.d2>div {/* 设置子元素的初始宽高 */width: 60px;height: 60px;/* 设置子元素位于grid布局网格的中心位置 */justify-self: center;align-self: center;/* 设置子元素缓动动画 */transition: all 0.3s linear;/* 设置子元素背景图片 */background: url(../image/test.jpg) no-repeat;/* 设置背景图片的大小 这个大小等于后面拼接成的完成图片的大小 */background-size: 300px 300px;/* 利用JS设置的CSS变量控制子元素的背景偏移 */background-position: var(--bgx, 0) var(--bgy, 0);}/* 父元素hover之后 修改子元素的宽高 使子元素能连接在一起 */.d2:hover div {width: 100px;height: 100px;}
</style><div class="d2"><div class="d2-1"></div><div class="d2-2"></div><div class="d2-3"></div><div class="d2-4"></div><div class="d2-5"></div><div class="d2-6"></div><div class="d2-7"></div><div class="d2-8"></div><div class="d2-9"></div>
</div><script>// 获取所有子元素const d2List = document.querySelectorAll('.d2 > div');// 遍历所有子元素d2List.forEach((item, index) => {// 计算当前子元素所在行 0~2const row = Math.floor(index / 3);// 计算当前子元素所在列 0~2const col = index % 3;console.log(row, col);// 根据子元素所在行和列 设置CSS变量 决定显示的背景图片偏移量item.style.setProperty('--bgx', `${-col * 100}px`);item.style.setProperty('--bgy', `${-row * 100}px`);})
</script>
3、九宫格子元素显示完整小图,然后从外向内合并成一张完整大图
页面效果:

在这里插入图片描述

实现思路:

​ ① 首先在一个父元素内,创建九个子元素,并通过display: grid;实现3×3的九宫格布局,并且设置子元素之间存在固定间隙。

​ ② 给每一个子元素都设置背景图片,并且设置背景图片的大小等于子元素的大小,使背景图片在子元素中完整展示。

​ ③ 在父元素hover时,修改子元素之间的间隙为0,并且修改子元素的背景图片大小和背景图片的偏移量,使子元素只显示背景图片的一部分,并且所有子元素拼接起来时,能够构成一张完整的背景图片。

核心思路:同时改变父元素和子元素,改变父元素控制间隙的属性,改变子元素的背景属性。

具体代码:
<style>.d4 {/* 设置grid布局 */display: grid;grid-template-columns: 100px 100px 100px;grid-template-rows: 100px 100px 100px;/* 设置子元素之间的间隙 */gap: 20px;width: 340px;height: 340px;/* 设置子元素整体内容区域相对于父元素水平垂直居中 */justify-content: center;align-content: center;cursor: pointer;/* 设置父元素缓动动画 */transition: all 0.4s linear;border: 2px solid red;}.d4>div {/* 设置子元素缓动动画 */transition: all 0.4s linear;/* 设置子元素的背景 背景图片大小适配元素大小 */background: url(../image/test.jpg) no-repeat;background-size: 100% 100%;}/* 父元素hover时 将子元素之间的间隙变为0  */.d4:hover {gap: 0;}/* 父元素hover时 修改子元素背景图片的大小 以及背景图片偏移量 */.d4:hover>div {/* 设置的背景图片大小 就是子元素拼接成一张图片时 图片的大小 */background-size: 300px 300px;/* 根据JS设置的CSS变量 设置背景图片的偏移量 */background-position: var(--bgx, 0) var(--bgy, 0);}
</style><div class="d4"><div class="d4-1"></div><div class="d4-2"></div><div class="d4-3"></div><div class="d4-4"></div><div class="d4-5"></div><div class="d4-6"></div><div class="d4-7"></div><div class="d4-8"></div><div class="d4-9"></div>
</div><script>// 获取所有子元素const d4List = document.querySelectorAll('.d4 > div');// 遍历所有子元素d4List.forEach((item, index) => {// 计算当前子元素所在行 0~2const row = Math.floor(index / 3);// 计算当前子元素所在列 0~2const col = index % 3;console.log(row, col);// 根据子元素所在行和列 设置CSS变量 决定显示的背景图片偏移量item.style.setProperty('--bgx', `${-col * 100}px`);item.style.setProperty('--bgy', `${-row * 100}px`);})
</script>

三、延伸扩展

1、简易的九宫格拼图游戏

​ 上面的三个案例Demo中,都是在父元素hover时,通过控制CSS样式子元素进行整体变化,无法做到针对单个元素进行变化。如果我们结合JS的点击事件,以及子元素的定位属性,就可以实现针对单个元素的变化。比如实现简单的拼图游戏效果等等。

页面效果:

在这里插入图片描述

实现思路:

​ ① 首先在一个父元素内,创建九个子元素,并通过display: grid;实现3×3的九宫格布局,并且设置子元素之间无间隙,紧密结合在一起,并且在父元素中水平垂直居中。

​ ② 通过JS获取所有子元素,然后遍历获取到的子元素,根据子元素所在行和所在列,设置表示背景偏移的CSS变量,最后再统一通过子级选择器+CSS变量的形式,统一设置元素背景,使九个子元素各自占据背景图片的一部分。

​ ③ 在上一步遍历所有子元素时,根据子元素所在行和所在列,同步设置表示子元素偏移的CSS变量,然后再给子元素设置 position: relative;相对定位,最后再统一通过子级选择器+CSS变量的形式,利用CSS变量设置子元素的偏移量,使其形成有监理的九宫格布局。

​ ④ 在遍历所有子元素的同时,给所有子元素绑定点击事件,根据事件触发元素上的表示元素偏移量的CSS变量的值,决定元素该向内还是向外偏移,然后根据元素所在的行和列,决定具体的元素偏移量。

具体代码:
<style>.d3 {/* 设置grid布局 */display: grid;grid-template-columns: 100px 100px 100px;grid-template-rows: 100px 100px 100px;width: 340px;height: 340px;/* 设置子元素整体内容区域相对于父元素水平垂直居中 */justify-content: center;align-content: center;cursor: pointer;border: 2px solid red;}.d3>div {/* 设置子元素的偏移 使子元素之间出现间隙 形成九宫格布局 */position: relative;/* 利用JS的定义的CSS变量设置元素偏移量 */left: var(--pleft, 0);top: var(--ptop, 0);z-index: 1;width: 100px;height: 100px;/* 设置子元素的背景图片 */background: url(../image/test.jpg) no-repeat;/* 设置背景图片尺寸 该尺寸等同于子元素拼接后图片的尺寸 */background-size: 300px 300px;/* 利用JS的定义的CSS变量设置背景图片的偏移量 */background-position: var(--bgx, 0) var(--bgy, 0);/* 设置子元素的缓动动画 */transition: all 0.3s linear;}
</style><div class="d3"><div class="d3-1"></div><div class="d3-2"></div><div class="d3-3"></div><div class="d3-4"></div><div class="d3-5"></div><div class="d3-6"></div><div class="d3-7"></div><div class="d3-8"></div><div class="d3-9"></div>
</div><script>// 获取所有子元素const d3List = document.querySelectorAll('.d3 > div');// 遍历所有子元素d3List.forEach((item, index) => {// 计算当前子元素所在行 0~2const row = Math.floor(index / 3);// 计算当前子元素所在列 0~2const col = index % 3;// 根据子元素所在行和列 设置CSS变量 决定显示的背景图片偏移量item.style.setProperty('--bgx', `${-col * 100}px`);item.style.setProperty('--bgy', `${-row * 100}px`);// 根据子元素所在行和列 设置CSS变量 决定元素的偏移量item.style.setProperty('--pleft', `${(col - 1) * 20}px`);item.style.setProperty('--ptop', `${(row - 1) * 20}px`);// 为当前子元素添加点击事件item.addEventListener('click', (e) => {// 获取当前子元素表示元素偏移量的CSS变量值const left = e.target.style.getPropertyValue('--pleft');const top = e.target.style.getPropertyValue('--ptop');// 判断当前子元素是否在原始位置if (left === '0px' && top === '0px') {// 如果在原始位置 则根据子元素所在行和列 设置CSS变量 决定使元素偏移e.target.style.setProperty('--pleft', `${(col - 1) * 20}px`);e.target.style.setProperty('--ptop', `${(row - 1) * 20}px`);} else {// 如果不在原始位置 则将CSS变量值设置为0px 将其移回原始位置e.target.style.setProperty('--pleft', `0px`);e.target.style.setProperty('--ptop', `0px`);}});})
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/651435.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringMVC 环境搭建入门

SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架&#xff0c;属于SpringFrameWork 的后续产品&#xff0c;已经融合在 Spring Web Flow 中。 SpringMVC 已经成为目前最主流的MVC框架之一&#xff0c;并且随着Spring3.0 的发布&#xff0c;全面…

02 Redis之配置文件

3. Redis配置文件 3.1 网络部分 首先明确&#xff0c;tcp-backlogestablished Linux 内核 2.2 版本之后&#xff08;现在大部分都是3.x了&#xff09; TCP 系统中维护了两个队列, 用来存放TCP连接 a. SYN_RECEIVED 队列中存放未完成三次握手的连接 b. ESTABLISHED队列中存放已…

Java面试题之序列化和反序列化

Java面试题之序列化和反序列化 文章目录 Java面试题之序列化和反序列化序列化和反序列化什么是序列化?什么是反序列化?如果有些字段不想进行序列化怎么办&#xff1f;常见序列化协议有哪些&#xff1f;为什么不推荐使用 JDK 自带的序列化&#xff1f; 文章来自Java Guide 用于…

腾讯云4核16G服务器价格,用于幻兽帕鲁Palworld专用

腾讯云幻兽帕鲁服务器4核16G、8核32G和16核64G配置可选&#xff0c;4核16G14M带宽66元一个月、277元3个月&#xff0c;8核32G22M配置115元1个月、345元3个月&#xff0c;16核64G35M配置580元年1个月、1740元3个月、6960元一年&#xff0c;腾讯云百科txybk.com分享腾讯云幻兽帕鲁…

腾讯云幻兽帕鲁专有服务器配置价格表,4核16G、8核32G

幻兽帕鲁服务器配置CPU内存多大合适&#xff1f;如何选择&#xff1f;最低4核8G起步&#xff0c;4核16G是官方推荐配置&#xff0c;最好是4核32G配置。阿腾云atengyun.com分享幻兽帕鲁Palworld服务器CPU内存配置及租用费用&#xff0c;如下图&#xff0c;Palworld官方推荐服务器…

特征点匹配 harris

算法的核心是利用局部窗口在图像上进行移动&#xff0c;判断灰度是否发生较大的变化。如果窗口内的灰度值&#xff08;在梯度图上&#xff09;都有较大的变化&#xff0c;那么这个窗口所在区域就存在角点。 这样就可以将 Harris 角点检测算法分为以下三步&#xff1a; 当窗口…

【Java面试】Mysql

目录 sql的执行顺序索引的优点和缺点怎么避免索引失效(也属于sql优化的一种)一条sql查询非常慢&#xff0c;我们怎么去排查和优化&#xff1f;存储引擎 MylSAM和InnoDB、Memory的区别事务的四大特性(ACID)脏读、不可重复读、幻读事务的隔离级别&#xff1f;怎么优化数据库SQL优…

云计算中的弹性是什么?

云弹性是指当客户需求增加或减少时&#xff0c;自动从数据中心配置和取消配置资源。这使得云资源(包括计算、存储和内存资源)能够根据需求变化快速重新分配。CPU/处理、内存、输入/输出带宽和存储容量等计算资源可以根据需要增加或减少&#xff0c;而不会影响系统性能。 它旨在…

应急消防应用步入“繁花”时代,卓翼智能消防无人机顺势而行大有可为

近日&#xff0c;北京卓翼智能科技有限公司&#xff08;以下简称“卓翼智能”&#xff09;宣布完成超亿元B轮融资&#xff0c;融资金额高达2.5亿元。这个“智能无人系统”黑马品牌&#xff0c;凭什么出圈&#xff1f;重点发力在哪些领域呢&#xff1f;今天&#xff0c;带你走进…

设计模式-生成器设计模式

什么是生成器设计模式 众所周知我们设计代码的时候要将代码设计出模块化的&#xff0c;一个功能是一个模块&#xff0c;那么生成器设计模式&#xff0c;是将一个类再度进行了一个拆分&#xff0c;让一个类的内部进行了单一职责化&#xff0c;其实我们在平时开发的时候就会不经…

分布式id-Leaf算法

一、介绍 由美团开发&#xff0c;开源项目链接&#xff1a;https://github.com/Meituan-Dianping/Leaf Leaf同时支持号段模式和snowflake算法模式&#xff0c;可以切换使用。ID号码是趋势递增的8byte的64位数字&#xff0c;满足上述数据库存储的主键要求。 Leaf的snowflake模…

交叉导轨为何要保持日常清洁?

在工业自动化的发展中&#xff0c;交叉导轨因其具有精度高、高刚性、高耐磨性等特点&#xff0c;在数控技术的发展中得到了越来越多的使用&#xff0c;对于交叉导轨来说&#xff0c;保持日常清洁对其性能和寿命具有重要意义。 1、防止灰尘和杂质的侵入&#xff1a;交叉导轨在机…

嵌入式学习第十一天

1.数组和指针的关系: 1.一维数组和指针的关系: int a[5] {1, 2, 3, 4, 5}; int *p NULL; p &a[0]; p a; 数组的数组名a是指向数组第一个元素的一个指针常量 a &a[0] a 的类型可以理解为 int * 有两种情况除…

五步安装和配置CLion的ESP-IDF开发框架

记录CLion安装和配置ESP-IDF开发框架 真无语了&#xff0c;弄了半天多&#xff0c;近一天&#xff0c;这里弄那里弄。记录一下&#xff0c;万一后面还要踩坑呢&#xff01; 弄一早上components的编写和使用&#xff08;想用别人的components&#xff09;&#xff0c;下午弄开…

JavaScript学习-原型和原型链

原型和原型链 示例代码 //创建一个Person类 class Person {constructor(name) {this.name name;}drink() {console.log(喝水);} } //创建一个Teacher类&#xff0c;继承Person class Teacher extends Person {constructor(name, subject) {super(name);this.subject subjec…

动手学深度学习8 Softmax回归+损失函数+图片分类

Softmax回归损失函数图片分类 1. Softmax回归--分类问题2. 三个常用损失函数1. 均方损失 L2 Loss2. 绝对值损失函数 L1 Loss3. 两个结合 HUber’s Robust Loss 3. 图片分类数据集4. Softmax回归从零开始实现5. Softmax回归简洁实现6. QA 1. Softmax回归–分类问题 真实y只有一个…

基于java+jsp+ssh的毕业生就业信息管理系统

&#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩项目推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;希望帮…

ShardingSphere之ShardingJDBC客户端分库分表下

目录 ShardingJDBC实战 STANDARD标准分片策略 COMPLEX_INLINE复杂分片策略 CLASS_BASED自定义分片策略 HINT_INLINE强制分片策略 ShardingJDBC实战 上篇已经将需要用到的类、数据库表都准备好了&#xff0c;本篇主要介绍分片配置文件。 STANDARD标准分片策略 如果按照上篇文…

纳斯达克户外大屏背景配什么颜色效果最好-大舍传媒

纳斯达克户外大屏背景配什么颜色效果最好 引言 纳斯达克大屏是世界闻名的户外广告媒体之一&#xff0c;通过高清大屏呈现的广告内容吸引了众多目光。大舍传媒作为纳斯达克大屏的提供商和运营商之一&#xff0c;致力于创造最佳的视觉效果来吸引观众的注意力。在纳斯达克大屏投…

HCIA学习作业四

要求&#xff1a; 1、AR3还回为3.3.3.0/24 2、其他基于192.168.1.0/24进行合理划分 3、AR1和AR2均存在两个环回 4、整个网络运行RIP v2 但是不能直接宣告AR3的环回 5、全网可达&#xff0c;保障更新安全&#xff0c;尽量减少路由条目&#xff0c;避免环路 拓扑图&#xf…