可以使用位图字体在KineticJs中创建文本吗?

时间:2013-12-16 15:56:25

标签: kineticjs bitmap-fonts

我喜欢“Text”级的KineticJS,但它还不足以满足我的想法。这就是为什么我想创建一个位图字体(在一个图像中包含所有字符并使用图像的一部分来创建文本)。

  • 在KineticJS中有最好的方法吗?
  • 有没有办法复制图像的一部分并在图层上绘制?

2 个答案:

答案 0 :(得分:1)

如果你使用Kinetic.Shape,你会得到一个画布上下文来使用。

(它实际上是围绕着实际的背景 - 但它几乎完全正常运作)。

然后使用带有剪切参数的context.drawImage来剪切你的"字体spritesheet"中的字母。

另请注意,没有什么可以阻止您为像您这样的任务创建屏幕外的html画布。

将spritesheet中的字母剪切到屏幕外的画布上,然后使用offscreen.toDataURL()创建一个可以在Kinetic.Image中使用的图像对象 - 两全其美!

干杯!

答案 1 :(得分:0)

此答案基于markEanswer给我的信息。

我实施了markE给我的建议,并希望与您分享代码(最后完整的工作示例)。

解释

我将spritesheet加载到脚本的顶部。在函数“drawGame()”中我创建一个新的图像将使用“create_math_task_image()” - 函数的返回值。在这个函数中,我在屏幕外画布上绘制了我需要的数字(在这个例子中,这些只是随机数)。完成绘图后,我使用c.toDataURL("image/png");抓取图像数据并将其返回。

工作示例,只需复制并粘贴到空的html文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />   <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Canvas-Spritesheet Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link href="/favicon.ico" type="image/x-icon" rel="icon" /><link href="/favicon.ico" type="image/x-icon" rel="shortcut icon" /><meta name="description" />
<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.css" />

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
  <script src="//raw.github.com/twbs/bootstrap/v3.0.0/assets/js/html5shiv.js"></script>
  <script src="//raw.github.com/twbs/bootstrap/v3.0.0/assets/js/respond.min.js"></script>
<![endif]-->

<script src="http://cdnjs.cloudflare.com/ajax/libs/kineticjs/4.7.2/kinetic.min.js"></script>

<style type="text/css">
    #container {border: 1px solid black;}
    #offscreen-canvas   {border: 1px solid red;}
</style>  

</head>
<body>
<div id="container"></div>
<canvas id="offscreen-canvas" style="display:block;"></canvas>

<script type="text/javascript">
var stage;
var game_width = 600;
var game_height = 800;

var layer_math_task = new Kinetic.Layer();

var images = new Array();
images['spritesheet'] = new Image(); 
images['spritesheet'].src = 'http://tuuduu.de/html-templates/ultimath-images/big_numbers.png';

$(function() {
    initGame();

    setTimeout(function() {
        drawGame();
    }, 1000);
});

function initGame() {
    stage = new Kinetic.Stage({
        container: 'container',
        width: game_width,
        height: game_height
    });
}

function drawGame() {
    stage.add(layer_math_task);

    var myMathTaskImgObj = new Image(); 
    myMathTaskImgObj.src = create_math_task_image();

    var image_math_task = new Kinetic.Image({ x: 0, y: 0, image: myMathTaskImgObj});
    layer_math_task.add(image_math_task);
    layer_math_task.draw();     
}


function create_math_task_image() {
    var c=document.getElementById("offscreen-canvas");
    var ctx=c.getContext("2d");
    ctx.canvas.width = game_width;
    ctx.canvas.height = game_height;
    ctx.clearRect(0, 0, game_width, game_height);

    var xpos_pointer = 0;
    var ypos_pointer = 0;

    for(var i=0; i<5; i++)
    {
        var math_task_number = Math.floor(Math.random()*4);
        switch(math_task_number)
        {
            case 0:
                ctx.drawImage(images['spritesheet'], 0, 0, 83, 110, xpos_pointer, 0, 83, 110);
                xpos_pointer += 83;     
                break;
            case 1:
                ctx.drawImage(images['spritesheet'], 84, 0, 45, 110, xpos_pointer, 0, 45, 110);
                xpos_pointer += 45;
                break;
            case 2:
                ctx.drawImage(images['spritesheet'], 131, 0, 86, 110, xpos_pointer, 0, 86, 110);
                xpos_pointer += 86;
                break;
            case 3:
                ctx.drawImage(images['spritesheet'], 218, 0, 75, 110, xpos_pointer, 0, 75, 110);
                xpos_pointer += 75;
                break; 
        }
    }

    return c.toDataURL("image/png");
}
</script>   
</body>
</html>

其他信息:

  • 我将spritesheet加载到顶部。我使用settimeout,因此一旦我在画布中需要它就会加载图像
  • 我刚从spritesheet
  • 中映射了数字0-3
  • 出于测试目的,屏幕外画布仍然可见。只需将其设置为“display:none”来隐藏它