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
相关产品推荐
相关产品推荐

