无法导入 css houdini paint js 文件
Can't import css houdini paint js file
我有一个 React/Electron 应用程序,我正在尝试使用新的 CSS Houdini paint()
功能(如 in this page 所示)。在我项目的 index.html
文件中,我添加了一个带有 paintWorklet addModule()
函数的脚本标签,如下所示:
<script>
CSS.paintWorklet.addModule('../src/ResultDisplay/DefaultResultDisplay/testPaint.js');
</script>
然后在该 testPaint.js
文件中,我基本上拥有该博客中显示内容的副本 post:
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` file is never showed.
我尝试了 addModule
文件路径的多种变体;我试过 testPaint.js
,同时使用 ./src
和 src
启动它,但似乎没有任何效果;这在 Electron/React 应用程序中可能吗?
addModule 函数将无法通过 webpack 或其他捆绑器工作,而是通过浏览器的本机模块系统工作。您必须将 testPaint.js
文件放在 public 目录中,否则它将与其他所有内容捆绑在一起。
这是我添加到 index.html 以将其从本地 Create React App 项目的 public 目录添加到 运行 的内容:
<script>
CSS.paintWorklet.addModule('%PUBLIC_URL%/testPaint.js');
</script>
我实际上并没有设置任何标记,只是添加了容器 class 来测试它:
如果你想在不通过 public 文件夹的情况下使用它(因为通常你必须在 index.html 中添加绘画模块,这会改变 public 目录),那么我建议使用 React Helmet 来设置脚本标签。请注意,CRA 的 hot-reload 功能似乎会阻止脚本更新,因此每次更改脚本标签时,您都需要手动刷新页面。
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')
);
如果您希望避免使用 /public,您可以使用像 Yarn Workspaces 这样的 monorepo 管理器将您的工作集保存在一个专用包中。然后,您可以将它导入您的客户端应用程序,就像导入任何其他包依赖项一样。
循序渐进(使用 Yarn Workspaces):
- 为您的应用程序(package.json 名称为@packages/myapp)和工作集(@packages/myworklet)创建专用包
- 将您的工作集添加为应用程序的依赖项 -- from @packages/myapp 运行 yarn add @packages/myworklet
- 从@packages/myworklet导入您的工作集并添加它——参见https://houdini.how/usage/
我有一个 React/Electron 应用程序,我正在尝试使用新的 CSS Houdini paint()
功能(如 in this page 所示)。在我项目的 index.html
文件中,我添加了一个带有 paintWorklet addModule()
函数的脚本标签,如下所示:
<script>
CSS.paintWorklet.addModule('../src/ResultDisplay/DefaultResultDisplay/testPaint.js');
</script>
然后在该 testPaint.js
文件中,我基本上拥有该博客中显示内容的副本 post:
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` file is never showed.
我尝试了 addModule
文件路径的多种变体;我试过 testPaint.js
,同时使用 ./src
和 src
启动它,但似乎没有任何效果;这在 Electron/React 应用程序中可能吗?
addModule 函数将无法通过 webpack 或其他捆绑器工作,而是通过浏览器的本机模块系统工作。您必须将 testPaint.js
文件放在 public 目录中,否则它将与其他所有内容捆绑在一起。
这是我添加到 index.html 以将其从本地 Create React App 项目的 public 目录添加到 运行 的内容:
<script>
CSS.paintWorklet.addModule('%PUBLIC_URL%/testPaint.js');
</script>
我实际上并没有设置任何标记,只是添加了容器 class 来测试它:
如果你想在不通过 public 文件夹的情况下使用它(因为通常你必须在 index.html 中添加绘画模块,这会改变 public 目录),那么我建议使用 React Helmet 来设置脚本标签。请注意,CRA 的 hot-reload 功能似乎会阻止脚本更新,因此每次更改脚本标签时,您都需要手动刷新页面。
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')
);
如果您希望避免使用 /public,您可以使用像 Yarn Workspaces 这样的 monorepo 管理器将您的工作集保存在一个专用包中。然后,您可以将它导入您的客户端应用程序,就像导入任何其他包依赖项一样。
循序渐进(使用 Yarn Workspaces):
- 为您的应用程序(package.json 名称为@packages/myapp)和工作集(@packages/myworklet)创建专用包
- 将您的工作集添加为应用程序的依赖项 -- from @packages/myapp 运行 yarn add @packages/myworklet
- 从@packages/myworklet导入您的工作集并添加它——参见https://houdini.how/usage/