2017-04-27 9 views
6

Próbuję znaleźć sposób wypełniania złożonych wielokątów tekstem na stronie internetowej. enter image description hereWypełnianie złożonych wielokątów z tekstem - dowolne JS (lub inne) alternatywy dla wykluczeń CSS?

CSS Exclusions wydaje się robić dokładnie to, co robię, ale wsparcie jest raczej minimalne (tylko IE10 + do tej pory ...).

Każdy pomysł, jak mogę rozwiązać ten problem w JS? Może być po stronie serwera lub po stronie klienta. Może nawet być PHP lub Python lub cokolwiek innego.

Dzięki

+0

[SVG] (https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg) lub HTML5 [Canvas] (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) będą oczywistymi podejrzanymi dla zaawansowanych kształtów. –

+0

Cześć Emil, tak na pewno. Po prostu staram się wypracować sposób wypełnienia tych kształtów tekstem. – jcbmb

Odpowiedz

3

bawił się z płótna i wymyślił to:

var canvas = document.body.appendChild(document.createElement("canvas")); 
 
canvas.width = 200; 
 
canvas.height = canvas.width; 
 
var ctx = canvas.getContext("2d"); 
 
var Shape = (function() { 
 
    function Shape(position, points) { 
 
    if (points === void 0) { 
 
     points = []; 
 
    } 
 
    this.position = position; 
 
    this.points = points; 
 
    } 
 
    Shape.prototype.draw = function(ctx, str) { 
 
    var lineSize = ctx.measureText("a").width; 
 
    var minY = this.points 
 
     .map(function(a) { 
 
     return a.y; 
 
     }) 
 
     .sort(function(a, b) { 
 
     return (a < b ? -1 : 1); 
 
     })[0]; 
 
    var minX = this.points 
 
     .map(function(a) { 
 
     return a.x; 
 
     }) 
 
     .sort(function(a, b) { 
 
     return (a < b ? -1 : 1); 
 
     })[0]; 
 
    var maxY = this.points 
 
     .map(function(a) { 
 
     return a.y; 
 
     }) 
 
     .sort(function(a, b) { 
 
     return (b < a ? -1 : 1); 
 
     })[0]; 
 
    var maxX = this.points 
 
     .map(function(a) { 
 
     return a.x; 
 
     }) 
 
     .sort(function(a, b) { 
 
     return (b < a ? -1 : 1); 
 
     })[0]; 
 
    ctx.fillStyle = "rgba(255,0,0,0.1)"; 
 
    for (var ai = 0; ai < this.points.length; ai++) { 
 
     var a = this.points[ai]; 
 
     var b = this.points[(ai + 1) % this.points.length]; 
 
     if (ai === 0) { 
 
     ctx.beginPath(); 
 
     ctx.moveTo(a.x + this.position.x, a.y + this.position.y); 
 
     } 
 
     ctx.lineTo(b.x + this.position.x, b.y + this.position.y); 
 
    } 
 
    ctx.closePath(); 
 
    ctx.fill(); 
 
    //ctx.textBaseline = "bottom"; 
 
    ctx.fillStyle = "black"; 
 
    var strLeft = str; 
 
    var line = minY; 
 
    while (line <= maxY && strLeft.length > 0) { 
 
     var startX = null; 
 
     var endX = null; 
 
     for (var x = minX; x <= maxX; x += lineSize) { 
 
     var data = ctx.getImageData(x + this.position.x - lineSize, line + this.position.y - lineSize, 1, 1).data; 
 
     if (data[0] + data[1] + data[2] + data[3] > 0) { 
 
      if (startX === null) { 
 
      startX = x; 
 
      } else { 
 
      endX = x; 
 
      } 
 
     } 
 
     } 
 
     var length = Math.floor((endX - startX)/lineSize); 
 
     var localStr = strLeft.substr(0, length); 
 
     strLeft = strLeft.substr(length); 
 
     ctx.fillText(localStr, startX + this.position.x, line + this.position.y); 
 
     line += lineSize + 2; 
 
    } 
 
    }; 
 
    return Shape; 
 
}()); 
 
var shape = new Shape({ 
 
    x: 100, 
 
    y: 60 
 
}, [{ 
 
    x: -100, 
 
    y: -40 
 
    }, 
 
    { 
 
    x: 100, 
 
    y: -60 
 
    }, 
 
    { 
 
    x: 0, 
 
    y: 0 
 
    }, 
 
]); 
 
shape.draw(ctx, "once upon a midnight dreary while i pondered weak and weary");

Jest szorstki, ale jest to punkt wyjścia.

EDIT

Tutaj jest bardziej trafny portret i przy użyciu czcionki o wielkości invariabel Symbol:

var canvas = document.body.appendChild(document.createElement("canvas")); 
 
canvas.width = 610; 
 
