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

React集成CSS Paint API:无编译错误但效果不显示的问题

问题:React 结合 CSS Paint API 基础示例无效果

我正在搭建 React 与 CSS Paint API 结合的基础示例,目前没有编译错误,但预期的图案效果无法显示。相关文件内容如下:

1. index.html 中的脚本

<script>
CSS.paintWorklet.addModule('%PUBLIC_URL%/paintWorklet.js');
</script>

2. public/paintWorklet.js 代码

class Shape {
  paint(ctx, geom, properties) {
    ctx.strokeStyle = 'red';
    ctx.lineWidth = 4;
    ctx.beginPath();
    ctx.arc(200, 200, 50, 0, 2 * Math.PI);
    ctx.stroke();
    ctx.closePath();
  }
}

registerPaint('pattern', Shape);

3. App.tsx 组件

import React from 'react';
import './App.css';

const TestDiv = () => {  
  return(
    <div className='TestDiv'>
      <h1>I am a TestDiv</h1>
    </div>
  )
}

function App() {
  return (
    <div className="App">
      <TestDiv />
    </div>
  );
}

export default App;

4. App.css 样式

.TestDiv {
  background: paint(pattern);
}

我已经尝试过将 worklet 文件移到 src 目录、在 React 组件的 useEffect 中引入 worklet,但都没有效果。奇怪的是,如果在 index.html 中给 body 添加如下样式,图案可以正常显示:

<style>
  body {
    margin: 0;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: paint(pattern);
  }
</style>

解决思路

1. 给目标元素设置明确尺寸

.TestDiv 默认没有宽高,背景绘制需要元素有可见的空间才能展示。直接给元素添加宽高样式:

.TestDiv {
  background: paint(pattern);
  width: 400px;
  height: 400px;
}

2. 适配元素尺寸绘制图案

你当前的 worklet 用了固定坐标 (200,200),如果元素尺寸小于 400x400,圆形会被裁到元素外面,看起来就像没显示。改成基于元素自身尺寸绘制:

class Shape {
  paint(ctx, geom, properties) {
    // 以元素中心为圆心
    const centerX = geom.width / 2;
    const centerY = geom.height / 2;
    // 半径取元素最小边的一半,留出线条宽度的空间
    const radius = Math.min(centerX, centerY) - 2;

    ctx.strokeStyle = 'red';
    ctx.lineWidth = 4;
    ctx.beginPath();
    ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
    ctx.stroke();
    ctx.closePath();
  }
}

registerPaint('pattern', Shape);

3. 确保 Worklet 加载完成后再渲染元素

React 组件可能在 worklet 注册完成前就渲染了,导致样式不生效。用 useEffect 等待加载完成:

import React, { useState, useEffect } from 'react';
import './App.css';

const TestDiv = () => {
  const [workletReady, setWorkletReady] = useState(false);

  useEffect(() => {
    async function loadWorklet() {
      await CSS.paintWorklet.addModule(`${process.env.PUBLIC_URL}/paintWorklet.js`);
      setWorkletReady(true);
    }
    loadWorklet();
  }, []);

  if (!workletReady) return null;

  return(
    <div className='TestDiv'>
      <h1>I am a TestDiv</h1>
    </div>
  )
}

function App() {
  return (
    <div className="App">
      <TestDiv />
    </div>
  );
}

export default App;

4. 检查浏览器兼容性

CSS Paint API 目前仅支持 Chromium 系浏览器(Chrome、Edge 等),Firefox 和 Safari 需要开启实验性特性才能使用,换个浏览器测试看看。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 19:13:17