你绝对没有见过的CSS骚操作-页面中的图片竟然是box-shadow实现的

86 阅读1分钟

CSS骚操作-页面中的图片竟然是box-shadow实现的

image.png


import { useEffect, useRef } from "react";

// 根据图片生成css
const createCss = (width: number, height: number, bmp) => {
  const shadowCSSFragments = [];
  for (let r = 0; r < height; r++) {
    for (let c = 0; c < width; c++) {
      const i = r * width + c;
      const R = bmp.data[i * 4],
        G = bmp.data[i * 4 + 1],
        B = bmp.data[i * 4 + 2],
        A = bmp.data[i * 4 + 3];
      shadowCSSFragments.push(
        `${c + 1}px ${r}px  rgba(${R},${G},${B},${A / 255})`
      );
    }
  }
  const shadowCSS = shadowCSSFragments.join(",");
  return shadowCSS;
};

function App() {
  const ref = useRef<HTMLInputElement | null>(null);
  const boxRef = useRef<HTMLInputElement | null>(null);
  useEffect(() => {
    const { current } = ref;
    const { current: box } = boxRef;
    if (!current || !box) return;
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    current.onchange = () => {
      const file = current!.files?.[0];
      const reader = new FileReader();
      reader.onload = function (e) {
        const img = new Image();
        img.src = e?.target?.result as string;
        img.onload = function () {
          canvas.width = img.width;
          canvas.height = img.height;
          box.style.width = "1px";
          box.style.height = "1px";
          ctx?.drawImage(img, 0, 0);
          const data = ctx?.getImageData(0, 0, img.width, img.height);
          const { width, height } = data || {
            width: 0,
            height: 0,
          };
          const boxShadow = createCss(width, height, data);
          box.style.boxShadow = boxShadow;
        };
      };
      if (file) {
        reader.readAsDataURL(file);
      }
    };
  }, []);

  return (
    <>
      <input type="file" ref={ref} />
      <div
        ref={boxRef}
        style={{
          width: `1px !important`,
          height: `1px !important`,
        }}
      ></div>
    </>
  );
}

export default App;