0

I'm looking for a simple solution to be able to word wrap within a fixed rectangle in my canvas....

I thought this might work, but unless I make the wrap point longer than the text, it causes my canvas to go completely blank.

<canvas id="planner1" width="300" height="300" style="z-index:0;position:absolute;left:10px;top:10px;border:1px solid #000000;background-color:white;"></canvas>

var c1 = document.getElementById("planner1");
var ctx = c1.getContext("2d");

ctx.font = "16px Arial";
ctx.fillStyle = "red";
ctx.textAlign = "left";
ctx.fillText("<?php echo wordwrap("Sample Text", 10, "\n", FALSE);?>",80 ,80);

Looking through the PHP manual, I don't see anything that would preclude this, but I know mixing PHP and javascript is fraught with peril.

I get the data used in the canvas from my db and echo it to draw the rectangle. I then would like echo text (easy via javascript) and wordwrap it (less easy in javascript). PHP has an easy way to do this which I tried, however it doesn't word wrap correctly within the javascript. This isn't a server side versus client side issue and that all works properly....this is formatting issue mainly tied to how javascript handles displaying text within the confines of the canvas tags.

Anybody ever try this and/or found a better way?

airider74
  • 390
  • 3
  • 14
  • 1
    You might consider using CSS to do the word wrap part. http://www.html5canvastutorials.com/tutorials/html5-canvas-wrap-text-tutorial/ – Difster Jul 15 '17 at 02:26
  • Thanks...I've looked at that and it's a lot of code to basically do what the wordwrap function does.... – airider74 Jul 15 '17 at 02:30
  • PHP runs on server clide while JavaScript runs on client's. – Louys Patrice Bessette Jul 15 '17 at 02:34
  • Possible duplicate of [What is the difference between client-side and server-side programming?](https://stackoverflow.com/questions/13840429/what-is-the-difference-between-client-side-and-server-side-programming) – Louys Patrice Bessette Jul 15 '17 at 02:35
  • 1
    Sure, it's more code. But CSS and JavaScript go together better than PHP and JavaScript. The function is 18 lines of code and it works whereas you're wasting a bunch of time trying shoehorn PHP in to it. – Difster Jul 15 '17 at 02:35
  • Louys, I understand that... – airider74 Jul 15 '17 at 02:38
  • Difster, I'll make a go of it, I'm just looking to take advantage of all the latest features available. The good news is you all are showing me examples I've seen so I know I'm not crazy (as far as I can tell). – airider74 Jul 15 '17 at 02:40
  • Louys, I've got things setup to get data I need from the server and store it in an array. I echo the db information to construct the size of the rectangle and then I want to draw the text within the rectangle appropriate for the data I retrieved from the server, and bounded by the dimensions of the box based on the db info. – airider74 Jul 15 '17 at 02:48
  • This is why I'm looking for a "simple" wordwrap. – airider74 Jul 15 '17 at 02:49
  • 1
    The effect of a new line inserted by `wordwrap()` will have **absolutely** no effect in the `ctx.fillText()` argument. Your question is *«Can I use PHP wordwrap...»* Answer is no. Look for client-side solutions. – Louys Patrice Bessette Jul 15 '17 at 03:35
  • Louys....perfect that's what I needed to know. I've implemented a version of Difsters recommendation....now I have another question. Using Difsters example, I'm trying to transition the word wrap method into a word break method, when the words are larger than the max width of the rectangle I'm writing in. I was thinking I could easily pull this off with an if-else statement that changes the:var words = text.split(' '); to var words = text.split(''); ... do you have a suggestion? – airider74 Jul 15 '17 at 23:36
  • Scratch that....I realized that switching from a simple if-else switch won't do the trick....I'll have to build something different. – airider74 Jul 15 '17 at 23:52

2 Answers2

0

I've found a solution to my problem. Difster got me headed down the right path with his link to an example...the thing I was looking for was javascript functionality for what CSS calls "word break".

So what I needed what another check in the example link from Difster, within the word wraps to actually break the word if it is too long to fit in the rectangle. So now I needed to switch from measuring the word length to measuring text. W3Schools got me started measuring the text. Then I tried building a while loop. I struggled a bit with that and then I found an example at code pen...

codepen.io/peterhry/pen/AGIEa

This includes both word wrap and word break....after shoe horning this into the previous example from difster and tweaking it a bit, here's the jsfiddle that does what I'm looking for.

function wrapText (context, text, x, y, maxWidth, lineHeight) {
    
    var words = text.split(' ');
    var line = '';
    var lineCount = 0;
    var test;
    var metrics;

    for (var i = 0; i < words.length; i++) {
        test = words[i];
    // add test for length of text
        metrics = context.measureText(test);
        while (metrics.width > maxWidth) {
            test = test.substring(0, test.length - 1);
            metrics = context.measureText(test);
        }
        if (words[i] != test) {
            words.splice(i + 1, 0,  words[i].substr(test.length))
            words[i] = test;
        }  

        test = line + words[i] + ' ';  
        metrics = context.measureText(test);
        
        if (metrics.width > maxWidth && i > 0) {
            context.fillText(line, x, y);
            line = words[i] + ' ';
            y += lineHeight;
            lineCount++;
        }
        else {
            line = test;
        }
    }
     context.fillText(line, x, y);
}

var c1 = document.getElementById("planner1");
var ctx = c1.getContext("2d");

ctx.font = "16px Arial";
ctx.fillStyle = "red";
ctx.textAlign = "left";
text = 'This is a bunch of really looooooong text';

wrapText (ctx, text, 10, 20, 50, 20);
<canvas id="planner1" width="300" height="300" style="z-index:0;position:absolute;left:10px;top:10px;border:1px solid #000000;background-color:white;"></canvas>

Thanks to everyone for your input!!!

airider74
  • 390
  • 3
  • 14
-1

I think as a separator in the php section you sould use

<canvas id="planner1" width="300" height="300" style="z-index:0;position:absolute;left:10px;top:10px;border:1px solid #000000;background-color:white;"></canvas>

var c1 = document.getElementById("planner1");
var ctx = c1.getContext("2d");

ctx.font = "16px Arial";
ctx.fillStyle = "red";
ctx.textAlign = "left";
ctx.fillText("<?php echo wordwrap("Sample Text", 10, "<br />\n", FALSE);?>",80 ,80);
Marco F
  • 1
  • 4
  • Thanks, it just causes my screen to go blank...increasing 10 to a higher number brings it back, but unfortunately doesn't support any word wrapping. – airider74 Jul 15 '17 at 02:33