我正在尝试在HTML5 Canvas上获得动画打字机效果,但我真的很难使用Word Wrapping。
这是我的Shapes中的Shapes.js:https://gist.github.com/Jamesking56/0d7df54473085b3c5394
在那里,我创建了一个Text对象,它有很多方法。其中一个名为typeText()
。
typeText()
基本上从打字效果开始,但它一直在下降,我真的很难找到修复自动换行的方法。
有人可以指导我做最好的方法吗?
答案 0 :(得分: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
}
由于似乎无法测量输出文本的高度,因此您需要手动将输出的每一行偏移一些硬编码的行高。
答案 1 :(得分:0)
我无法弄清楚你的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);
}
查看演示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);
};
}
您不应该通过构造函数向对象添加方法,因为每次实例化对象时都会创建方法。而是将方法添加到对象的原型中,这样,它们将只创建一次并由所有实例共享。象 -
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 here。
希望有所帮助。
PS:每个角色75毫秒,每分钟800字符!
更新 - 如果您想要可扩展的图形,则应考虑SVG。 Canvas是基于栅格的,而SVG是基于矢量的。这意味着SVG可以很容易地调整大小,而当您调整画布大小时,画布的内容将开始像素化并且看起来模糊。 Read more。
要调整画布内容的大小,您需要重新绘制整个画布。每当在画布上绘制某些内容时,浏览器就会绘制并忘记它。因此,如果要更改对象的大小/位置,则需要完全清除画布并重绘对象。在您的情况下,您需要根据画布的大小更改ctx.font
,然后更新画布,这将是一项非常繁琐的任务。
答案 2 :(得分:-1)
<canvas>
不适用于文字处理。通过在<canvas>
的顶部覆盖透明DOM元素,可以更加轻松地完成此操作。这自然会假设您不需要在<canvas>
中对文本像素进行后期处理。否则你需要在Javascript中重新实现整个文本处理的东西,这有点重新发明轮子,因为浏览器可以简单地为我们做。
以下是有关如何使用CSS position: absolute
和position: relative
执行此操作的更多信息。
Allowing the user to type text in a HTML5 Canvas game
我认为你应该有一个DOM元素,其中所有文本都是透明的颜色,每个字母都包含一个<span>
。然后,您只需通过调整不透明度开始使<span>
可见。通过这种方式,字母位置不会改变。
答案 3 :(得分:-1)
就个人而言,当我在画布游戏中需要文本时,我总是使用位图字体。它有几个优点:
您仍然可以通过使用案例合成操作来选择字体颜色,并通过动态调整绘制宽度高度来获得字体大小。