2013-03-19 86 views
3

我想在HTML5 Canvas上獲得動畫打字機效果,但我真的很苦於Word Wrapping。HTML5帆布打字機效果與文字包裝?

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

在那裏,我已經創建了有大量的方法Text對象。其中之一被稱爲typeText()

typeText()基本上開始打字效果,但它不斷下降的邊緣,我真的很努力找到一種固定文字換行的方式。

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

+1

+1 for _solution with NO plugins!標準的JavaScript和HTML5 Canvas!_。我喜歡。但是你的代碼評論很差。目前還不清楚'typeText'方法需要什麼參數以及'baseObjects'實際是什麼。 – ShuklaSannidhya 2013-03-31 12:54:28

+0

你可以告訴你如何調用'typeText',你傳遞的是什麼參數? – ShuklaSannidhya 2013-03-31 12:58:48

+0

'baseObjects'是畫布上所有對象的數組(用於重繪)。 從Text對象調用'typeText()'。所以我會做'var text = new Text();'然後調用'text.typeText(baseObjects,20);' – Jamesking56 2013-04-01 09:40:42

回答

2

我使用了一個解決方案大致是:

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 
} 

由於似乎沒有辦法測量輸出文本的高度,你需要一些硬編碼線高度手動偏移的每一行,你的輸出。

+0

哦,我明白了,你可以預先計算出單詞,然後開始輸入它。唯一的缺點是我也在尋找響應度,所以如果用戶調整了我的畫布會發生什麼? – Jamesking56 2013-04-01 09:36:50

+0

這是迄今爲止最簡單的解決方案,但我可以將它集成到我的「文本」對象中。 – Jamesking56 2013-04-01 09:43:14

+0

@ Jamesking56您無法使用此方法添加文字效果。 – ShuklaSannidhya 2013-04-01 11:06:31

-1

<canvas>不適用於文本處理。通過在您的<canvas>的頂部覆蓋透明的DOM元素來完成此操作要容易得多。這自然會假設你不需要在<canvas>中後處理文本像素。否則,你需要在Javascript中重新實現整個文本處理的東西,這是重新發明輪子,因爲瀏覽器可以簡單地爲我們做。

下面是更多信息如何使用CSS position: absoluteposition: relative執行它。

Allowing the user to type text in a HTML5 Canvas game

我想你應該有它有透明色,每個字母包裹着<span>所有文字DOM元素。然後,您只需通過調整不透明度即可使這些<span>可見。這樣的信函職位不會改變。

+0

我想要的Type寫作效果如何?我將如何分別輸出每封信? – Jamesking56 2013-03-28 15:15:26

+0

那麼響應性呢?我的畫布反應靈敏,這樣可以覆蓋文本也能反應嗎? – Jamesking56 2013-03-28 15:17:56

+0

1)在''中包裝每個字母'2)我不明白爲什麼它不是 – 2013-03-28 15:42:19

-1

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

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

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

+0

你能舉一個例子說明你的意思以及你將如何使用位圖字體?就目前而言,這是一個不好的答案,因爲它沒有詳細說明實際實施的細節。 – 2014-04-12 13:58:19

+0

你是對的。它應該是一個評論。然而,這些文字不適合評論。所以我不應該包括它?好吧,我認爲它仍然是非常有效的,有用的信息,可以是一個看似複雜的任務,值得分享。我猜投票比較容易。 – Jarrod 2014-04-12 19:14:57

0

我想不通你的Text構造函數是如何工作的。所以我寫了一個獨立的函數(不屬於任何對象)。所有你需要傳遞給這個函數的是一個字符串,即XY的位置,行高和填充。它假設畫布被分配給變量canvas,第二個上下文被分配給變量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); 
} 

查看演示here

提示 -

我要通過你的代碼,並發現了一些聯繫這個 -

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); 
    }; 
} 

,因爲它創造的方法,每次你不應該通過構造方法添加到對象該對象被實例化。而是將方法添加到對象的原型,這樣,它們將只創建一次,並將由所有實例共享。 Like-

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); 
} 

此外,我發現你正在創建額外的變量來指向一些對象。 Like -

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

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

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 

瞭解更多關於綁定here

希望有所幫助。

PS: 75毫秒爲每個字符,這將是神聖的800個字符每分鐘!


更新 - 如果你想可擴展的圖形,你應該考慮SVG。畫布是基於柵格的,而SVG是基於矢量的。這意味着SVG可以輕鬆調整大小,而當您調整畫布的大小時,畫布的內容將開始像素化並顯得模糊。 Read more

要調整畫布的內容,您需要重新繪製整個畫布。只要在畫布上繪製東西,瀏覽器就會繪製並忘記它。所以如果你想改變對象的大小/位置,你需要完全清除畫布並重繪對象。在你的情況下,你需要根據畫布的大小更改ctx.font,然後更新畫布,這將是一個非常乏味的任務。

+0

我的演示唯一的問題是我的畫布可以由用戶調整大小(它始終與瀏覽器的高度和寬度相匹配)。如果用戶在中途調整了畫布大小,會發生什麼? – Jamesking56 2013-04-01 09:38:34

+0

感謝編碼技巧,我實際上在大學層面教授使用'this.draw = function(){}'作爲我的對象的方法。真的不知道這是否有任何標準?至於'that = this;'我實際上並不知道'.bind()'存在,所以這會很有用。 – Jamesking56 2013-04-01 09:44:42

+0

@ Jamesking56我已經更新了我的答案。 – ShuklaSannidhya 2013-04-01 18:02:16