无法导入CSS Houdini Paint JS文件 [英] Can't import css houdini paint js file

查看:66
本文介绍了无法导入CSS Houdini Paint JS文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个React/Electron应用程序,我试图在其中使用新的CSS Houdini paint()函数(如


如果您要使用该功能而不需要通过公用文件夹(完全是因为通常必须在更改公用目录的index.html中添加绘画模块),那么我建议使用反应头盔来设置脚本标签.值得注意的是,CRA的热重装功能似乎阻止了脚本的更新,因此,每次更改脚本标记时,都需要手动刷新页面.

  import从'react'导入React;从'react-dom'导入{render};从'react-helmet'导入{头盔};从'styled-components'导入样式;//渲染这些样式化的组件,就像普通的react组件一样.//他们将传递所有道具和工作//像普通的react组件一样-除了它们的样式!const Demo = styled.div`背景:#1108a0;填充:50px 0;`;const Test = styled.div`--color:青色;-乘数:0.24;-垫:30;-倾斜:20;背景:油漆(background-canvas);过渡:-乘数0.4s;字体:粗体6em sans-serif;颜色:黄色;文字阴影:0 3px 1px青色;行高:1.5em;宽度:最大含量;padding-left:30px;padding-right:50像素;隔离&:hover {-乘数:1;}&跨度 {混合混合模式:排除;}`;导出const App =()=>(< Demo>< Test className ="el"right = {'right'}>< span> JS-in-CSS</span></Test></Demo>);export const Helm =()=>(<头盔>< script language =" javascript + paint"> {`registerPaint('background-canvas',class {静态获取inputProperties(){return ['--multiplier','--color','--pad','--slant'];}油漆(ctx,geom,属性){let multiplier = + properties.get('-multiplier').toString();让c = properties.get('-color').toString();让pad = + properties.get('-pad').toString();let slant = + properties.get('-slant').toString();ctx.moveTo(0,0);ctx.lineTo(pad +(geom.width-倾斜-pad)*乘数,0);ctx.lineTo(pad +(geom.width-倾斜-pad)*乘数+倾斜,geom.height);ctx.lineTo(0,geom.height);ctx.fillStyle = c;ctx.fill();}})`}</script>< script> {`if(CSS中的"paintWorklet"){const src = document.querySelector('script [language $ ='"paint"]').innerHTML;const blob = new Blob([src],{类型:文字/javascript"});CSS.paintWorklet.addModule(URL.createObjectURL(blob));}`}</script></头盔>);使成为(< div><头盔/>< App/></div> ;,document.getElementById('root')); 

I have a React/Electron app, where I'm trying to use the new CSS Houdini paint() function (as demonstrated in this page). In my project's index.html file I have added a script tag with the paintWorklet addModule() function as shown:

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

Then in that testPaint.js file I have essentially a copy of what's shown in that blog 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();
        }
      }
    }
  }
);

And finally my css file:

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

I should point out I am using CSS Modules, so this file is defaultResultStyles.module.scss; not sure if that affects anything. When I bring up the component that's meant to have these styles in my app, it has no styles, though inspecting it, it does display background-image: paint(testPaint). The console.log that I added to the testPaint.js` file is never shown.

I have tried multiple variations of the filepath for addModule; I've tried just testPaint.js, starting it with ./src and src both, but nothing seems to work; is this possible in an Electron/React app?

解决方案

The addModule function will not work through webpack or other bundlers, it instead works through the native module system of browsers. You have to put the testPaint.js file in the public directory, otherwise it would get bundled with everything else.

Here's what I added to the index.html to get it to run from the public directory on a local Create React App project:

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

I didn't actuallly set up any of the markup and just added the container class to test it out:


If you want to use this without going through the public folder (at all, because normally you'd have to add the paint module in the index.html which is changing the public directory), then I'd suggest using React Helmet to set up the script tags. As a note with this, the hot-reload features of CRA seems to prevent the scripts from updating, so every time you change the script tags, you'll need to refresh the page manually.

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')
);

这篇关于无法导入CSS Houdini Paint JS文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