ag-psd
ag-psd copied to clipboard
how to get real vector mask shape
The vector mask is a white background
And I can get vector mask path , but the path seems incomplete,I can't know the line is curve
What can I do to get the real vector mask shape to compose and clip two canvas,
Each of the knots represents point with 2 control handles like this
So it's x & y of 1st control point, then x & y of the actual point and then x & y 2nd control point
The basic idea is that photoshop has:
control-point -> point -> control-point
and in HTML canvas you have
control-point -> control-point -> point
You can use it like this
context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
Each of the knots represents point with 2 control handles like this
So it's x & y of 1st control point, then x & y of the actual point and then x & y 2nd control point
The basic idea is that photoshop has:
control-point -> point -> control-point
and in HTML canvas you havecontrol-point -> control-point -> point
You can use it like thiscontext.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
yeah!thank you!it seems work.but I don't know if it's my reason. Aftrer parsing the curve is different.
This is the original:
And this is the result
Did I do something wrong...
paste your code and I'll check it
paste your code and I'll check it
that's my code and thank you:
const {canvas} = layer
const newCanvas = document.createElement('canvas')
const ctx = newCanvas.getContext('2d')
if(layer.mask && layer.vectorMask){
newCanvas.width = canvas!.width
newCanvas.height = canvas!.height
const knots = layer.vectorMask.paths[0]?.knots.map(it=>{
const newPoints = it.points.map((point,index)=>{
if(index%2 === 0){
return point - layer.left!
}else{
return point - layer.top!
}
})
return {...it, points : newPoints}
})
ctx?.beginPath()
for(let i = 0;i<knots.length;i++){
const cp1x = Math.floor(knots[i].points[0])
const cp1y = Math.floor(knots[i].points[1])
const cp2x = Math.floor(knots[i].points[4])
const cp2y = Math.floor(knots[i].points[5])
const x = Math.floor(knots[i].points[2])
const y = Math.floor(knots[i].points[3])
ctx?.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
}
ctx?.closePath()
ctx?.clip()
ctx?.drawImage(canvas!, 0, 0)
return newCanvas
}
Ok, so a little bit more details: in photoshop knots relate to points, but in HTML canvas it's curves with control points. to draw a curve you need one control point from previous knot, like this:
const cp1x = Math.floor(knots[i - 1].points[4])
const cp1y = Math.floor(knots[i - 1].points[5])
const cp2x = Math.floor(knots[i].points[0])
const cp2y = Math.floor(knots[i].points[1])
const x = Math.floor(knots[i].points[2])
const y = Math.floor(knots[i].points[3])
ctx?.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
So you'll have to start from 2nd knot, not the first one, and then ad the end wrap it back to the first knot
You probably also shouldn't floor the coordinates, that will distort the shape.
Ok, so a little bit more details: in photoshop knots relate to points, but in HTML canvas it's curves with control points. to draw a curve you need one control point from previous knot, like this:
const cp1x = Math.floor(knots[i - 1].points[4]) const cp1y = Math.floor(knots[i - 1].points[5]) const cp2x = Math.floor(knots[i].points[0]) const cp2y = Math.floor(knots[i].points[1]) const x = Math.floor(knots[i].points[2]) const y = Math.floor(knots[i].points[3]) ctx?.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
So you'll have to start from 2nd knot, not the first one, and then ad the end wrap it back to the first knot
thank you so much ,your tips are very useful ! I‘m very new to PS, very sorry and I have a little question here.
I found a very strange problem,It seems that the last curve is a little wrong
and here is my code:
for(let i = 0;i<knots.length;i++){
const preIndex = i === 0?knots.length - 1:i - 1
const cp1x = knots[preIndex].points[4]
const cp1y = knots[preIndex].points[5]
const cp2x = knots[i].points[0]
const cp2y = knots[i].points[1]
const x = knots[i].points[2]
const y = knots[i].points[3]
ctx?.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
}
You need to set the starting point correctly before starting the loop:
ctx?.moveTo(knots[knots.length - 1].points[2], knots[knots.length - 1].points[3])
You need to set the starting point correctly before starting the loop:
ctx?.moveTo(knots[knots.length - 1].points[2], knots[knots.length - 1].points[3])
it works! thank you very much