You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需额外div实现图片从右下到左上的渐显CSS/JS动画?

问题描述

我是CSS初学者,想要实现一张图片从右下角开始渐显至左上角的动画。尝试直接在img元素上实现失败后,我使用了一个与背景同色的div覆盖在图片上方完成效果,现请教无需额外div的专业实现方法,纯CSS或JS方案均可。

原实现代码:

.personal-photo {
  padding: 4rem;
  z-index: -10;
}

.photo-effect {
  position: absolute;
  padding: 42%;
  top: 91px;
  left: 91px;
  background-image: linear-gradient(120deg, #fff 0%, #fff 50%, transparent 50%);
  background-size: 300%;
  animation: photoEffect 2s infinite;
  z-index: 10;
}

@keyframes photoEffect {
  100% {
    background-position: 100%;
  }
}
<div class="container">
  <img src="https://placekitten.com/200/300" class="personal-photo" alt="">
  <div class="photo-effect"></div>
</div>
无需额外div的实现方案

方案一:CSS Mask 属性(推荐)

用CSS Mask可以直接在img元素上做遮罩动画,不用额外元素,效果精准。核心是用渐变遮罩从完全覆盖图片(隐藏状态)过渡到完全透明(显示状态),动画方向对应右下角到左上角。

代码示例:

.container {
  position: relative;
  padding: 4rem;
}

.personal-photo {
  width: 200px;
  height: 300px;
  animation: revealFromCorner 2s forwards;
  /* 初始遮罩完全盖住图片 */
  mask: linear-gradient(120deg, black 50%, transparent 50%);
  mask-size: 300%;
  mask-position: 100% 100%; /* 遮罩初始定位在右下角 */
  /* 兼容webkit内核浏览器 */
  -webkit-mask: linear-gradient(120deg, black 50%, transparent 50%);
  -webkit-mask-size: 300%;
  -webkit-mask-position: 100% 100%;
}

@keyframes revealFromCorner {
  to {
    mask-position: 0% 0%; /* 遮罩移到左上角,完全显示图片 */
    -webkit-mask-position: 0% 0%;
  }
}
<div class="container">
  <img src="https://placekitten.com/200/300" class="personal-photo" alt="猫咪图片">
</div>
  • 黑色遮罩区域会显示图片,透明区域隐藏图片
  • 动画通过改变mask-position,让遮罩从右下角滑到左上角,实现渐显
  • 加-webkit-前缀适配Chrome、Safari等浏览器

方案二:父容器伪元素替代额外div

如果要兼容不支持mask的旧浏览器,可以用图片父容器的伪元素来做,同样不用额外div标签。

代码示例:

.container {
  position: relative;
  padding: 4rem;
  display: inline-block; /* 让容器贴合图片尺寸 */
}

.container::after {
  content: '';
  position: absolute;
  top: 4rem; /* 对应容器的padding值 */
  left: 4rem;
  width: 100%;
  height: 100%;
  background: linear-gradient(120deg, #fff 50%, transparent 50%);
  background-size: 300%;
  background-position: 100% 100%;
  animation: coverEffect 2s forwards;
}

.personal-photo {
  width: 200px;
  height: 300px;
}

@keyframes coverEffect {
  to {
    background-position: 0% 0%;
    opacity: 0; /* 动画结束后隐藏伪元素 */
  }
}
<div class="container">
  <img src="https://placekitten.com/200/300" class="personal-photo" alt="猫咪图片">
</div>
  • 用容器的::after伪元素代替原来的额外div,定位在图片上方
  • 动画移动渐变背景,让白色覆盖区域从右下角移到左上角,最后隐藏伪元素

方案三:JavaScript 像素级控制(可选)

如果需要更精细的自定义效果,可以用JS通过Canvas逐像素控制透明度,不过性能比CSS方案稍差,适合复杂交互场景。

代码示例:

.container {
  padding: 4rem;
}

.personal-photo {
  width: 200px;
  height: 300px;
  position: relative;
}
<div class="container">
  <img src="https://placekitten.com/200/300" class="personal-photo" id="photo" alt="猫咪图片">
</div>
<script>
const img = document.getElementById('photo');
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');

canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);

let progress = 0;
const duration = 2000; // 动画时长2秒
const startTime = Date.now();

function animate() {
  const elapsed = Date.now() - startTime;
  progress = Math.min(elapsed / duration, 1);
  
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const data = imageData.data;
  
  // 遍历每个像素,根据进度控制透明度
  for (let y = 0; y < canvas.height; y++) {
    for (let x = 0; x < canvas.width; x++) {
      const index = (y * canvas.width + x) * 4;
      // 计算当前像素到右下角的距离比例
      const distanceRatio = Math.sqrt(
        Math.pow((canvas.width - x)/canvas.width, 2) + 
        Math.pow((canvas.height - y)/canvas.height, 2)
      ) / Math.sqrt(2);
      
      // 进度达标就显示该像素
      data[index + 3] = distanceRatio <= progress ? 255 : 0;
    }
  }
  
  ctx.putImageData(imageData, 0, 0);
  img.src = canvas.toDataURL();
  
  if (progress < 1) requestAnimationFrame(animate);
}

img.onload = animate;
</script>
  • 通过Canvas绘制图片,逐像素设置透明度,实现从右下角到左上角的渐显
  • 适合需要自定义渐变曲线或复杂交互的场景,但性能开销比CSS大

内容的提问来源于stack exchange,提问作者Marya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 08:40:32