iT邦幫忙

2024 iThome 鐵人賽

DAY 3
0

Day03 是用 CSS 變數來更改圖片的樣式,可以做出簡單的圖片編輯器,但我剛開始的寫法似乎沒有符合原作的精神(?

後來問了 AI 後,發現還是可以從 CSS 取出資料,那麼就開始吧

CSS

  • 到 TailwindCSS 的 index.css 裡面設定初始值
@layer base {
  :root {
    --base: #ffc600;
    --spacing: 10px;
    --blur: 10px;
  }
}

取出 CSS 變數的函式

const getInitialValue = (
  varName: string,
  defaultValue: string | number
): string | number => {
  if (typeof window !== "undefined") {
    const value = getComputedStyle(document.documentElement)
      .getPropertyValue(varName)
      .trim();

    if (varName === "--base") {
      return value || defaultValue;
    }
    const parsedValue = parseInt(value);
    return isNaN(parsedValue) ? defaultValue : parsedValue;
  }
  return defaultValue;
};

初始資料

  • 由於用了 TypeScript,所以加上型別判斷

    • 這邊會從 CSS 裡面讀取資料
const SPACING = 10;
const BLUR = 1;
const BG_COLOR = "#ffc600";

  const [spacing, setSpacing] = useState<number>(() => {
    const initialValue = getInitialValue("--spacing", SPACING);
    return typeof initialValue === "number" ? initialValue : SPACING;
  });
  const [blur, setBlur] = useState<number>(() => {
    const initialValue = getInitialValue("--blur", BLUR);
    return typeof initialValue === "number" ? initialValue : BLUR;
  });
  const [baseColor, setBaseColor] = useState<string>(() => {
    const initialValue = getInitialValue("--base", BG_COLOR);
    return typeof initialValue === "string" ? initialValue : BG_COLOR;
  });
  • 可以用來設定圖片的樣式
  const imageStyle: React.CSSProperties = {
    padding: `${spacing}px`,
    backgroundColor: baseColor,
    filter: `blur(${blur}px)`,
  };

畫面結構

  • 在 TailwindCSS 裡面可以用 p-[var(--spacing)] 方式使用變數

    • 但要動態改變還是得用 style
  return (
    <div className="min-h-screen bg-gray-200 p-8">
      <div className="max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl">
        <div className="p-8">
          <div className="mb-4">
            <label
              htmlFor="spacing"
              className="block text-gray-700 text-sm font-bold mb-2"
            >
              Spacing: {spacing}px
            </label>
            <input
              id="spacing"
              type="range"
              min="10"
              max="200"
              value={spacing}
              onChange={(e) => setSpacing(Number(e.target.value))}
              className="w-full"
            />
          </div>

          <div className="mb-4">
            <label
              htmlFor="blur"
              className="block text-gray-700 text-sm font-bold mb-2"
            >
              Blur: {blur}px
            </label>
            <input
              id="blur"
              type="range"
              min="0"
              max="25"
              value={blur}
              onChange={(e) => setBlur(Number(e.target.value))}
              className="w-full"
            />
          </div>

          <div className="mb-4">
            <label
              htmlFor="base"
              className="block text-gray-700 text-sm font-bold mb-2"
            >
              Base Color
            </label>
            <input
              id="base"
              type="color"
              value={baseColor}
              onChange={(e) => setBaseColor(e.target.value)}
              className="w-full h-10"
            />
          </div>
        </div>

        <img
          src="https://plus.unsplash.com/premium_photo-1661873673782-88b30e6abef4/"
          alt="Sample"
          className="w-full h-auto p-[var(--spacing)] bg-[var(--base)] blur-[var(--base)]"
          style={imageStyle}
        />
      </div>
    </div>
  );

DEMO

https://codesandbox.io/p/devbox/5wh5nq

總結

  • input type=”color” 會有原生的調色盤可以使用

  • TailwindCSS 使用變數的方式 p-[var(--spacing)]

  • getComputedStylegetPropertyValue 可以用來取出 CSS

const value = getComputedStyle(document.documentElement)
      .getPropertyValue(varName)
      .trim();

上一篇
[Day02]_Clock
下一篇
[Day04]_Array-Cardio-Day1
系列文
React30——用 React 探索 JavaScript30 的魅力30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言