簡體   English   中英

HTML5 Canvas打字機效果與自動換行?

[英]HTML5 Canvas typewriter effect with word wrapping?

我正試圖在HTML5 Canvas上獲得一個動畫打字機效果,但我真的在使用Word Wrapping。

這是我的Shapes中的Shapes.js: https ://gist.github.com/Jamesking56/0d7df54473085b3c5394

在那里,我創建了一個Text對象,它有很多方法。 其中一個叫做typeText()

typeText()基本上是從打字效果開始的,但它一直在脫離邊緣,我真的很難找到修復自動換行的方法。

任何人都可以指導我最好的方法嗎?

我使用的解決方案大致是:

var maxWidth = 250;
var text = 'lorem ipsum dolor et sit amet...';

var words = text.split(' ');
var line = [words[0]]; //begin with a single word

for(var i=1; i<words.length; i++){
    while(ctx.measureText(line.join(' ')) < maxWidth && i<words.length-1){
        line.push(words[i++]);
    }
    if(i < words.length-1) { //Loop ended because line became too wide
        line.pop(); //Remove last word
        i--; //Take one step back
    }
    //Ouput the line
}

由於似乎無法測量輸出文本的高度,因此需要手動將輸出的每一行偏移一些硬編碼的行高。

我無法弄清楚Text構造函數的工作原理。 所以我寫了一個獨立的函數(不屬於任何對象)。 傳遞給此函數所需的只是一個字符串, XY位置,行高和填充。 它假定將畫布分配給變量canvas ,並將2d上下文分配給變量ctx

var canvas, ctx;
function typeOut(str, startX, startY, lineHeight, padding) {
    var cursorX = startX || 0;
    var cursorY = startY || 0;
    var lineHeight = lineHeight || 32;
    padding = padding || 10;
    var i = 0;
    $_inter = setInterval(function() {
        var w = ctx.measureText(str.charAt(i)).width;
        if(cursorX + w >= canvas.width - padding) {
            cursorX = startX;
            cursorY += lineHeight;
        }
        ctx.fillText(str.charAt(i), cursorX, cursorY);
        i++;
        cursorX += w;
        if(i === str.length) {
            clearInterval($_inter);
        }
    }, 75);
}

這里查看演示。

提示 -

我正在瀏覽你的代碼並找到了一些鏈接 -

function Rectangle(x,y,width,height,colour) {
    //properties
    this.draw = function() { //Don't assigns object methods through constructors
        ctx.fillStyle = this.colour;
        ctx.fillRect(this.x, this.y, this.width, this.height);
    };
}

您不應該通過構造函數向對象添加方法,因為每次實例化對象時都會創建方法。 而是將方法添加到對象的原型中,這樣,它們將只創建一次並由所有實例共享。 喜歡-

function Rectangle(x,y,width,height,colour) {
    //properties
}
Rectangle.prototype.draw = function() {
    ctx.fillStyle = this.colour;
    ctx.fillRect(this.x, this.y, this.width, this.height);
}

此外,我發現您正在創建額外的變量來指向某些對象。 喜歡 -

var that = this;
var fadeIn = setInterval(function() {
    //code
    that.draw();
    //code
}, time);

您不應該創建對Text對象的額外引用。 使用bind方法, this將指向Text對象。 喜歡-

var fadeIn = setInterval(function() {
    //code
    this.draw(); // <-- Check this it is `this.draw` no need for `that.draw`
    //code
}.bind(this), time);   //bind the object

閱讀更多關於bind的信息

希望有所幫助。

PS:每個角色75毫秒,每分鍾800字符!


更新 - 如果你想要可擴展的圖形,你應該考慮SVG Canvas是基於柵格的,而SVG是基於矢量的。 這意味着SVG可以很容易地調整大小,而當您調整畫布大小時,畫布的內容將開始像素化並且看起來模糊。 閱讀更多

要調整畫布內容的大小,您需要重新繪制整個畫布。 每當在畫布上繪制某些內容時,瀏覽器就會繪制並忘記它。 因此,如果要更改對象的大小/位置,則需要完全清除畫布並重繪對象。 在你的情況下,你需要根據畫布的大小更改ctx.font然后更新畫布,這將是一個非常繁瑣的任務。

<canvas>不是為文本處理而設計的。 通過在<canvas>頂部覆蓋透明DOM元素,可以更加輕松地完成此操作。 當然,這假定您不需要在<canvas>后處理文本像素。 否則你需要在Javascript中重新實現整個文本處理的東西,這有點重新發明輪子,因為瀏覽器可以簡單地為我們做。

以下是有關如何使用CSS position: absolute執行它的更多信息position: absoluteposition: relative

允許用戶在HTML5 Canvas游戲中鍵入文本

我認為你應該有一個DOM元素,其中所有文本都是透明的顏色,每個字母都包含一個<span> 然后,您只需通過調整不透明度開始使這些<span>可見。 這樣字母的位置就不會改變。

就個人而言,當我在畫布游戲中需要文本時,我總是使用位圖字體。 它有幾個優點:

  1. 畫布上的FillText很慢。 位圖字體要快得多。
  2. 你知道每個字母的寬度使包裝和文本對齊更容易。

您仍然可以通過使用案例合成操作來選擇字體顏色,並通過動態調整繪制寬度高度來獲得字體大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM