Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image 支持 node-canvas 服务端渲染 #1344

Closed
xiaoiver opened this issue May 19, 2023 · 2 comments
Closed

Image 支持 node-canvas 服务端渲染 #1344

xiaoiver opened this issue May 19, 2023 · 2 comments
Assignees

Comments

@xiaoiver
Copy link
Contributor

xiaoiver commented May 19, 2023

之前 Image 其实已经支持了服务端渲染,配合 node-canvas 提供的 Image

https://github.com/antvis/G/blob/next/__tests__/integration/__node__tests__/canvas/image.spec.js

const { createCanvas, Image: CanvasImage } = require('canvas');

const canvas = new Canvas({
  width: SIZE,
  height: SIZE,
  canvas: nodeCanvas, // 使用 node-canvas
  renderer,
  createImage: () => { // 使用 node-canvas 提供的 Image 创建,代替浏览器环境的 Image
    const image = new CanvasImage();
    return image;
  },
});

但由于 Image 加载是一个异步的过程(node-canvas 的实现也是如此):

Note: In some cases, img.src= is currently synchronous. However, you should always use img.onload and img.onerror, as we intend to make img.src= always asynchronous as it is in browsers. See Automattic/node-canvas#1007.

因此截图前需要等待一段时间。

@xiaoiver
Copy link
Contributor Author

xiaoiver commented May 19, 2023

但需要注意的是,如果希望设置 Image 的 src 为 canvas,jsdom 需要升级到 19.x 以上,才可以直接通过 document.createElement('canvas') 创建 node-canvas。否则会报错,例如 16.x 就不支持:

  console.error
    Error: Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)
        at module.exports (/Users/panyuqi/Documents/webgl/g/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/browser/not-implemented.js:9:17)
        at HTMLCanvasElementImpl.getContext (/Users/panyuqi/Documents/webgl/g/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/nodes/HTMLCanvasElement-impl.js:42:5)

@wang1212
Copy link
Member

Since the src value of the Image object instance returned by the loadImage() API of node-canvas is '', any Image instance is hit in the same cache (G caches image data internally with the value of src as the key). This is not the expected result.

We can solve it by manually assigning a value to src.

import { loadImage } from 'canvas';
import { Image } from '@antv/g';

const image = await loadImage(imgUrl);

// note: manually assigning a value to `src`
Object.defineProperty(image, 'src', { value: imgUrl });

const gimage = new Image({
  style: {
    x: i * 200,
    y: 256,
    width: image.width / 4,
    height: image.height / 4,
    src: image,
  },
});
gCanvas.appendChild(gimage);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants