Reputation: 341
I’m searching for a way of automatically
compose a sentence using javascript.
Here is an example using this sentence :
«here is an amazing sentence well composed»
Then I’d like the block size to change dependind
on the word width
So that finally, it could look like this :
So far, I only found how to cut the sentences in words.
How could I define a width for each «words / text block»
depending on their width ?
function wordsinblocks() {
var str = document.getElementById("demo").innerHTML;
var res = str.split(" ");
document.getElementById("demo").innerHTML = res;
}
body{
font-family:"helvetica";
font-size: 40px;
}
p {border: 1px solid black;}
<button onclick="wordsinblocks();">Design the sentence</button>
<p id="demo">Here is an amazing sentence well composed</p>
Upvotes: 3
Views: 147
Reputation: 196187
Here is an implementation that finds the relevant grid size to apply. (and reruns the fitting code when resizing the browser so that it will work responsively)
function wordsinblocks(self) {
var demo = document.getElementById("demo"),
initialText = demo.textContent,
wordTags = initialText.split(" ").map(function(word){
return '<span class="word">' + word + '</span>';
});
demo.innerHTML = wordTags.join('');
self.disabled = true;
fitWords();
window.addEventListener('resize', fitWords);
}
function fitWords(){
var demo = document.getElementById("demo"),
width = demo.offsetWidth,
sizes = [10,30,50, 100],
calculated = sizes.map(function(size){return width*size/100}),
node,
i,
nodeWidth,
match,
index;
for (i=0;i<demo.childNodes.length;i++){
node = demo.childNodes[i];
node.classList.remove('size-1','size-2','size-3','size-4');
nodeWidth = node.clientWidth;
match = calculated.filter(function(grid){
return grid >= nodeWidth;
})[0];
index = calculated.indexOf(match);
node.classList.add( 'size-' + (index+1));
}
}
#demo{
display:block;
padding:0 0 0 1px;
overflow:auto;
}
#demo .word{
float:left;
box-sizing:border-box;
padding:5px;
border:1px solid #999;
}
#demo .size-1{width:10%}
#demo .size-2{width:30%}
#demo .size-3{width:50%}
#demo .size-4{width:100%}
<button onclick="wordsinblocks(this);">Design the sentence</button>
<p id="demo">Here is an amazing sentence well composed</p>
Upvotes: 2
Reputation: 7793
What about something like this? The result might not fully represent your picture but it does calculate the length of each word and apply a class accordingly:
$("p span").each(function() {
// get length of word characters
var l = $(this).text().length;
// apply 10 percent class if equal or to less than 2 characters
if (l <= 2) {
$(this).addClass('p10'); }
// apply 30 percent class if equal or to less than 5 characters
else if (l <= 5) {
$(this).addClass('p30'); }
// otherwise, apply a 50 percent class
else {
$(this).addClass('p50')
}
});
p {
border: 1px dashed red;
}
span {
border: 1px solid #000;
padding: 5px;
display: inline-block;
box-sizing: border-box;
}
.p10 {
width: 10%;
background: lightblue;
}
.p30 {
width: 30%;
background: lightgreen;
}
.p50 {
width: 50%;
background: lightyellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<span class="p10">10 percent</span>
<span class="p30">30 percent</span>
<span class="p50">50 percent</span>
<p>
<span>Here</span>
<span>is</span>
<span>an</span>
<span>amazing</span>
<span>sentence</span>
<span>well</span>
<span>composed</span>
</p>
Upvotes: 0
Reputation: 10327
Before you put your words back in html, wrap each word into a span and style the spans. This is just the part of how would you design the spans. Based on letter count you could add grid classes to them.
Please note that i didn't write the styles for the grid classes, therefore that won't be visible.
function wordsinblocks() {
var str = document.getElementById("demo").innerHTML;
var res = str.split(" ");
for (var x in res) {
var l = res[x].length;
var className = "grid-1";
switch(true) {
case (l < 3):
className = "grid-1";
break;
case (l > 2 && l < 5):
className = "grid-2";
break;
// and so on until you get all cases you wish to cover
default: // and finally longer words would have the widest column class
className = "grid-4";
break;
}
res[x] = '<span class="word-item ' + className + '">' + res[x] + '</span>';
}
document.getElementById("demo").innerHTML = res.join("");
}
body{
font-family:"helvetica";
font-size: 40px;
}
p span.word-item {border: 1px solid black; padding: 0 0.5em; box-sizing: border-box; display: inline-block;}
<button onclick="wordsinblocks();">Design the sentence</button>
<p id="demo">Here is an amazing sentence well composed</p>
Upvotes: 2