1

我有一个 React/Electron 应用程序,我正在尝试使用新的 CSS Houdinipaint()功能(如本页所示)。在我的项目index.html文件中,我添加了一个带有 paintWorkletaddModule()函数的脚本标记,如下所示:

<script>
  CSS.paintWorklet.addModule('../src/ResultDisplay/DefaultResultDisplay/testPaint.js');
</script>

然后在该testPaint.js文件中,我基本上拥有该博客文章中显示的内容的副本:

registerPaint(
  "testPaint",
  class {
    paint(ctx, geom) {
      console.log("painting!!!");
      const circleSize = 10;
      const bodyWidth = geom.width;
      const bodyHeight = geom.height;

      const maxX = Math.floor(bodyWidth / circleSize);
      const maxY = Math.floor(bodyHeight / circleSize);

      for (let y = 0; y < maxY; y++) {
        for (let x = 0; x < maxX; x++) {
          ctx.fillStyle = "blue";
          ctx.beginPath();
          ctx.arc(
            x * circleSize * 2 + circleSize,
            y * circleSize * 2 + circleSize,
            circleSize,
            0,
            2 * Math.PI,
            true
          );
          ctx.closePath();
          ctx.fill();
        }
      }
    }
  }
);

最后是我的css文件:

.container {
  background-image: paint(testPaint);
  display: flex;
  margin: 4px;
  border-radius: 12px;
  height: 75px;
}

我应该指出我正在使用 CSS 模块,所以这个文件是defaultResultStyles.module.scss; 不确定这是否会影响任何事情。当我在我的应用程序中调出本应具有这些样式的组件时,它没有样式,尽管检查它,它确实显示background-image: paint(testPaint). The console.log that I added to the testPaint.js` 文件从未显示。

我已经尝试了文件路径的多种变体addModule;我试过 just testPaint.js,从./srcand开始src,但似乎没有任何效果;这在 Electron/React 应用程序中可行吗?

4

2 回答 2

2

addModule 函数不能通过 webpack 或其他捆绑器工作,而是通过浏览器的本机模块系统工作。您必须将testPaint.js文件放在公共目录中,否则它将与其他所有内容捆绑在一起。

这是我添加到 index.html 的内容,以使其从本地 Create React App 项目的公共目录中运行:

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

我实际上并没有设置任何标记,只是添加了容器类来测试它: 在此处输入图像描述


如果您想在不通过公用文件夹的情况下使用它(因为通常您必须在更改公用目录的 index.html 中添加绘图模块),那么我建议使用React Helmet进行设置起来脚本标签。需要注意的是,CRA 的热重载功能似乎会阻止脚本更新,因此每次更改脚本标签时,都需要手动刷新页面。

import React from 'react';
import { render } from 'react-dom';
import { Helmet } from 'react-helmet';
import styled from 'styled-components';

// Render these styled components like normal react components.
// They will pass on all props and work
// like normal react components – except they're styled!
const Demo = styled.div`
  background: #1108a0;
  padding: 50px 0;
`;
const Test = styled.div`
  --color: cyan;
  --multiplier: 0.24;
  --pad: 30;
  --slant: 20;
  background: paint(background-canvas);
  transition: --multiplier 0.4s;
  font: bold 6em sans-serif;
  color: yellow;
  text-shadow: 0 3px 1px cyan;
  line-height: 1.5em;
  width: max-content;
  padding-left: 30px;
  padding-right: 50px;
  isolation: isolate;
  &:hover {
    --multiplier: 1;
  }
  & span {
    mix-blend-mode: exclusion;
  }
`;
export const App = () => (
  <Demo>
    <Test className="el" right={'right'}>
      <span>JS-in-CSS</span>
    </Test>
  </Demo>
);
export const Helm = () => (
  <Helmet>
    <script language="javascript+paint">{`
  registerPaint('background-canvas', class {
  static get inputProperties() {
      return ['--multiplier', '--color', '--pad', '--slant'];
  }
  paint(ctx, geom, properties) {
    let multiplier = +properties.get('--multiplier').toString();
    let c = properties.get('--color').toString();
    let pad = +properties.get('--pad').toString();
    let slant = +properties.get('--slant').toString();
    ctx.moveTo(0, 0);
    ctx.lineTo(pad + (geom.width - slant - pad) * multiplier, 0);
    ctx.lineTo(pad + (geom.width - slant - pad) * multiplier + slant, geom.height);
    ctx.lineTo(0, geom.height);
    ctx.fillStyle = c;
    ctx.fill();
  }
})
`}</script>

    <script>{`
  if ("paintWorklet" in CSS) {
  const src = document.querySelector('script[language$="paint"]').innerHTML;
  const blob = new Blob([src], {
    type: 'text/javascript'
  });
  CSS.paintWorklet.addModule(URL.createObjectURL(blob));
}
`}</script>
  </Helmet>
);
render(
  <div>
    <Helm />
    <App />
  </div>,
  document.getElementById('root')
);

于 2020-11-09T14:55:12.507 回答
0

如果你想避免使用 /public,你可以使用像 Yarn Workspaces 这样的 monorepo 管理器来将你的工作集保存在一个专用的包中。然后,您可以像导入任何其他包依赖项一样将其导入您的客户端应用程序。

一步一步(使用纱线工作区):

  1. 为您的应用程序(package.json 名称为 @packages/myapp)和工作包(@packages/myworklet)创建专用包
  2. 将您的工作集添加为您的应用程序的依赖项——从 @packages/myapp 运行 yarn add @packages/myworklet
  3. 从 @packages/myworklet 导入您的工作集并添加它 - 请参阅https://houdini.how/usage/
于 2022-01-19T17:49:37.927 回答