[英]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
構造函數的工作原理。 所以我寫了一個獨立的函數(不屬於任何對象)。 傳遞給此函數所需的只是一個字符串, X
和Y
位置,行高和填充。 它假定將畫布分配給變量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: absolute
和position: relative
。
我認為你應該有一個DOM元素,其中所有文本都是透明的顏色,每個字母都包含一個<span>
。 然后,您只需通過調整不透明度開始使這些<span>
可見。 這樣字母的位置就不會改變。
就個人而言,當我在畫布游戲中需要文本時,我總是使用位圖字體。 它有幾個優點:
您仍然可以通過使用案例合成操作來選擇字體顏色,並通過動態調整繪制寬度高度來獲得字體大小。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.