p5.js icon indicating copy to clipboard operation
p5.js copied to clipboard

Add textLineHeight method to Typography

Open yashpandit opened this issue 4 years ago • 14 comments

Most appropriate sub-area of p5.js?

  • [ ] Color
  • [ ] Core/Environment/Rendering
  • [ ] Data
  • [ ] Events
  • [ ] Image
  • [ ] IO
  • [ ] Math
  • [x] Typography
  • [ ] Utilities
  • [ ] WebGL
  • [ ] Other (specify if possible)

New feature details:

We can add functionality that can add spaces around a line(space on top and bottom of the line) which can be done in CSS by using line-height property.

Below is the behavior of line-height: lineHeightDemo

Can we add a method textLineHeight() to Typography module?

The signature of the function would be something like this:

/**
* N is the number of pixels
* @param {number} N
*/
function textLineHeight(N) {}

yashpandit avatar Jan 09 '20 14:01 yashpandit

Welcome! 👋 Thanks for opening your first issue here! And to ensure the community is able to respond to your issue, be sure to follow the issue template if you haven't already.

welcome[bot] avatar Jan 09 '20 14:01 welcome[bot]

@lmccart - What do you think about this?

yashpandit avatar Jan 09 '20 14:01 yashpandit

This should be already covered by textLeading unless you mean something else?

limzykenneth avatar Jan 09 '20 17:01 limzykenneth

Correct me if I am wrong but textLeading only adds space below the text and keeps the baseline of the text the same(the content only goes down).

With textLineHeight, it actually increases the height of the line while keeping the text in the center and adds even spaces on the top and bottom of the text keeping it in the center so that the formatting looks even for all the lines.

yashpandit avatar Jan 09 '20 17:01 yashpandit

Ok I see what you mean. I feel that it's a bit niche and possibly some overlap with textLeading but I'll let other people chip in their thoughts on this as well. 😄

limzykenneth avatar Jan 09 '20 18:01 limzykenneth

Can I claim this issue?

ArjunwadkarAjay avatar Feb 25 '20 07:02 ArjunwadkarAjay

@ArjunwadkarAjay I would like to get some opinions on this issue and workout the implementation outline before assinging anyone. Notably now that I've looked at this again, I a bit more hesitant to add this especially into the Typography module because the line-height property is added in CSS and not in the JS canvas API itself, which could cause problem with user defined CSS.

Any thoughts on this?

limzykenneth avatar Feb 25 '20 10:02 limzykenneth

Can we just pass a parameter in the function mentioned and manipulate the css's line height property a particular mentionedtext.Thereby allowing flexibility to programmer

ArjunwadkarAjay avatar Feb 27 '20 01:02 ArjunwadkarAjay

And sorry for replying to you late, as I was stuck in exams.

ArjunwadkarAjay avatar Feb 27 '20 01:02 ArjunwadkarAjay

Can we just pass a parameter in the function mentioned and manipulate the css's line height property a particular mentionedtext.Thereby allowing flexibility to programmer

I don't quite get what you mean here. The problem I have here is the textLineHeight() function would necessarily modify the CSS property of the canvas which could cause conflict with user defined styling defined with p5.Element or in user created stylesheet.

limzykenneth avatar Feb 27 '20 11:02 limzykenneth

@limzykenneth I thought about CSS property you mentioned, but mostly it would change the text property of the font rendered on the web page and not on canvas. @yashpandit and @limzykenneth can we do it by adding empty text element to achieve this. A function can be created which can add a empty text before and after the actual text. Pls do take a look at the example and tell if this idea is correct `function setup() { createCanvas(400, 400); }

function draw() { background(220); textSize(32); text('', 10, 60-32);//line of empty text for getting the space fill(0, 102, 153); text('word', 10, 60); text('', 10, 60+32);//line of empty text for getting the space fill(0, 102, 153); text('word1', 10, 60+32+32); text('',10,60+32+32+32);//line of empty text for getting the space text('word2', 10, 60+32+32+32+32); }`

ArjunwadkarAjay avatar Feb 29 '20 04:02 ArjunwadkarAjay

So @yashpandit can try to work on this in the mentioned manner? And @yashpandit and @limzykenneth plz tell if it is possible as well.

ArjunwadkarAjay avatar Feb 29 '20 04:02 ArjunwadkarAjay

@ArjunwadkarAjay Yeah, you're right about CSS, not sure what I was on about. CSS should not come into this.

There isn't a need to draw an empty string to get some space as if you draw nothing there, nothing is there. You can just skip to drawing the first line text('word', 10, 60); then the next text('word1', 10, 60+32+32);. But this is also not quite what textLineHeight() is meant for.

Assuming textLineHeight() is a variation similar to textLeading(), it is meant to be used for something like this:

// Text to display. The "\n" is a "new line" character
let lines = 'L1\nL2\nL3';
textSize(12);

textLineHeight(10); // Set line height to 10
text(lines, 10, 25);

textLineHeight(20); // Set line height to 20
text(lines, 40, 25);

textLineHeight(30); // Set line height to 30
text(lines, 70, 25);

The way textLeading() achieve this is through manipulating the final font size on the element. The code is a bit complicated so I haven't gone through it in detail yet but it's here. I'm not sure how possible it is to work textLineHeight() in, especially to consider compatibility with textLeading() as well. This will require more investigating.

limzykenneth avatar Feb 29 '20 10:02 limzykenneth

My (cursory) understanding is that textLeading and textLineHeight are similar except that with leading, space is added above the text (this would start above the 2nd line of a paragraph), while with line-height it is split above and below.

image source

It seems to me that one can simulate the behavior of textLineHeight by setting vertical textAlign to CENTER and using textLeading (as shown in the bottom image), but perhaps I am missing some subtlety here.

Other than being consistent with the (non-standard) CSS api, is there some use-case for which textLeading(), together with textAlign(), does not suffice?

Screenshot 2020-05-28 at 2 18 39 PM

Screenshot 2020-05-28 at 2 22 50 PM

dhowe avatar May 28 '20 06:05 dhowe

👋 Revisiting this after discussion with @munusshih for GSoC. I believe @dhowe's comment shows how you can get close to the functionality of CSS line-height by using centered vertical text alignment; the only complication there is having to specify centered y values when drawing with text().

Alternatively, you can use textLeading and then calculate a text offset if you're drawing from the vertical top, bottom, or baseline — I think that was what @ArjunwadkarAjay and @limzykenneth were discussing:

Screen Shot 2023-06-20 at 10 35 55 AM

Neither one of these approaches perfectly mirrors the CSS line-height behavior though, since the CSS spacing is dependent on the height of the actual text. Here's a side-by-side comparison with CSS:

Screen Shot 2023-06-20 at 11 01 45 AM

more info here about how line-height works. You could approximate the required padding using fontSize:

Screen Shot 2023-06-20 at 11 22 24 AM

https://editor.p5js.org/kyeah/sketches/zwpiK7FFm

Similar to Kenneth — Munus and I are not too sure how it would work to have both a textLineHeight and textLeading function since they would both be used to adjust line spacing. It does seem like textLeading can replicate line-height behavior — maybe we want to add an example to the textLeading() documentation?

kyeah avatar Jun 20 '23 15:06 kyeah

Suggestion to close this issue.

munusshih avatar Sep 04 '23 03:09 munusshih