1

I have a routine that attaches an image to my SVG canvas and on load, it creates a rectangle with rounded corners so I can clip the image. This is run multiple times, fed by an array of image addresses.

Method 1 - clipWith()

The clipping does work (the final image looks fine) but it's throwing errors in the console on the on the clipWith() line:

this.root() is null

Errors occur with each run through the same array of images but on different images each time.

const newImage = newNested.image(imageData, (e) => {
  const newWidth = e.target.naturalHeight;
  const newHeight = e.target.naturalWidth;
  const clipper = newNested.clip();
  clipper.rect(newWidth, newHeight).attr({ rx: 5, ry: 5 }).fill('#000');
  newImage.clipWith(clipper);
}

Method 2 - maskWith()

Same error as above whilst the output SVG is fine:

const newImage = newNested.image(imageData, (e) => {
  const newWidth = e.target.naturalHeight;
  const newHeight = e.target.naturalWidth;
  const masker = newNested.rect(newWidth, newHeight).attr({ rx: 5, ry: 5 }).fill('#000');
  newImage.maskWith(masker);
}

Method 3 - SVG.ClipPath()

I have also looked through the docs and the Github issues and found other ways to render a clipping mask:

const newImage = newNested.image(imageData, (e) => {
  const newWidth = e.target.naturalHeight;
  const newHeight = e.target.naturalWidth;
  const clipPath = new SVG.ClipPath();
  clipPath.rect(newWidth, newHeight).attr({ rx: imageNode.r, ry: imageNode.r }).fill('#000');
  newImage.clipWith(clipPath);
}

Yet this throws the following error:

 Uncaught TypeError: _svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_2__.SVG.ClipPath is not a constructor

And from looking at the docs, there is this one line that doesn't explain if this is related but trying it with SVGElement.ClipPath() got the same result:

Note: All properties that were former available on the global SVG object need to be imported now, see example below:

import { SVG, extend as SVGextend, Element as SVGElement } from'@svgdotjs/svg.js'

RieMars
  • 51
  • 5
  • It would be really helpful to have a [mre] here... – Robby Cornelissen Dec 08 '22 at 08:49
  • Also, the line in the docs suggest, that you need to import `{ ClipPath }` and use `new ClipPath()`. Also, you can stop execution in the debugger on error. Then you can check where it is actually happening and why – Fuzzyma Dec 08 '22 at 12:45
  • I guess I took the documentation too literally. The key problem above is the newImage object doesn't have a root() sometimes, which shows up when calling clipWith() & maskWith(). This routine above is deep in a renderer that can update very quickly depending on the data source. The error could be because the by the time the callback is called, the newImage reference isn't there as the whole SVG has been cleared and is being rewritten. I made a [JSFiddle](https://jsfiddle.net/fnkr5wvL/39/) to mimic the above code but couldn't replicate the error. – RieMars Dec 09 '22 at 01:01

0 Answers0