canvas2svg icon indicating copy to clipboard operation
canvas2svg copied to clipboard

Transformation order

Open mudcube opened this issue 8 years ago • 3 comments

Although this is valid Canvas operation the following results in the error "Attempted to apply path command to node g":

var ctx = new C2S()
ctx.rect(0, 0, 100, 100)
ctx.scale(2, 2)
ctx.fill()
ctx.getSerializedSvg()

I'll investigate into why this is happening.

mudcube avatar Aug 13 '16 21:08 mudcube

Made some headway on this: https://github.com/mudcube/canvas2svg/commit/c7df7fa81e9d8b392d0fc2a894f72af7ba54e306

mudcube avatar Aug 14 '16 00:08 mudcube

I'm still getting the dreaded "Attempted to apply path command to node g" error, even on the latest version on master.

Apparently, the error occurs whenever you perform a ctx.save() immediately before a ctx.fill(). e.g.

const { document } = (new JSDOM('')).window;
const ctx = new C2S({
    document,
    width: 500,
    height: 500,
});
ctx.beginPath();
ctx.rect(20, 20, 150, 100);
ctx.fillStyle = "red";
ctx.save();
ctx.fill();

It will error out on the fill. Also note that it isn't a node issue, because I get the exact same error when trying in a browser. Does anyone have any ideas or workarounds?

Zamiell avatar May 06 '19 22:05 Zamiell

For whoever is interested, this is a quick hotfix for the for ctx.save() issue with Paths:

const save = Context.prototype.save;
Context.prototype.save = function () {
  /**
   * @PATCH Keep the path as `__currentElement` so that `ctx.fill()` triggering `__applyCurrentDefaultPath`
   * won't error
   */
  if (this.__currentElement.nodeName === "path") {
    !this.prevented && (this.prevented = 0);
    this.prevented += 1;
    return;
  }

  save.call(this)
};

const restore = Context.prototype.restore;
Context.prototype.restore = function () {
  /** @PATCH Check if this `ctx.restore()` was prevented */
  if (this.__currentElement.nodeName === "path" && this.prevented) {
    this.prevented -= 1;
    return;
  }

  restore.call(this)
};

But if possible it's preferrable to avoid calling ctx.save/restore() while a path is not closed yet. It's typically not necessary as well.

jiayihu avatar Feb 23 '24 11:02 jiayihu