canvas.height = 787; 
 
var ctx = canvas.getContext("2d"); 
 
var bgimg = (function() { 
 
    var img = document.createElement("img"); 
 
    img.src = 'https://i.stack.imgur.com/XYThp.png'; 
 
    return img; 
 
})(); 
 
canvas.onclick = function(evt) { 
 
    console.log(evt.layerX - evt.target.offsetLeft, evt.layerY); 
 
}; 
 
var Shape = (function() { 
 
    function Shape(position, points) { 
 
    if (points === void 0) { 
 
     points = []; 
 
    } 
 
    this.position = position; 
 
    this.points = points; 
 
    } 
 
    Shape.prototype.draw = function(ctx, str) { 
 
    ctx.font = "14px Courier"; 
 
    var lineSize = ctx.measureText("i").width; 
 
    var minY = this.points 
 
     .map(function(a) { 
 
     return a.y; 
 
     }) 
 
     .sort(function(a, b) { 
 
     return (a < b ? -1 : 1); 
 
     })[0]; 
 
    var minX = this.points 
 
     .map(function(a) { 
 
     return a.x; 
 
     }) 
 
     .sort(function(a, b) { 
 
     return (a < b ? -1 : 1); 
 
     })[0]; 
 
    var maxY = this.points 
 
     .map(function(a) { 
 
     return a.y; 
 
     }) 
 
     .sort(function(a, b) { 
 
     return (b < a ? -1 : 1); 
 
     })[0]; 
 
    var maxX = this.points 
 
     .map(function(a) { 
 
     return a.x; 
 
     }) 
 
     .sort(function(a, b) { 
 
     return (b < a ? -1 : 1); 
 
     })[0]; 
 
    ctx.fillStyle = "rgba(255,0,0,0.1)"; 
 
    for (var ai = 0; ai < this.points.length; ai++) { 
 
     var a = this.points[ai]; 
 
     var b = this.points[(ai + 1) % this.points.length]; 
 
     if (ai === 0) { 
 
     ctx.beginPath(); 
 
     ctx.moveTo(a.x + this.position.x, a.y + this.position.y); 
 
     } 
 
     ctx.lineTo(b.x + this.position.x, b.y + this.position.y); 
 
    } 
 
    ctx.closePath(); 
 
    ctx.fill(); 
 
    //ctx.textBaseline = "bottom"; 
 
    ctx.fillStyle = "black"; 
 
    var strLeft = str; 
 
    var line = minY; 
 
    while (line <= maxY && strLeft.length > 0) { 
 
     var startX = null; 
 
     var endX = null; 
 
     for (var x = minX; x <= maxX; x += lineSize) { 
 
     var data = ctx.getImageData(x + this.position.x, line + this.position.y, 1, 1).data; 
 
     if (data[0] + data[1] + data[2] + data[3] > 0) { 
 
      if (startX === null) { 
 
      startX = x; 
 
      } else { 
 
      endX = x; 
 
      } 
 
     } 
 
     } 
 
     if (line == 398) { 
 
     console.log(startX, endX); 
 
     } 
 
     var length = Math.floor((endX - startX)/lineSize); 
 
     var localStr = strLeft.substr(0, length); 
 
     strLeft = strLeft.substr(length); 
 
     ctx.fillText(localStr, startX + this.position.x, line + this.position.y); 
 
     line += lineSize + 2; 
 
    } 
 
    /* 
 
    ctx.globalCompositeOperation = 'destination-over'; 
 
    ctx.drawImage(bgimg, 0, 0); 
 
    ctx.globalCompositeOperation = 'source-over'; 
 
    */ 
 
    }; 
 
    return Shape; 
 
}()); 
 
