Find me on twitter @geongeorgek
geongeorge / canvas-txt Goto Github PK
View Code? Open in Web Editor NEWMultiline text on HTML5 Canvas
Home Page: https://canvas-txt.geongeorge.com
License: MIT License
Multiline text on HTML5 Canvas
Home Page: https://canvas-txt.geongeorge.com
License: MIT License
Find me on twitter @geongeorgek
Hello,
Thanks for this library.
Is there any way to know if the text we want to write on the canvas will fit on the target canvas size given the selected parameters ?
That would be very helpfull.
Thank you,
I try your jsfiddle
and I see that the single-line text doesn't center absolutely.
Here is what I test center text on the canvas follows https://stackoverflow.com/questions/13771310/center-proportional-font-text-in-an-html5-canvas. Look like it centers vertical absolutely
Sorry if I'm wrong.
Hi there!
I'd like to suggest the addition of a "maxLines" parameter to limit text overflow by appending "..." if it exceeds the specified line count.
Adding this feature would greatly enhance the package's versatility in managing text display within defined boundaries.
Thanks for considering this enhancement!
Hi,
I noticed that sometimes the last character of the word is out of the rectangle :
This happens when the last character which is out the rectangle is also the last character of a word:
while (textpixlen < linelen) {
textlen++
texttoprint = temptext.substr(0, textlen)
textpixlen = ctx.measureText(temptext.substr(0, textlen)).width
}
This can be fixed by removing the last character after this loop :
textlen--
texttoprint = texttoprint.substr(0, textlen)
Can I make a PR for this ?
It is important for me because when the text is justified we see some lines with a character which is not aligned.
This is very impressive.
Is there a way to stop text spilling out of the text box bounds?
If i provide too much text or increase the font size too much the text is spilling out of the text box at the top and bottom.
The current TypeScript definition is for canvas-txt 3.0. Please update the type definitions to match the 4.0 version.
Do you think there will be support for multiple colored words at any stage?
Hi @geongeorge
Thank you for creating this great helper. Feel free to send me a PayPal donate link ๐.
I have a quick question: in your source code, I see you're adding the fontsize to the Y-position:
if (this.vAlign === 'top')
txtY = y + this.fontSize
Because of that, my output is not aligned to the top of the debug lines:
Is there a reason I'm not aware about for adding the fontSize to the Y
position? Can it be removed?
Hi, thank you for this great library it is very useful.
I have a bold text to display, in canvas I would do context.font = 'bold 35pt Arial'
, but I saw that you override the font, so do you have an idea on how I can do this ?
Thank you.
can we add an outline? by using drawText
Currently the height of the text is auto approximated with
let charHeight = ctx.measureText('M').width;
This does not do justice to all types of fonts.
I have an idea i dont know how to implement but i think it would be appriciated, my idea is to add the text-shadow from css into canvas-txt to make it possible to add shadows to text.
I have a method in my react class component that display text on canvas ,The properties passed to canvas text can be changed through state of the component everything works fine and I can change the font color ,text position ,but I when I change font size with text on top right or top left position the text dissapears from the canvas ,but shows up If I change it position other then top right and top left
code I am using
draw = (
video: any,
img: any,
context: any,
context2: any,
width: any,
height: any
) => {
if (video.paused || video.ended) return false;
context2.drawImage(video, 0, 0, width, height);
context2.fillStyle = this.state.textColor;
canvasTxt.fontSize = this.state.fontSize;
canvasTxt.vAlign = this.state.vAlign;
canvasTxt.align = this.state.align;
canvasTxt.lineHeight = 20;
canvasTxt.debug=true;
canvasTxt.drawText(
context2,
this.state.text,
30,
30,
width - 50,
height - 50
);
let idata = context2.getImageData(0, 0, width, height);
let that = this;
context.putImageData(idata, 0, 0);
setTimeout(function() {
that.draw(video, img, context, context2, width, height);
}, 0);
};
Hello, let me start by thanking the creator/mantainers of this little library it's great! However I'm running into one issue, I have some text that has some whitespaces in front of it. When I try to draw this text I'm noticing that the whitespace is trimmed out (only if it's not between actual characters in a line).
Up until now, we have a canvasTxt
object with props and methods you can invoke. This to me is a bad pattern. I built this a while back and it fitted my need perfectly back then. But as the library is evolving and others are using it, I feel it is necessary to follow a better pattern.
I can think of 2 different ways we can use canvas-txt:
This will look a lot like this
import { drawText } from 'canvas-txt'
const config = {
width: 200,
height: 200,
x: 200,
y: 200,
vAlign: 'middle',
align: 'center',
debug: true
}
drawText(ctx, txt, config)
This will look something like
import CanvasTxt from 'canvas-txt'
const ct = new CanvasTxt({
vAlign: 'middle',
align: 'center',
debug: true
})
ct.drawText(ctx, txt, {
width: 200,
height: 200})
ct.align = 'left'
// Or a setter
ct.setAlign('left')
I personally prefer the function approach, but the class might end up useful for some use cases. I would love if anyone has any suggestions or if there's a different approach we can go with.
Hello,
I have this strange issue when I write arabic, the text goes out of the box.
When I use align = left
the text fits correctly, but when I make align = right
it doesn't fit.
But with rtl language I need to align right.
I tried to set canvas.dir = 'rtl'
but it didn't change.
Here some screenshots :
With align right :
With align left it fits perfectly:
The text I used to test :
ุงูููู ูุงู ุฅููููู ุฅููุงูู ูููู ุงูุญูููู ุงูููููููู ู ูุงู ุชูุฃูุฎูุฐููู ุณูููุฉู ูู ูุงู ููููู ู ูููู ู ูุง ููู ุงูุณููู ูุงููุงุชู ูู ู ูุง ููู ุงูุฃูุฑูุถู ู ููู ุฐูุง ุงูููุฐูู ููุดูููุนู ุนูููุฏููู ุฅููุงูู ุจูุฅูุฐููููู ููุนูููู ู ู ูุง ุจููููู ุฃูููุฏููููู ู ูู ู ูุง ุฎูููููููู ู ูู ูุงู ููุญููุทูููู ุจูุดูููุกู ู ููู ุนูููู ููู ุฅููุงูู ุจูู ูุง ุดูุงุกู ููุณูุนู ููุฑูุณูููููู ุงูุณููู ูุงููุงุชู ูู ุงูุฃูุฑูุถู ูู ูุงู ููุฆููุฏููู ุญูููุธูููู ูุง ูู ูููู ุงูุนูููููู ุงูุนูุธููู ู.
Do you have an idea of what I could do ?
Support for \n
line breaks is already in here but
this is only accounted for after lines are already split into arrays.
This ends up creating lines with a single word or few
Code
...
var txt =
'Hello how are \n Lorem ipsum dolor sit ame\n Lorem ipsum dolor sit ame Lorem ipsum dolor sit ame'
canvasTxt.fontSize = 24
canvasTxt.fontWeight = '100'
canvasTxt.fontStyle = 'oblique'
canvasTxt.fontVariant = 'small-caps'
// canvasTxt.debug = true
canvasTxt.align = 'right'
canvasTxt.vAlign = 'middle'
...
Hi @geongeorge ,
Is it possible to justify the text ?
I know that canvas context doesn't support "align justify" because it doesn't support multi-line text, but since this package provides multi-line support, maybe it could be a nice feature to have.
What do you think we need to do to implement this ?
Thank you.
Hi @geongeorge
I know this library is probably not maintained anymore but I'm happy to pay for your time.
In your opinion, would it be a lot of work to add an option to force the content on 1 line (or N lines)? So when the width exceeds 1 line, the font size becomes smaller so the text still fits on that one line.
How can I use strokeText
with CanvasTxt?
I love this package and would like to be able to use it in NodeJS applications as well.
Currently, this does not seem to be possible, as it results in the following error:
ReferenceError: window is not defined
Are there any workarounds for this, or is this something that could be changed in a future update?
Thanks!
In the screenshot I've loaded Source Sans Pro on the right which works correctly and is perfectly centered,
I also loaded in a random TTF font from dafont, and it's not centered. This is the case for most custom fonts I load, especially the artsy ones.
Changing the baseline, unfortunately, doesn't help much, with ideographic being the closest to being centered, and the rest just putting it even lower
Is it possible to add texts on an image?
Great library, we use it to render text on our site
I'm not 100% sure, however it seems to me that changing the bounding box' width to be too low for the text causes a freeze. I haven't tested with height but I imagine it's the same.
You can reproduce the issue on our site by opening the editor, then following these steps:
I haven't tested this issue in isolation using just your library, however no such issue has occurred with any other items we have, so I'm afraid it's your library - however, if it's not, feel free to close the issue.
For this text copied for wikipedia
ๅผบ็็ญๅธฆๆฐๆๆ้ฉฌๅฅๅฐๆฏ2018ๅนด3ๆไธๆฌๅจ้ฉฌ่พพๅ ๆฏๅ ๅ็ๅฐผๆฑชๅผๅๆดช็พ็ๅผบ็็ฑๅธถๆฐฃๆ๏ผ2ๆ27ๆฅ็ฑ่ฅฟๅๅฐๅบฆๆด้ฟๅ ่ๅ ็พคๅณถ้่ฟ็ไฝๆฐๅๅบๅๅฑ่ๆใ็ณป็ป3ๆ2ๆฅๅ่ๆ็ญๅธฆๆฐๅจ๏ผๆฌกๆฅๅ็บง็ญๅธฆ้ฃๆดๅนถ่ทๅใๆญคๅไธคๅคฉๆ้ฉฌๅฅๅฐๅ ๅค็็ฏๅขๆๅฉ่ฟ
้ๅข
The previous version looks much more perfect
I have a use case where I need to insert some text at the end of a canvas, and then I need to adjust the height of the canvas so it fits the text.
I am not sure how to do this, but I thought I could use the value of vheight
calculated at this line :
Line 100 in a812978
What do you think ? Maybe we could return it so we can use it :
const { vHeight } = canvasTxt.drawText(ctx, txt, 0, 0, 200, 200)
The canvas by default aligns the text to middle which defies the flexibility. Is there any solution or recommendation. Thank you
Hi, I'm making a rasterizer kernel, but "0,0" is in the bottom left when I want it in the top left. Is there a way I can change how the kernel iterates like how instead of incrementing thread.y I could decrementing thread.y.
If width is less than font-width then the one of the while loops never ends
Hi, wanna ask is there possible to get the text height dynamically if the text wrapped?
I've 2 different font of text stacking top bottom to each other, but I want the top text if it is goes to 2 lines, the bottom text position can be move to bottom. Is there a way to calculate this or just get the top text bounding box height so that I can get the value?
Scenario
Consider the following example with a <textarea>
element over a <canvas>
element, both with the exact same size, font properties and absolute position. If done right, they align perfectly. In the animation below textarea has a light grey background and canvas has the debug bounding box borders on.
Issue
textarea second line: 'render text on HTML5'
canvas second line: 'render text on'
Possible cause
I assume there is a whitespace at the beginning of the second line (so actually ' render text on') and the measured width is wrong.
Hi,
If I don't specify lineHeight nothing gets rendered on iOS11.
From reading the code i guess the bug is somewhere in the getTextHeight function.
Thanks for a great canvas-helper!
Hi George!
I am a big fan of your work; I really appreciate your contribution here. I wanted to use canvas-txt in another project I maintain however I found it to be too slow. I eventually forked and modified your library to the point of being basically unrecognizable, but made it better suited to the tasks I had at hand.
Anyway, I figured you might want to take some of the performance adaptations back into your library to make it much faster with large amounts of text. You can find the work here: https://github.com/glideapps/canvas-hypertxt
While I have every intention to maintain this library and keep it up to date as I need it for my own uses, I fully expect the vast majority of people are better served by canvas-txt unless they are performance sensitive or need to integrate into a larger rendering framework which already has text rendering functionality.
I'm still in the process of publishing and setting up project pages, if you decide to bring back any of the performance improvements Im happy to update the benchmarks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.