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~2
      const row = Math.floor(index / 3);
      // 计算当前子元素所在列 0~2
      const 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~2
      const row = Math.floor(index / 3);
      // 计算当前子元素所在列 0~2
      const 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~2
      const row = Math.floor(index / 3);
      // 计算当前子元素所在列 0~2
      const 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~2
      const row = Math.floor(index / 3);
      // 计算当前子元素所在列 0~2
      const 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>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux C | 进程】Linux 进程间通信的10种方式(1)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

Nacos注册中心

Nacos注册中心 前言一、初识Nacos二、服务注册到nacos1.引入依赖2.配置nacos地址3.重启微服务 三、Nacos配置1.权重配置2.环境隔离2.1 创建namespace2.2给微服务配置namespace 四、Nacos与Eureka的区别 前言 一、初识Nacos Nacos是是SpringCloudAlibaba的组件,是一个动态服务…

springboot中JSP模版集成

一.配置 引入JSP解析依赖 <!--c标签库--> <dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version> </dependency><!--让内嵌tomcat具有解析jsp功能--> <dependency>&l…

实现上下文初始化参数

实现上下文初始化参数 问题方案 要解决上述问题,需要执行以下任务: 创建Web应用程序。创建检索初始化参数的servlet。指定初始化参数。构建Web应用程序。访问servlet。1. 创建Web应用程序 要使用NetBeans IDE创建Web应用程序,需要执行以下步骤: 选择“开始”→“所有程序”…

【Web】NSSCTF Round#17 Basic个人wp(全)

题目作为小练手还行&#xff0c;具体细节不必较劲。 目录 ①真.签到 ②真的是文件上传吗&#xff1f; 解法1 解法2 ①真.签到 访问/robots.txt base解码在线工具 hint直接base16解码&#xff0c;也算真给hint了&#xff0c;新生一个一个翻过去就好,在[SWPUCTF 2022 新生…

【C++中的STL】函数对象

函数对象 函数对象概念谓词概念 内建函数对象算术仿函数关系仿函数逻辑仿函数&#xff08;基本用不到&#xff09; 函数对象概念 重载函数调用操作符的类&#xff0c;其对象常称为函数对象&#xff0c;函数对象使用重载的()时。行为类似函数调用&#xff0c;也叫仿函数。 函数…

Element table组件内容\n换行

漂亮的页面总是让人心旷神怡&#xff0c;层次清晰的页面让用户操作起来也是易于上手及展示。 如下的页面展示就是非常low的&#xff1a;用户根本阅读其中的数据。 在这个页面&#xff0c;根据用户填写过程生成多次填写记录&#xff0c;如果不进行层次性的展示&#xff0c;数据…

Nestjs 异常拦截器

一、异常拦截器 目标&#xff1a;访问路径不存在时&#xff0c;返回结果中包含请求路径path 实现&#xff1a;1、创建一个异常过滤器&#xff0c;负责将捕获作为HttpException类实例的异常 2、访问底层平台Request、Response&#xff0c;通过访问Request对象&#xff0c;提取原…

微信小程序-04

rpx&#xff08;responsive pixel&#xff09;是微信小程序独有的&#xff0c;用来解决屏适配的尺寸单位。 import 后跟需要导入的外联样式表的相对路径&#xff0c;用 ; 表示语句结束。 定义在 app.wxss 中的样式为全局样式&#xff0c;作用于每一个页面。 在页面的 .wxss 文…

竞赛练一练 第30期:GESP和电子学会相关题目练习

Day14&#xff1a;CIE一级2022.06_报时的公鸡 故事背景&#xff1a;公鸡在黎明时分会打鸣迎接太阳升起&#xff0c;古人也将鸡鸣声当做晨起的“闹钟”。 1. 准备工作 &#xff08;1&#xff09;背景&#xff1a;根据下图绘制两张背景&#xff1b; 01 02 &#xff08;2&…

第5章 (python深度学习——波斯美女)