var shape = new Shape({ 
 
    x: 0, 
 
    y: 0 
 
}, [{ 
 
    x: 5, 
 
    y: 104 
 
    }, 
 
    { 
 
    x: 125, 
 
    y: 46 
 
    }, 
 
    { 
 
    x: 205, 
 
    y: 50 
 
    }, 
 
    { 
 
    x: 254, 
 
    y: 101 
 
    }, 
 
    { 
 
    x: 346, 
 
    y: 180 
 
    }, 
 
    { 
 
    x: 398, 
 
    y: 254 
 
    }, 
 
    { 
 
    x: 425, 
 
    y: 290 
 
    }, 
 
    { 
 
    x: 462, 
 
    y: 347 
 
    }, 
 
    { 
 
    x: 476, 
 
    y: 414 
 
    }, 
 
    { 
 
    x: 485, 
 
    y: 459 
 
    }, 
 
    { 
 
    x: 515, 
 
    y: 546 
 
    }, 
 
    { 
 
    x: 524, 
 
    y: 590 
 
    }, 
 
    { 
 
    x: 539, 
 
    y: 634 
 
    }, 
 
    { 
 
    x: 572, 
 
    y: 689 
 
    }, 
 
    { 
 
    x: 571, 
 
    y: 712 
 
    }, 
 
    { 
 
    x: 567, 
 
    y: 734 
 
    }, 
 
    { 
 
    x: 582, 
 
    y: 777 
 
    }, 
 
    { 
 
    x: 557, 
 
    y: 746 
 
    }, 
 
    { 
 
    x: 492, 
 
    y: 744 
 
    }, 
 
    { 
 
    x: 489, 
 
    y: 757 
 
    }, 
 
    { 
 
    x: 461, 
 
    y: 757 
 
    }, 
 
    { 
 
    x: 349, 
 
    y: 597 
 
    }, 
 
    { 
 
    x: 203, 
 
    y: 537 
 
    }, 
 
    { 
 
    x: 130, 
 
    y: 413 
 
    }, 
 
    { 
 
    x: 94, 
 
    y: 312 
 
    }, 
 
    { 
 
    x: 93, 
 
    y: 244 
 
    }, 
 
    { 
 
    x: 103, 
 
    y: 198 
 
    }, 
 
    { 
 
    x: 105, 
 
    y: 162 
 
    }, 
 
    { 
 
    x: 73, 
 
    y: 124 
 
    }, 
 
    { 
 
    x: 36, 
 
    y: 118 
 
    }, 
 
]); 
 
