做一个好看的首屏图片展示动画

前些日逛掘金,逛到了coco大佬的很炫酷的图片动画:现代 CSS 之高阶图片渐隐消失术 - 掘金 (juejin.cn)

利用 mask@property 做出图片像素化渐隐的效果实在是炫酷,正好现在没项目在摸鱼,脑子一抽开始用 nuxt3 写个人博客,正好首屏展示用得上 (又菜又爱玩)

定义网格

开始的想法是这样的,在大佬的代码基础上修改,通过代码获取到窗口宽高,然后通过 css变量 来动态修改行数列数,试了老半天也不太对,老是报错:

var(--w) is not a number

Undefined operation "calc(var(--w) * var(--h)) + 1"

也许一开始想用 js 去修改预处理器就有问题了🙃

正好又看油管一个大佬的图像碎片化,so,干脆用这个差不多的方法来代替 mask,做一个丐版图片渐隐,不需要 @propertyPaint 这种,兼容性还是蛮稳,也就一点点小卡

首先定义一下网格宽高,主要就是一层网格铺在图片前面,颜色跟背景色一致,后面再触发隐藏网格

js 复制代码
const centerBg = ref(null); // ref 获取到标签
const mask = ref(null); // ref 获取到标签
const row = ref(0); // 行数
const col = ref(0); // 列数
const len = ref(0); // 每个网格的大小
const initImg = () => {
  const imageWidth = window.innerWidth;
  const imageHeight = window.innerHeight;
  const maxGridCount =
    window.innerWidth > 1920
      ? 1000
      : window.innerWidth > 1080
      ? 800
      : window.innerWidth > 768
      ? 600
      : 400;
  // len 取宽高中较小的值,保证铺满
  len.value = Math.min(imageWidth, imageHeight) / Math.sqrt(maxGridCount);
  col.value = Math.floor(imageWidth / len.value);
  row.value = Math.floor(imageHeight / len.value);
};
const getCellStyle = (rowIndex, colIndex) => {
  return {
    width: `${len.value}px`,
    transition: `opacity ${100 + Math.random() * 500}ms ${
      ((colIndex + rowIndex / 2) / 20) * Math.random() * 500
    }ms`,
  };
};
html 复制代码
<template>
  <div
    class="centerBg relative w-screen h-screen overflow-hidden flex flex-col justify-center items-center gap-6"
    ref="centerBg"
  >
    <!-- mask -->
    <div class="mask absolute inset-0" ref="mask">
      <div v-for="rowIndex in row" :key="rowIndex" class="row flex">
        <div
          v-for="colIndex in col"
          :key="colIndex"
          class="col flex-1 aspect-square"
          :style="getCellStyle(rowIndex, colIndex)"
        ></div>
      </div>
    </div>
    <!-- title -->
    ...
    <!-- 简介 -->
    ...
    <!-- waves -->
    ...
  </div>
</template>

这段代码也没什么好解释的,len 是取的宽高较小的值为了保证能铺满,然后看下标签那部分,getCellStyle 里面的 transition 随便改,现在是从左往右带一些倾斜

修改 css

先把 css 的部分给写了,后面修改 --o 让网格隐藏就完工~

scss 复制代码
.centerBg {
  --o: 1;
  --img: url("assets/images/0.png");
  background: var(--img) center center/cover;
  .col {
    background: var(--bg); // 背景色
    opacity: var(--o);
  }
}
.dark .centerBg {
  --img: url("assets/images/_0.png");
}

触发动画

在完成定义网格和修改样式后,可以用个延时,或者正好可以等图片加载完在触发,用 Image 对象的 decode() 等,不然直接触发是没有效果的

js 复制代码
onMounted(() => {
  initImg();
  setTimeout(()=>{
    centerBg.value.style.setProperty("--o", 0)
  });
});

几百个 div 的动画,卡不卡就另说了 🤔

相关推荐
谙忆10242 小时前
图片裁剪总是跑偏?用 object-fit、object-position 和真实像素把坐标对齐
javascript·css·图像识别
01_ice4 小时前
前端学习css
前端·css·学习
zh_xuan7 小时前
个人主页左侧菜单支持分组,以及菜单显示和隐藏
前端·javascript·css
Ming_studying7 小时前
HTML + CSS + JavaScript实现可视化JSON工具:格式化、折叠、搜索与错误定位
javascript·css·html·json·数据可视化·web工具
To_OC15 小时前
面试被问了三回三栏布局,这次我终于把 BFC 那层窗户纸捅破了
前端·css·面试
CarIise18 小时前
CSS选择器与样式关联
前端·css·tensorflow
里欧跑得慢20 小时前
CSS 模块化架构的演进:BEM、CSS Modules 到 CSS-in-JS 的反思
前端·css·flutter·web·css-in-js
人间凡尔赛1 天前
2026 前端必修:4 个让 CSS 脱胎换骨的现代新特性(附实战代码)
前端·css
Asize2 天前
2 道大厂面试题:TS 工具类型我懂了,CSS 3 列布局把我问住了
前端·css·typescript
用户059540174463 天前
把 AI 长期记忆去重测试从 20 分钟压到 40 秒,重复率从 18% 干到 1.5%
前端·css