JSFiddle - React, Tailwind, and code Playground

by HDL52

HTML

<div class="img"></div>

SCSS

body {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background: wheat;
}

// 用比例 400:600
$x:20;
$y:30;
$s:0.8;

@for $i from 0 through ($x - 1) {
  @for $j from 0 through ($y - 1) {
    @property --c-#{$i}-#{$j} {
      syntax: "<number>";
      initial-value: 1;
      inherits: false;
    }
  }
}

@function transition($i, $j) {
  @return ($s*random())+s ($s*random())+s;
}

@mixin image() {
  $all_t: ();
  $all_m: ();

  @for $i from 0 through ($x - 1) {
    @for $j from 0 through ($y - 1) {
      $all_t: append($all_t, --c-#{$i}-#{$j} transition($i, $j), comma);
      $all_m: append($all_m, linear-gradient(rgba(0, 0, 0, var(--c-#{$i}-#{$j})) 0 0) calc(#{$i}*100%/(#{$x} - 1)) calc(#{$j}*100%/(#{$y} - 1)), comma);
    }
  }

  transition: $all_t;
  -webkit-mask: $all_m;
  mask: $all_m;
}

div {
  width: 400px;
  height: 600px;
  border-radius: 10px;
  background: url("https://raw.githubusercontent.com/Hongda-OSU/PicGo-2.3.1/master/img1l99wbel5ip2y1oivo40zrh051humxd.png") no-repeat center/cover;
  @include image();
  -webkit-mask-size:calc(100%/#{$x}) calc(100%/#{$y});
  -webkit-mask-repeat: no-repeat;
  mask-size:calc(100%/#{$x}) calc(100%/#{$y});
  mask-repeat: no-repeat;
  transform: scale(0.5);
}

div:hover {
  @for $i from 0 through ($x - 1) {
    @for $j from 0 through ($y - 1) {
      --c-#{$i}-#{$j}: 0;
    }
  }
}