-
Notifications
You must be signed in to change notification settings - Fork 19
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
Calling Context.fill
with a path does not work
#20
Comments
I was able to bypass this issue with help of Proxy, this way works well with Note: it's just POC, this solution need some refactoring. Firstly i'd proxied three (that i used in my case) methods of Path2D's prototype: Path2D.prototype.moveTo = new Proxy(Path2D.prototype.moveTo, {
apply: function (target, thisArg: Path2D, args: [number, number]) {
if (!thisArg.operations) {
thisArg.operations = [];
}
thisArg.operations.push(['moveTo', args]);
Reflect.apply(target, thisArg, args);
},
});
Path2D.prototype.lineTo = new Proxy(Path2D.prototype.lineTo, {
apply: function (target, thisArg: Path2D, args: [number, number]) {
if (!thisArg.operations) {
thisArg.operations = [];
}
thisArg.operations.push(['lineTo', args]);
Reflect.apply(target, thisArg, args);
},
});
Path2D.prototype.bezierCurveTo = new Proxy(Path2D.prototype.bezierCurveTo, {
apply: function (
target,
thisArg: Path2D,
args: [number, number, number, number, number, number],
) {
if (!thisArg.operations) {
thisArg.operations = [];
}
thisArg.operations.push(['bezierCurveTo', args]);
Reflect.apply(target, thisArg, args);
},
}); Then i changed ctx.stroke = function (path?: Path2D) {
if (path?.operations) {
ctx.beginPath();
const operations = path.operations as (
| [operation: 'lineTo' | 'moveTo', args: [number, number]]
| [
operation: 'bezierCurveTo',
args: [number, number, number, number, number, number],
]
)[];
for (const operation of operations) {
switch (operation[0]) {
case 'lineTo': {
ctx.lineTo(...operation[1]);
break;
}
case 'moveTo': {
ctx.moveTo(...operation[1]);
break;
}
case 'bezierCurveTo': {
ctx.bezierCurveTo(...operation[1]);
break;
}
}
}
}
// Below is original code of `Context.stroke` method
if (this.__currentElement.nodeName === 'path') {
this.__currentElement.setAttribute('paint-order', 'fill stroke markers');
}
this.__applyCurrentDefaultPath();
this.__applyStyleToCurrentElement('stroke');
};
ctx.fill = function (
path?: Path2D | CanvasFillRule,
_fillRule?: CanvasFillRule,
) {
if (path?.operations) {
ctx.beginPath();
const operations = path.operations as (
| [operation: 'lineTo' | 'moveTo', args: [number, number]]
| [
operation: 'bezierCurveTo',
args: [number, number, number, number, number, number],
]
)[];
for (const operation of operations) {
switch (operation[0]) {
case 'lineTo': {
ctx.lineTo(...operation[1]);
break;
}
case 'moveTo': {
ctx.moveTo(...operation[1]);
break;
}
case 'bezierCurveTo': {
ctx.bezierCurveTo(...operation[1]);
break;
}
}
}
}
// Below is original code of `Context.fill` method
if (this.__currentElement.nodeName === 'path') {
this.__currentElement.setAttribute('paint-order', 'stroke fill markers');
}
this.__applyCurrentDefaultPath();
this.__applyStyleToCurrentElement('fill');
}; |
In the end the easiest fix it to draw using the Path commands ( |
The Canvas API supports passing a
Path2D
object tofill
andstroke
. This is not handled by svgcanvas.Unfortunately it doesn't look like it could be easily supported since there is no way to extract the path definition from the
Path2D
object.One approach might be to mock the
Path2D
object too so that the calls that construct the path can be recorded.The text was updated successfully, but these errors were encountered: