I have multiple Path2D in a single canvas and I want to be able to scale and position each of them independently rather than adjusting the context.scale() and context.translate(). I am constructing each path2D object with SVG path data because I want to be able to modify stroke-dash and stroke-length.
It seems like I might not be able to achieve this using Path2D, what's the best way to approach solving this?
I'm considering a few potential options:
Edit:
I built this code pen where I am trying to move p1 toward p2 without changing p2's position. When I translate the context, both objects move. What's the best way to adjust the position of p1 only?
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var p1x = 0
var p1 = new Path2D("M1 0 h 100 v 50 h -100 Z");
var p2 = new Path2D("M200 0 h 50 v 25 h -50 Z");
setInterval(() => {
p1x = p1x + 1
ctx.translate(0, 0)
ctx.clearRect(0, 0, 300, 300)
ctx.translate(p1x, 0)
ctx.fill(p1)
ctx.fill(p2)
}, 1000)
http://codepen.io/jasonpearson/pen/reXyVG
One could use the addPath
method in conjunction with the second transform-parameter to scale the path...
const m = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix()
const p = new Path2D()
const t = m.scale(0.5)
p.addPath(p1, t)
Example implementation:
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d")
var p1x = 0
var p1 = new Path2D("M1 0 h 100 v 50 h -100 Z")
var p2 = new Path2D("M200 0 h 50 v 25 h -50 Z")
var m = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix()
setInterval(() => {
p1x = p1x + 1
const p = new Path2D()
const t = m.translate(p1x, 0)
p.addPath(p1, t)
ctx.clearRect(0, 0, 300, 300)
ctx.fill(p)
ctx.fill(p2)
}, 1000)
canvas {
border: 1px solid blue;
height: 300px;
width: 300px;
}
<canvas id="canvas"></canvas>
Better implementation:
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d")
var p1 = new Path2D("M1 0 h 100 v 50 h -100 Z")
var p2 = new Path2D("M200 0 h 50 v 25 h -50 Z")
var m1 = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix()
setInterval(() => {
let p = new Path2D()
m1 = m1.translate(1, 0)
p.addPath(p1, m1)
ctx.clearRect(0, 0, 300, 300)
ctx.fill(p)
ctx.fill(p2)
}, 1000)
canvas {
border: 1px solid blue;
height: 300px;
width: 300px;
}
<canvas id="canvas"></canvas>
Just a little helper function for future uses:
function transformPath2D(path, matrix) {
const p = new Path2D()
p.addPath(path, matrix)
return p
}
You can apply the translation to just the first element:
setInterval(() => {
p1x = p1x + 1;
ctx.clearRect(0, 0, 300, 300);
ctx.save();
ctx.translate(p1x, 0);
ctx.fill(p1);
ctx.restore();
ctx.fill(p2);
}, 1000);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With