Không thể nhập tệp css houdini paint js

Nov 08 2020

Tôi có một ứng dụng React / Electron, nơi tôi đang cố gắng sử dụng paint()chức năng CSS Houdini mới (như được trình bày trong trang này ). Trong index.htmltệp dự án của tôi, tôi đã thêm một thẻ script có addModule()chức năng paintWorklet như được hiển thị:

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

Sau đó, trong testPaint.jstệp đó về cơ bản, tôi có một bản sao của những gì được hiển thị trong bài đăng blog đó:

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();
        }
      }
    }
  }
);

Và cuối cùng là tệp css của tôi:

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

Tôi nên chỉ ra rằng tôi đang sử dụng Mô-đun CSS, vì vậy tệp này là defaultResultStyles.module.scss; không chắc điều đó có ảnh hưởng gì không. Khi tôi hiển thị thành phần có nghĩa là có các kiểu này trong ứng dụng của mình, nó không có kiểu nào, mặc dù khi kiểm tra nó, nó không background-image: paint(testPaint). The console.log that I added to the bao giờ hiển thị tệp testPaint.js`.

Tôi đã thử nhiều biến thể của đường dẫn tệp cho addModule; Tôi đã thử chỉ testPaint.js, bắt đầu nó với ./srcsrccả hai, nhưng dường như không có gì hiệu quả; Điều này có khả thi trong ứng dụng Electron / React không?

Trả lời

1 ZacharyHaber Nov 09 2020 at 14:55

Hàm addModule sẽ không hoạt động thông qua webpack hoặc các gói khác, thay vào đó nó hoạt động thông qua hệ thống mô-đun gốc của trình duyệt. Bạn phải đặt testPaint.jstệp trong thư mục công khai, nếu không nó sẽ bị đóng gói với mọi thứ khác.

Đây là những gì tôi đã thêm vào index.html để làm cho nó chạy từ thư mục công khai trên một dự án Tạo ứng dụng React cục bộ:

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

Tôi đã không thiết lập thực tế bất kỳ đánh dấu nào và chỉ thêm lớp vùng chứa để kiểm tra nó:


Nếu bạn muốn sử dụng điều này mà không cần đi qua thư mục công cộng (vì thông thường bạn phải thêm mô-đun paint trong index.html đang thay đổi thư mục công khai), thì tôi khuyên bạn nên sử dụng React Helmet để thiết lập lên các thẻ script. Cần lưu ý điều này, các tính năng tải lại nóng của CRA dường như ngăn các tập lệnh cập nhật, vì vậy mỗi khi bạn thay đổi các thẻ tập lệnh, bạn sẽ cần phải làm mới trang theo cách thủ công.

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