Support addPath
properly.
However this is not correctly handling the transform. To do it correctly we need to store the sub-paths in the path in their original form (not a string) and apply the transforms at render time.
This commit is contained in:
parent
cc6973fa1c
commit
a891b0ad58
92
context.js
92
context.js
@ -92,30 +92,30 @@ export default (function () {
|
|||||||
// entity mapping courtesy of tinymce
|
// entity mapping courtesy of tinymce
|
||||||
namedEntities = createNamedToNumberedLookup(
|
namedEntities = createNamedToNumberedLookup(
|
||||||
"50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy," +
|
"50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy," +
|
||||||
"5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute," +
|
"5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute," +
|
||||||
"5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34," +
|
"5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34," +
|
||||||
"5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil," +
|
"5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil," +
|
||||||
"68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde," +
|
"68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde," +
|
||||||
"6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute," +
|
"6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute," +
|
||||||
"6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml," +
|
"6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml," +
|
||||||
"75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc," +
|
"75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc," +
|
||||||
"7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash," +
|
"7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash," +
|
||||||
"7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta," +
|
"7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta," +
|
||||||
"sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu," +
|
"sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu," +
|
||||||
"st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi," +
|
"st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi," +
|
||||||
"t9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota," +
|
"t9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota," +
|
||||||
"tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau," +
|
"tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau," +
|
||||||
"u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip," +
|
"u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip," +
|
||||||
"81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym," +
|
"81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym," +
|
||||||
"8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr," +
|
"8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr," +
|
||||||
"8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod," +
|
"8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod," +
|
||||||
"8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup," +
|
"8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup," +
|
||||||
"8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4," +
|
"8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4," +
|
||||||
"nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob," +
|
"nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob," +
|
||||||
"rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0," +
|
"rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0," +
|
||||||
"Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm," +
|
"Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm," +
|
||||||
"80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger," +
|
"80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger," +
|
||||||
"811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro",
|
"811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro",
|
||||||
32
|
32
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -355,9 +355,9 @@ export default (function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var element = this.__document.createElementNS(
|
var element = this.__document.createElementNS(
|
||||||
"http://www.w3.org/2000/svg",
|
"http://www.w3.org/2000/svg",
|
||||||
elementName
|
elementName
|
||||||
),
|
),
|
||||||
keys = Object.keys(properties),
|
keys = Object.keys(properties),
|
||||||
i,
|
i,
|
||||||
key;
|
key;
|
||||||
@ -775,12 +775,26 @@ export default (function () {
|
|||||||
path = this.__currentDefaultPath;
|
path = this.__currentDefaultPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pathElement = this.__createPathElement();
|
if (path.__pathString.length > 0) {
|
||||||
this.__applyStyleToElement(pathElement, action);
|
var pathElement = this.__createPathElement();
|
||||||
pathElement.setAttribute("paint-order", "fill stroke markers");
|
this.__applyStyleToElement(pathElement, action);
|
||||||
pathElement.setAttribute("d", path.__pathString);
|
pathElement.setAttribute("paint-order", "fill stroke markers");
|
||||||
|
pathElement.setAttribute("d", path.__pathString);
|
||||||
|
if (path2d) {
|
||||||
|
this.__applyTransformation(pathElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (path2d) {
|
if (path2d) {
|
||||||
this.__applyTransformation(pathElement);
|
path2d.__subPaths.forEach((subPath) => {
|
||||||
|
var pathElement = this.__createPathElement();
|
||||||
|
this.__applyStyleToElement(pathElement, action);
|
||||||
|
pathElement.setAttribute("paint-order", "fill stroke markers");
|
||||||
|
pathElement.setAttribute("d", subPath.path.__pathString);
|
||||||
|
if (subPath.transform) {
|
||||||
|
this.__applyTransformation(pathElement, this.getTransform().multiply(subPath.transform));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1160,9 +1174,9 @@ export default (function () {
|
|||||||
*/
|
*/
|
||||||
Context.prototype.createPattern = function (image, repetition) {
|
Context.prototype.createPattern = function (image, repetition) {
|
||||||
var pattern = this.__document.createElementNS(
|
var pattern = this.__document.createElementNS(
|
||||||
"http://www.w3.org/2000/svg",
|
"http://www.w3.org/2000/svg",
|
||||||
"pattern"
|
"pattern"
|
||||||
),
|
),
|
||||||
id = randomString(this.__ids),
|
id = randomString(this.__ids),
|
||||||
img;
|
img;
|
||||||
pattern.setAttribute("id", id);
|
pattern.setAttribute("id", id);
|
||||||
@ -1351,10 +1365,10 @@ export default (function () {
|
|||||||
/**
|
/**
|
||||||
* Not yet implemented
|
* Not yet implemented
|
||||||
*/
|
*/
|
||||||
Context.prototype.drawFocusRing = function () {};
|
Context.prototype.drawFocusRing = function () { };
|
||||||
Context.prototype.createImageData = function () {};
|
Context.prototype.createImageData = function () { };
|
||||||
Context.prototype.putImageData = function () {};
|
Context.prototype.putImageData = function () { };
|
||||||
Context.prototype.globalCompositeOperation = function () {};
|
Context.prototype.globalCompositeOperation = function () { };
|
||||||
|
|
||||||
return Context;
|
return Context;
|
||||||
})();
|
})();
|
||||||
|
28
path2d.js
28
path2d.js
@ -22,6 +22,7 @@ export default (function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
|
this.__subPaths = []; // Array of path string/transform pairs.
|
||||||
this.__currentPosition = { x: undefined, y: undefined };
|
this.__currentPosition = { x: undefined, y: undefined };
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -29,18 +30,19 @@ export default (function () {
|
|||||||
return this.ctx.__matrixTransform(x, y);
|
return this.ctx.__matrixTransform(x, y);
|
||||||
};
|
};
|
||||||
|
|
||||||
Path2D.prototype.addPath = function (path, transform) {
|
Path2D.prototype.addPath = function (path, transform = undefined) {
|
||||||
if (transform)
|
this.__subPaths.push({ path: path, transform: transform });
|
||||||
console.error("transform argument to addPath is not supported");
|
|
||||||
|
|
||||||
this.__pathString = this.__pathString + " " + path;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Path2D.prototype.appendPath = function (path) {
|
||||||
|
this.__pathString = this.__pathString + " " + path;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the current path
|
* Closes the current path
|
||||||
*/
|
*/
|
||||||
Path2D.prototype.closePath = function () {
|
Path2D.prototype.closePath = function () {
|
||||||
this.addPath("Z");
|
this.appendPath("Z");
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,7 +52,7 @@ export default (function () {
|
|||||||
Path2D.prototype.moveTo = function (x, y) {
|
Path2D.prototype.moveTo = function (x, y) {
|
||||||
// creates a new subpath with the given point
|
// creates a new subpath with the given point
|
||||||
this.__currentPosition = { x: x, y: y };
|
this.__currentPosition = { x: x, y: y };
|
||||||
this.addPath(
|
this.appendPath(
|
||||||
format("M {x} {y}", {
|
format("M {x} {y}", {
|
||||||
x: this.__matrixTransform(x, y).x,
|
x: this.__matrixTransform(x, y).x,
|
||||||
y: this.__matrixTransform(x, y).y,
|
y: this.__matrixTransform(x, y).y,
|
||||||
@ -64,14 +66,14 @@ export default (function () {
|
|||||||
Path2D.prototype.lineTo = function (x, y) {
|
Path2D.prototype.lineTo = function (x, y) {
|
||||||
this.__currentPosition = { x: x, y: y };
|
this.__currentPosition = { x: x, y: y };
|
||||||
if (this.__pathString.indexOf("M") > -1) {
|
if (this.__pathString.indexOf("M") > -1) {
|
||||||
this.addPath(
|
this.appendPath(
|
||||||
format("L {x} {y}", {
|
format("L {x} {y}", {
|
||||||
x: this.__matrixTransform(x, y).x,
|
x: this.__matrixTransform(x, y).x,
|
||||||
y: this.__matrixTransform(x, y).y,
|
y: this.__matrixTransform(x, y).y,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.addPath(
|
this.appendPath(
|
||||||
format("M {x} {y}", {
|
format("M {x} {y}", {
|
||||||
x: this.__matrixTransform(x, y).x,
|
x: this.__matrixTransform(x, y).x,
|
||||||
y: this.__matrixTransform(x, y).y,
|
y: this.__matrixTransform(x, y).y,
|
||||||
@ -101,7 +103,7 @@ export default (function () {
|
|||||||
*/
|
*/
|
||||||
Path2D.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {
|
Path2D.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {
|
||||||
this.__currentPosition = { x: x, y: y };
|
this.__currentPosition = { x: x, y: y };
|
||||||
this.addPath(
|
this.appendPath(
|
||||||
format("C {cp1x} {cp1y} {cp2x} {cp2y} {x} {y}", {
|
format("C {cp1x} {cp1y} {cp2x} {cp2y} {x} {y}", {
|
||||||
cp1x: this.__matrixTransform(cp1x, cp1y).x,
|
cp1x: this.__matrixTransform(cp1x, cp1y).x,
|
||||||
cp1y: this.__matrixTransform(cp1x, cp1y).y,
|
cp1y: this.__matrixTransform(cp1x, cp1y).y,
|
||||||
@ -118,7 +120,7 @@ export default (function () {
|
|||||||
*/
|
*/
|
||||||
Path2D.prototype.quadraticCurveTo = function (cpx, cpy, x, y) {
|
Path2D.prototype.quadraticCurveTo = function (cpx, cpy, x, y) {
|
||||||
this.__currentPosition = { x: x, y: y };
|
this.__currentPosition = { x: x, y: y };
|
||||||
this.addPath(
|
this.appendPath(
|
||||||
format("Q {cpx} {cpy} {x} {y}", {
|
format("Q {cpx} {cpy} {x} {y}", {
|
||||||
cpx: this.__matrixTransform(cpx, cpy).x,
|
cpx: this.__matrixTransform(cpx, cpy).x,
|
||||||
cpy: this.__matrixTransform(cpx, cpy).y,
|
cpy: this.__matrixTransform(cpx, cpy).y,
|
||||||
@ -180,7 +182,7 @@ export default (function () {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.lineTo(startX, startY);
|
this.lineTo(startX, startY);
|
||||||
this.addPath(
|
this.appendPath(
|
||||||
format(
|
format(
|
||||||
"A {rx} {ry} {xAxisRotation} {largeArcFlag} {sweepFlag} {endX} {endY}",
|
"A {rx} {ry} {xAxisRotation} {largeArcFlag} {sweepFlag} {endX} {endY}",
|
||||||
{
|
{
|
||||||
@ -370,7 +372,7 @@ export default (function () {
|
|||||||
this.lineTo(startX, startY);
|
this.lineTo(startX, startY);
|
||||||
this.ctx.__transformMatrix = currentTransform;
|
this.ctx.__transformMatrix = currentTransform;
|
||||||
|
|
||||||
this.addPath(
|
this.appendPath(
|
||||||
format(
|
format(
|
||||||
"A {rx} {ry} {xAxisRotation} {largeArcFlag} {sweepFlag} {endX} {endY}",
|
"A {rx} {ry} {xAxisRotation} {largeArcFlag} {sweepFlag} {endX} {endY}",
|
||||||
{
|
{
|
||||||
|
@ -45,4 +45,50 @@ export default function path2D(ctx) {
|
|||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
|
|
||||||
|
// Scaling path versus scaling the context.
|
||||||
|
const path2 = makePath(
|
||||||
|
ctx,
|
||||||
|
`M -10 -10
|
||||||
|
L 10 -10
|
||||||
|
L 10 10
|
||||||
|
L -10 10
|
||||||
|
Z`
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(25, 100);
|
||||||
|
ctx.scale(2, 1);
|
||||||
|
ctx.strokeStyle = "red";
|
||||||
|
ctx.moveTo(-10, -10);
|
||||||
|
ctx.lineTo(10, -10);
|
||||||
|
ctx.lineTo(10, 10);
|
||||||
|
ctx.lineTo(-10, 10);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fillStyle = "grey";
|
||||||
|
ctx.fill();
|
||||||
|
ctx.scale(1 / 2, 1); // Reset scale so that stroke is not scaled.
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.restore();
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(100, 100);
|
||||||
|
ctx.scale(2, 1);
|
||||||
|
ctx.fillStyle = "grey";
|
||||||
|
ctx.fill(path2);
|
||||||
|
ctx.strokeStyle = "red";
|
||||||
|
|
||||||
|
let pNext = makePath(ctx);
|
||||||
|
// add first path, transform path, twice size, move 100,10
|
||||||
|
pNext.addPath(path2, new DOMMatrix([
|
||||||
|
2, 0,
|
||||||
|
0, 1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
]));
|
||||||
|
|
||||||
|
ctx.scale(1 / 2, 1); // Reset scale so that stroke is not scaled.
|
||||||
|
ctx.stroke(pNext);
|
||||||
|
ctx.restore();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user