0

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

  • 在 KineticJS 中有没有最好的方法来做到这一点?
  • 有没有办法复制图像的一部分并将其绘制在图层上?
4

2 回答 2

1

如果您使用 Kinetic.Shape,您将获得一个可以使用的画布上下文。

(它实际上是围绕实际上下文的包装器——但它几乎是功能齐全的)。

然后使用带有裁剪参数的 context.drawImage 来裁剪“字体精灵表”中的字母。

还要记住,没有什么能阻止您为像您这样的任务创建屏幕外 html 画布。

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

干杯!

于 2013-12-16T17:41:35.483 回答
0

这个答案是基于markE在他的回答中给我的信息。

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

解释

我在脚本顶部加载精灵表。在函数“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>

附加信息:

  • 我在顶部加载精灵表。我使用 settimeout 所以一旦我在画布中需要它,图像就会被加载
  • 我刚刚映射了精灵表中的数字 0-3
  • 出于测试目的,屏幕外画布仍然可见。只需使用“display:none”设置样式即可隐藏它
于 2013-12-18T13:19:54.080 回答