setTimeout(function() { 
 
    shape.draw(ctx, "Once upon a midnight dreary, while I pondered, weak and weary,\nOver many a quaint and curious volume of forgotten lore\u2014\nWhile I nodded, nearly napping, suddenly there came a tapping,\nAs of some one gently rapping, rapping at my chamber door.\n\u201C\u2019Tis some visitor,\u201D I muttered, \u201Ctapping at my chamber door\u2014\nOnly this and nothing more.\u201D\n\nAh, distinctly I remember it was in the bleak December;\nAnd each separate dying ember wrought its ghost upon the floor.\nEagerly I wished the morrow;\u2014vainly I had sought to borrow\nFrom my books surcease of sorrow\u2014sorrow for the lost Lenore\u2014\nFor the rare and radiant maiden whom the angels name Lenore\u2014\nNameless here for evermore.\n\nAnd the silken, sad, uncertain rustling of each purple curtain\nThrilled me\u2014filled me with fantastic terrors never felt before;\nSo that now, to still the beating of my heart, I stood repeating\n\u201C\u2019Tis some visitor entreating entrance at my chamber door\u2014\nSome late visitor entreating entrance at my chamber door;\u2014\nThis it is and nothing more.\u201D\n\nPresently my soul grew stronger; hesitating then no longer,\n\u201CSir,\u201D said I, \u201Cor Madam, truly your forgiveness I implore;\nBut the fact is I was napping, and so gently you came rapping,\nAnd so faintly you came tapping, tapping at my chamber door,\nThat I scarce was sure I heard you\u201D\u2014here I opened wide the door;\u2014\nDarkness there and nothing more.\n\nDeep into that darkness peering, long I stood there wondering, fearing,\nDoubting, dreaming dreams no mortal ever dared to dream before;\nBut the silence was unbroken, and the stillness gave no token,\nAnd the only word there spoken was the whispered word, \u201CLenore?\u201D\nThis I whispered, and an echo murmured back the word, \u201CLenore!\u201D\u2014\nMerely this and nothing more.\n\nBack into the chamber turning, all my soul within me burning,\nSoon again I heard a tapping somewhat louder than before.\n\u201CSurely,\u201D said I, \u201Csurely that is something at my window lattice;\nLet me see, then, what thereat is, and this mystery explore\u2014\nLet my heart be still a moment and this mystery explore;\u2014\n\u2019Tis the wind and nothing more!\u201D\n\nOpen here I flung the shutter, when, with many a flirt and flutter,\nIn there stepped a stately Raven of the saintly days of yore;\nNot the least obeisance made he; not a minute stopped or stayed he;\nBut, with mien of lord or lady, perched above my chamber door\u2014\nPerched upon a bust of Pallas just above my chamber door\u2014\nPerched, and sat, and nothing more.\n\nThen this ebony bird beguiling my sad fancy into smiling,\nBy the grave and stern decorum of the countenance it wore,\n\u201CThough thy crest be shorn and shaven, thou,\u201D I said, \u201Cart sure no craven,\nGhastly grim and ancient Raven wandering from the Nightly shore\u2014\nTell me what thy lordly name is on the Night\u2019s Plutonian shore!\u201D\nQuoth the Raven \u201CNevermore.\u201D\n\nMuch I marvelled this ungainly fowl to hear discourse so plainly,\nThough its answer little meaning\u2014little relevancy bore;\nFor we cannot help agreeing that no living human being\nEver yet was blessed with seeing bird above his chamber door\u2014\nBird or beast upon the sculptured bust above his chamber door,\nWith such name as \u201CNevermore.\u201D\n\nBut the Raven, sitting lonely on the placid bust, spoke only\nThat one word, as if his soul in that one word he did outpour.\nNothing farther then he uttered\u2014not a feather then he fluttered\u2014\nTill I scarcely more than muttered \u201COther friends have flown before\u2014\nOn the morrow he will leave me, as my Hopes have flown before.\u201D\nThen the bird said \u201CNevermore.\u201D\n\nStartled at the stillness broken by reply so aptly spoken,\n\u201CDoubtless,\u201D said I, \u201Cwhat it utters is its only stock and store\nCaught from some unhappy master whom unmerciful Disaster\nFollowed fast and followed faster till his songs one burden bore\u2014\nTill the dirges of his Hope that melancholy burden bore\nOf \u2018Never\u2014nevermore\u2019.\u201D\n\nBut the Raven still beguiling all my fancy into smiling,\nStraight I wheeled a cushioned seat in front of bird, and bust and door;\nThen, upon the velvet sinking, I betook myself to linking\nFancy unto fancy, thinking what this ominous bird of yore\u2014\nWhat this grim, ungainly, ghastly, gaunt, and ominous bird of yore\nMeant in croaking \u201CNevermore.\u201D\n\nThis I sat engaged in guessing, but no syllable expressing\nTo the fowl whose fiery eyes now burned into my bosom\u2019s core;\nThis and more I sat divining, with my head at ease reclining\nOn the cushion\u2019s velvet lining that the lamp-light gloated o\u2019er,\nBut whose velvet-violet lining with the lamp-light gloating o\u2019er,\nShe shall press, ah, nevermore!\n\nThen, methought, the air grew denser, perfumed from an unseen censer\nSwung by Seraphim whose foot-falls tinkled on the tufted floor.\n\u201CWretch,\u201D I cried, \u201Cthy God hath lent thee\u2014by these angels he hath sent thee\nRespite\u2014respite and nepenthe from thy memories of Lenore;\nQuaff, oh quaff this kind nepenthe and forget this lost Lenore!\u201D\nQuoth the Raven \u201CNevermore.\u201D\n\n\u201CProphet!\u201D said I, \u201Cthing of evil!\u2014prophet still, if bird or devil!\u2014\nWhether Tempter sent, or whether tempest tossed thee here ashore,\nDesolate yet all undaunted, on this desert land enchanted\u2014\nOn this home by Horror haunted\u2014tell me truly, I implore\u2014\nIs there\u2014is there balm in Gilead?\u2014tell me\u2014tell me, I implore!\u201D\nQuoth the Raven \u201CNevermore.\u201D\n\n\u201CProphet!\u201D said I, \u201Cthing of evil!\u2014prophet still, if bird or devil!\nBy that Heaven that bends above us\u2014by that God we both adore\u2014\nTell this soul with sorrow laden if, within the distant Aidenn,\nIt shall clasp a sainted maiden whom the angels name Lenore\u2014\nClasp a rare and radiant maiden whom the angels name Lenore.\u201D\nQuoth the Raven \u201CNevermore.\u201D\n\n\u201CBe that word our sign of parting, bird or fiend!\u201D I shrieked, upstarting\u2014\n\u201CGet thee back into the tempest and the Night\u2019s Plutonian shore!\nLeave no black plume as a token of that lie thy soul hath spoken!\nLeave my loneliness unbroken!\u2014quit the bust above my door!\nTake thy beak from out my heart, and take thy form from off my door!\u201D\nQuoth the Raven \u201CNevermore.\u201D\n\nAnd the Raven, never flitting, still is sitting, still is sitting\nOn the pallid bust of Pallas just above my chamber door;\nAnd his eyes have all the seeming of a demon\u2019s that is dreaming,\nAnd the lamp-light o\u2019er him streaming throws his shadow on the floor;\nAnd my soul from out that shadow that lies floating on the floor\nShall be lifted\u2014nevermore!"); 
 
}, 100);

Uważaj, to zajmuje trochę czasu, aby obliczyć.

+0

Dzięki za obejrzenie tego. Wydaje mi się, że to w ogóle nie działa. Oto, co widzę: https://api.monosnap.com/rpc/file/download?id=kzwLI6dcguwVDTV8Xyc77fNp3wb3wK – jcbmb

+0

Działa również znacznie lepiej w Chrome. Dzięki, że powinno załatwić sprawę. – jcbmb

+0

Gra z Twoim rozwiązaniem jest świetna i prosta, jednak szuka rozwiązania z krzywymi Beziera itp. Tak więc używając wielokątów, które są nieco bardziej skomplikowane. – jcbmb