Open fzlee opened 4 years ago
Yes, this seems like some matrices are not applied in the correct order.
This issue is stale because it has been open 90 days with no activity. It will be closed soon. Please comment/reopen if this issue is still relevant.
It appears the matrix application is fine. The problem to me seems that the text functions always apply the matrix to the lower-left corner of the bounding box of the text to find the new center point, then call into lower-level PDF functions to apply the actual rotation angle; the current matrix rotation is thus applied to the text origin and only extracted (as an angle) for that low-level rendering function.
This would work fine enough if the code adjusted the text origin based on alignment properties, e.g. used the mid-point of the bounding box's bottom edge (for center alignment; using the left or right point for left/right alignment, of course).
The following monkey patch fixes alignment support by adjusting the x
parameter based on the current alignment. To be transparent, I've only test this on simple use cases, and it may break with some more intricate uses, but it does work with rotation and left/center/right justification. After applying this (and also the monkey patch from https://github.com/parallax/jsPDF/issues/3225 -- yes, you can apply both!) I get effectively identical output in both the HTML Canvas and jsPDF canvas for rendering rotated text with center or right alignment.
const oldFillText = ctx.fillText
ctx.fillText = (text, x, y, w) => {
const oldAlign = ctx.textAlign
const xs =
oldAlign == 'middle' || oldAlign == 'center' ? 0.5 :
oldAlign == 'right' || oldAlign == 'end' ? 1.0 :
0.0
ctx.textAlign = 'left'
const m = ctx.measureText(text)
oldFillText.call(ctx, text, x - m.width * xs, y, w)
ctx.textAlign = oldAlign
}
Version : v2.1.1 which is located in dist folder Code to reproduce this issue:
In all, I want to draw 'hello world' right in the middle of the canvas and then rotate it 45°.
Setting
ctx.textAlign = 'left'
(which is the default value I think), position for the text is just as expected , the text starts right from middle of the canvasWhile setting
ctx.textAlign = 'center'
, things work differently. There is a small distance from the rect and the text.In fact, you may refer to attached docs, position for the text is really hard to controll or to understand when you tried other degrees like 90 and 180.
no-align.pdf align-center-rotate45.pdf align-center-rotate90.pdf align-center-rotate180.pdf
You may try this example in your own laptop Archive.zip