繁体   English   中英

有没有办法在没有透明部分的 2d 画布上绘制图像片段?

[英]Is there a way to draw pieces of the image on 2d canvas without transparent parts?

我想在没有透明部分的画布上绘制这个图像。 我的渲染原理是使用createImageBitmap方法从大图像中裁剪出小图像并将它们存储在数组中。 然后我将它们一一呈现在画布上。 问题是它还不必要地绘制了透明部分。 所以如果我记录我的数组,我会得到这个 由于我的地图是 10x10 瓦片,因此会生成 100 张图像(其中 96 张是无用的)。 相反,我只想保存 4 张图像。

不仅它搞砸了我的表现,而且我还有更多的理由让我感到困扰。 有没有办法解决这个问题?

到目前为止我的代码:

(async () => {
    const img = new Image();
    img.src = "./img/obstacles.png";
    await img.decode();

    let tiles = [];
    let tileWidth = 32;
    let tileHeight = 32;

    for (let i = 0; i < 100; i++) {
        let x = i % 10;
        let y = Math.floor(i / 10);

        let bmp = await createImageBitmap(img, x * tileWidth, y * tileHeight, tileWidth, tileHeight); // index.js:13

        tiles.push({
            bmp,
            x,
            y
        })
    }

    console.log(tiles)

    const canvas = document.querySelector("canvas");
    canvas.width = 320;
    canvas.height = 320;

    const ctx = canvas.getContext("2d");

    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        tiles.forEach((tile) => {
            ctx.drawImage(tile.bmp, tile.x * tileWidth, tile.y * tileHeight);
        })

        // requestAnimationFrame(draw)
    }
    draw();

})();

最好的办法是正确准备你的资产,所以这意味着你的图集中只有 3 个独特的精灵:

OP 没有透明槽的图集

然后,您可以使用简单的循环将它们作为单独的对象获取。

但是,在同一个图集中拥有不同大小的精灵并不少见,在这种情况下,您的简单循环将无法执行。 相反,您应该准备一个坐标字典(例如作为 JSON 文件,或直接嵌入到您的 js 中),其中包含每个精灵的所有坐标。

大多数 spritesheet 生成工具都会为您生成这个。

这是一个示例,我刚刚在图集中添加了一个大精灵:

三个小精灵和一个大精灵的图集

 (async () => { // If you are same-origin, it's better to fetch as a Blob // and create your ImageBitmap from the Blob // Here we aren't, so we have to go through an <img> const img = new Image(); img.src = "https://i.stack.imgur.com/h7w1C.png"; await img.decode(); document.body.append(img); // We hardcode the coords of each sprite const map = [ // [x, y, w, h] [0, 0, 32, 32], [0, 32, 32, 32], [0, 64, 32, 32], [32, 0, 96, 96], ]; const tiles = []; for (const [x, y, w, h] of map) { const bmp = await createImageBitmap(img, x, y, w, h); tiles.push({ bmp, x, y }) } console.log(tiles) const canvas = document.querySelector("canvas"); canvas.width = 320; canvas.height = 320; const ctx = canvas.getContext("2d"); let m = 0; function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); m = (m + 0.005) % 0.5; const margin = m + 1; tiles.forEach((tile) => { // we add some margin to show these are separate bitmaps ctx.drawImage(tile.bmp, tile.x * margin, tile.y * margin); }) requestAnimationFrame(draw) } draw(); })().catch(console.error);
 .as-console-wrapper { max-height: 100px !important }
 <canvas></canvas>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM