when I use line-height=height to center text vertically锛孖 find it does not seem to be centered vertically in the picture generated by html2canvas.
https://jsbin.com/cohugezaxo/1/edit?html,output
Hi there, I've met your problem in my project these days, but in this case you've mentioned, I find it draws quite well...I'don't know how to repeat it again, looking forward for your help :-)
Try to set 'font-family:serif'...
Try to set 'font-family:serif'...
Thanks for your reply, I've solved my problem~Have a nice day:-)
how do you solved it
I met the same prolem, and i found that it's the problem of getRangeBounds
;
the rangeBounds's height of a TextNode may bigger than the container node's clientHeight;
and then when fillText with bounds.top + bounds.height
and textBaseline: 'bottom'
into canvas, the text will be lower than the original position
my solution is adjust all text nodes's top in clonedElement:
but i think this should be solved in the library itself.
Try to set 'font-family:serif'...
Thanks for your reply, I've solved my problem~Have a nice day:-)
How do you solved this problem? Need your help.
Try to set 'font-family:serif'...
Thanks for your reply, I've solved my problem~Have a nice day:-)
How do you solved this problem? Need your help.
It seems html2canvas doesn't support some fonts, just try to disable them one by one, then you will find the unsupported one. in my case, it's FangZheng xxx
.
Try to set 'font-family:serif'...
Thanks for your reply, I've solved my problem~Have a nice day:-)
How do you solved this problem? Need your help.
It seems html2canvas doesn't support some fonts, just try to disable them one by one, then you will find the unsupported one. in my case, it's
FangZheng xxx
.
Yes锛寉ou are right! html2canvas doesn't support most fonts.
first: different font with get different textnode top and height
line-height: 70px;
font-size: 50px;
Ping Fang, sans-serif, serif will get 70px height and STKaiti is 50px height inside html2canvas
so
this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
will fillText in different position
but in Safari and Firefox, html2canvas result is almost same with dom
then I find that
html2canvas set context.textBaseline to middle or bottom but it's useless to let different font-family vertical-align: middle in Chromium
in html2canvas
first: different font with get different textnode top and height
line-height: 70px; font-size: 50px;
in MacOs
in Chromium (chrome 84.0.4147.89 and new edge)
Ping Fang, sans-serif, serif will get 70px height and STKaiti is 50px height inside html2canvas
sothis.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
will fillText in different position
but in Safari and Firefox, html2canvas result is almost same with dom
then I find thathttps://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline
html2canvas set context.textBaseline to middle or bottom but it's useless to let different font-family vertical-align: middle in Chromium
I try all context.textBaseline values and find ideographic useful in Chromium and Safari
but ideographic will result in first image in FireFox
Please explain me how can i fix this. Where should I write which code? Should I edit html2canvas.js or just edit in html2canvas(elemet).then(canvas => {--------});?
in my scene, I only need to support Chrome, so I change in line 6200 @1.0.0-rc.5
CanvasRenderer.prototype.renderTextWithLetterSpacing = function (text, letterSpacing) {
var _this = this;
if (letterSpacing === 0) {
this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
}
to
CanvasRenderer.prototype.renderTextWithLetterSpacing = function (text, letterSpacing) {
var _this = this;
if (letterSpacing === 0) {
this.ctx.textBaseline = 'ideographic'
this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
}
I think you can try to design a new system to get same text.bounds.top and text.bounds.height for different font-family in all browsers such as Chrome, Edge, Safari, Firefox, and main mobile browsers
or
set different canvas context.textBaseline in different browsers before use canvas context.fillText
or
is it possibility to use a div to
<div style="font-size: textnode-font-size; line-height: textnode-line-height; white-space: nowrap;">textnode</div>
then use div.clientHeight and top = recursion computation div.parent.offsetTop and div.parent.parent.offsetTop to fillText(text, left, top+div.clientHeight)
in html2canvas
first: different font with get different textnode top and height
line-height: 70px; font-size: 50px;
in MacOs
in Chromium (chrome 84.0.4147.89 and new edge)
Ping Fang, sans-serif, serif will get 70px height and STKaiti is 50px height inside html2canvas
sothis.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
will fillText in different position
but in Safari and Firefox, html2canvas result is almost same with dom
then I find thathttps://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline
html2canvas set context.textBaseline to middle or bottom but it's useless to let different font-family vertical-align: middle in Chromium
I try all context.textBaseline values and find ideographic useful in Chromium and Safari
but ideographic will result in first image in FireFox
Please explain me how can i fix this. Where should I write which code? Should I edit html2canvas.js or just edit in html2canvas(elemet).then(canvas => {--------});?
in my scene, I only need to support Chrome, so I change in line 6200 @1.0.0-rc.5
CanvasRenderer.prototype.renderTextWithLetterSpacing = function (text, letterSpacing) { var _this = this; if (letterSpacing === 0) { this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height); }
to
CanvasRenderer.prototype.renderTextWithLetterSpacing = function (text, letterSpacing) { var _this = this; if (letterSpacing === 0) { this.ctx.textBaseline = 'ideographic' this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height); }
I think you can try to design a new system to get same text.bounds.top and text.bounds.height for different font-family in all browsers such as Chrome, Edge, Safari, Firefox, and main mobile browsers
or
set different canvas context.textBaseline in different browsers before use canvas context.fillText
or
is it possibility to use a div to<div style="font-size: textnode-font-size; line-height: textnode-line-height; white-space: nowrap;">textnode</div>
then use div.clientHeight and top = recursion computation div.parent.offsetTop and div.parent.parent.offsetTop to fillText(text, left, top+div.clientHeight)
Thanks. It work for me!
in html2canvas
first: different font with get different textnode top and height
line-height: 70px; font-size: 50px;
in MacOs
in Chromium (chrome 84.0.4147.89 and new edge)
Ping Fang, sans-serif, serif will get 70px height and STKaiti is 50px height inside html2canvas
sothis.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
will fillText in different position
but in Safari and Firefox, html2canvas result is almost same with dom
then I find thathttps://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline
html2canvas set context.textBaseline to middle or bottom but it's useless to let different font-family vertical-align: middle in Chromium
I try all context.textBaseline values and find ideographic useful in Chromium and Safari
but ideographic will result in first image in FireFox
Please explain me how can i fix this. Where should I write which code? Should I edit html2canvas.js or just edit in html2canvas(elemet).then(canvas => {--------});?
in my scene, I only need to support Chrome, so I change in line 6200 @1.0.0-rc.5
CanvasRenderer.prototype.renderTextWithLetterSpacing = function (text, letterSpacing) { var _this = this; if (letterSpacing === 0) { this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height); }
to
CanvasRenderer.prototype.renderTextWithLetterSpacing = function (text, letterSpacing) { var _this = this; if (letterSpacing === 0) { this.ctx.textBaseline = 'ideographic' this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height); }
I think you can try to design a new system to get same text.bounds.top and text.bounds.height for different font-family in all browsers such as Chrome, Edge, Safari, Firefox, and main mobile browsers
or
set different canvas context.textBaseline in different browsers before use canvas context.fillText
or
is it possibility to use a div to<div style="font-size: textnode-font-size; line-height: textnode-line-height; white-space: nowrap;">textnode</div>
then use div.clientHeight and top = recursion computation div.parent.offsetTop and div.parent.parent.offsetTop to fillText(text, left, top+div.clientHeight)
It works for me!
I improved it simply in line 6200
CanvasRenderer.prototype.renderTextWithLetterSpacing = function (text, letterSpacing) {
var _this = this;
if (letterSpacing === 0) {
this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
}
// ...
};
to
CanvasRenderer.prototype.renderTextWithLetterSpacing = function (text, letterSpacing) {
var _this = this;
if (navigator.userAgent.indexOf('Firefox') === -1){
// non-Firefox browser add this
this.ctx.textBaseline = 'ideographic';
}
if (letterSpacing === 0) {
this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
}
// ...
};
in html2canvas
first: different font with get different textnode top and height
line-height: 70px; font-size: 50px;
in MacOs
in Chromium (chrome 84.0.4147.89 and new edge)
Ping Fang, sans-serif, serif will get 70px height and STKaiti is 50px height inside html2canvas
sothis.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
will fillText in different position
but in Safari and Firefox, html2canvas result is almost same with dom
then I find thathttps://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline
html2canvas set context.textBaseline to middle or bottom but it's useless to let different font-family vertical-align: middle in Chromium
I try all context.textBaseline values and find ideographic useful in Chromium and Safari
but ideographic will result in first image in FireFox
Please explain me how can i fix this. Where should I write which code? Should I edit html2canvas.js or just edit in html2canvas(elemet).then(canvas => {--------});?
in my scene, I only need to support Chrome, so I change in line 6200 @1.0.0-rc.5
CanvasRenderer.prototype.renderTextWithLetterSpacing = function (text, letterSpacing) { var _this = this; if (letterSpacing === 0) { this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height); }
to
CanvasRenderer.prototype.renderTextWithLetterSpacing = function (text, letterSpacing) { var _this = this; if (letterSpacing === 0) { this.ctx.textBaseline = 'ideographic' this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height); }
I think you can try to design a new system to get same text.bounds.top and text.bounds.height for different font-family in all browsers such as Chrome, Edge, Safari, Firefox, and main mobile browsers
or
set different canvas context.textBaseline in different browsers before use canvas context.fillText
or
is it possibility to use a div to<div style="font-size: textnode-font-size; line-height: textnode-line-height; white-space: nowrap;">textnode</div>
then use div.clientHeight and top = recursion computation div.parent.offsetTop and div.parent.parent.offsetTop to fillText(text, left, top+div.clientHeight)
it works ! thank you too much
Most helpful comment
in my scene, I only need to support Chrome, so I change in line 6200 @1.0.0-rc.5
to
I think you can try to design a new system to get same text.bounds.top and text.bounds.height for different font-family in all browsers such as Chrome, Edge, Safari, Firefox, and main mobile browsers
or
set different canvas context.textBaseline in different browsers before use canvas context.fillText
or
is it possibility to use a div to
then use div.clientHeight and top = recursion computation div.parent.offsetTop and div.parent.parent.offsetTop to fillText(text, left, top+div.clientHeight)