第5章 深度学习用于计算机视觉 本章包括以下内容&#xff1a; 理解卷积神经网络&#xff08;convnet&#xff09; 使用数据增强来降低过拟合 使用预训练的卷积神经网络进行特征提取 微调预训练的卷积神经网络 将卷积神经网络学到的内容及其如何做出分类决策可视化 本章将…

仰暮计划|“她就是用她的一双小脚把我们兄弟姐妹几个拉扯大的”

在残存的一些老物件中&#xff0c;在一些泛黄的相片中&#xff0c;掩藏着岁月的冲刷和青葱的时光。曾经无忧无虑的少女早已白发苍苍&#xff0c;不复青春貌美&#xff1b;曾经在父母面前笑闹的孩子早已变成他人眼中的长辈。 ——题记 她的身影也许并不高大&#xff0c;甚至还略…

Windows11 鼠标拖动文件到CMD控制终端窗口无效,无法显示具体文件路径

对于某些用户来说&#xff0c;他们可能会在Windows 11上遇到鼠标拖动文件到CMD控制终端时&#xff0c;无法显示具体文件路径的情况。 系统更新&#xff0c;习惯基础操作无效了&#xff0c;真的有点烦&#xff0c;不会提问就无计可施。 果然善于提问&#xff0c;才有果子吃 问…

Linux-动静态库

背景 在实践中&#xff0c;我们一定会使用别人的库&#xff08;不限于C、C的库&#xff09;&#xff0c;在实践中&#xff0c;我们会使用成熟、被广泛使用的第三方库&#xff0c;而不会花费很多时间自己造轮子&#xff0c;为了能更好地使用库&#xff0c;就要在学习阶段了解其…

jenkins+gitlab实现Android自动打包填坑之旅

一.背景 1.首先你需要知道你想要实现的Android自动打包的Android项目的一些环境配置及需要使用的一些开发版本。 声明&#xff1a;本文 Android项目基于&#xff1a;1.jdk11 2.SDK无要求 3.gradle无要求&#xff08;同Manven一样为项目自动化构建开源工具&#xff09; 注&am…

【控制算法笔记】卡尔曼滤波(二)——基于状态空间表达的KF基本计算流程以及Python实现

本文是个人学习笔记&#xff0c;包含个人理解&#xff0c;如有错误欢迎指正。 KF算法更多的情况下会用来处理复杂的非线性数据&#xff0c;尤其是当对象特征或检测的状态量不止一个时就得使用状态方程的方法&#xff0c;利用线性代数的计算方式来解决噪声的估计问题。这其中涉及…

C++实现满天星效果静态图片

用编程C实现随机生成不同效果的星星&#xff0c;实现看星星的效果图片&#xff0c;借助EasyX图形化工具!!! 在vs2019中新建文件夹&#xff0c;并且注意在项目目录下保存两张小人的抬头观看背景的图片 将下面代码粘贴进去实现效果&#xff1a; #define _CRT_SECURE_NO_WARNIN…

前端canvas项目实战——简历制作网站(三)——右侧属性栏(线条宽度样式)

目录 前言一、效果展示二、实现步骤1. 实现线条宽度&#xff08;strokeWidth&#xff09;的属性模块2. 实线线条样式&#xff08;strokeDashArray&#xff09;的属性模块3. 意料之外的“联动” 三、Show u the code后记 前言 上一篇博文中&#xff0c;我们初步实现了右侧属性栏…

IDEA 创建maven项目没有src

环境&#xff1a; IntelliJ IDEA 2022.3.3 (Ultimate Edition) JDK 17 Windows 11 10.0 Maven 3.9.5 创建maven项目的时候没有src目录 试过网上说的重新配置maven库&#xff0c;增加vm-options&#xff0c;并没有什么用。直到我看见了 正常创建就好了。

QoS服务质量

内存QoS——服务质量&#xff08;Quality of Service&#xff09; 作用&#xff1a;如果不开启QoS&#xff0c;会通过内存复用技术&#xff0c;动态调整虚拟机的资源&#xff0c;如果说有一台跑核心业务&#xff0c;然后通过QoS技术&#xff0c;通过限额&#xff0c;预留&…