javascript - Canvas/JS 存储矢量/位图对象

标签 javascript canvas

在我的 Canvas 项目中,我有两种类型的 Sprite 对象,一种是用矢量图形绘制的,另一种是在 Canvas 上绘制位图图像的。

draw function(context){
 ...
 context.lineTo(some place)
 context.lineTo(some other place)
 etc.
}

另一种类型的 Sprite 是位图图像,目前它们是占位符资源,因此足够小,不需要 onload 事件处理程序,但实际资源会更大,因此需要一个。

bitmap loadImage function(){

   this.image = new Image(); 
   //Currently my images are too small to warrant an onload eventHandler as they're placeholders
   this.image.src = "some path";
} 

目前,我将所有 Sprite 存储在同一个容器中,并通过一个简单的循环执行绘图。这目前有效,因为位图 Sprite 没有加载函数。

for each sprite {

 sprite.draw(context);
 }

一旦我用 Sprite 表替换了占位符资源,它们将需要一个分配给 onload 事件的函数 - 这会阻碍我的设计。

任何人都可以阐明如何实现将所有 Sprite 存储在同一个容器中并通过迭代该集合来调用绘制吗?

注意:随着 onload 事件处理程序添加位图绘制,但是(显然)在加载图像之前在位图 Sprite 上调用绘制时,我收到错误。

最佳答案

我制作了这个加载程序,它允许您向其中添加所有图像 URL,然后调用 load() 来启动加载。

您可以使用此类加载器来支持进度回调,以便向用户显示当前进度。

如果您需要跨源图像,您可以通过添加一个标志来告诉加载的图像为您设置跨源类型,从而添加对此的支持。以下示例为所有图像设置了此设置,但可以对其进行扩展以支持单个图像。

<强> Live demo here

加载器:

/// callback - function to call when finished (mandatory)
/// progress - function to call for each image loaded (optional)
/// progress contains an argument with an "event" containing properties
/// img (the image loaded), url, current (integer) and total (integer)
function imageLoader(callback, progress, error) {

    if (typeof callback !== 'function') throw 'Need a function for callback!';

    var lst = [],
        crossOrigin = false;

    this.crossOrigin = function (state) {
        if (typeof state !== 'bool') return crossOrigin;
        crossOrigin = state;
        return this;
    }
    this.add = function (url) {
        lst.push(url);
        return this;
    }

    this.load = function () {
        if (lst.length > 0) {
            startLoading();
        }
        return this;
    }

    function startLoading() {

        var i = 0,
            url,
            count = lst.length,
            images = [];

        for (; url = lst[i]; i++) {
            var img = document.createElement('img');
            images.push(img);

            img.onload = function () {
                _handler(url, this)
            };
            img.onerror = function (e) {
                _handlerError(url, e)
            };

            if (crossOrigin === true) img.crossOrigin = 'anonymous';

            img.src = url;
        }

        function _handler(url, img) {

            count--;

            if (typeof progress === 'function') progress({
                current: lst.length - count,
                total: lst.length,
                url: url,
                img: img
            });

            if (count === 0) callback({
                images: images,
                urls: lst
            });
        }

        function _handlerError(url, e) {
            if (typeof error === 'function') error({
                url: url,
                error: e
            });

            console.warn('WARNING: Could not load image:', url);
            _handler();
        }
    }

    return this;
}

用法:

var loader = new imageLoader(done, progress);

/// methods can be chained:
loader.add(url1)
      .add(url2)
      .add(url3)

      .load();

(完整示例请参阅演示)

处理程序可以执行以下操作:

function done(e) {

    for (i = 0; i < e.images.length; i++) {

        /// draw the image
        ctx.drawImage(e.images[i], i * 20, i * 20, 40, 40);
    }
}

function progress(e) {

    ///progress bar
    status.style.width = ((e.current / e.total) * 100).toFixed(0) + '%';

    /// current loaded image
    ctx.drawImage(e.img, 0, 340, 60, 60);
}

关于javascript - Canvas/JS 存储矢量/位图对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19798250/

相关文章:

javascript - 跳转播放音频

javascript - 创建零填充 JavaScript 数组的最有效方法是什么?

java - 在带有彩色背景的 Canvas 上绘制位图(来自可绘制对象)

android - 如何清理位图?

javascript - 如何避免在 HTML5 Canvas 中对特定颜色着色

javascript - 如何为对象数组编写 firestore 查询过滤器?

javascript - 按年份和月份对数组进行排序

java - 如何确定用户是否触摸了我的位图?

javascript - 为什么我的 HTML5 Canvas 绘图会这样?

javascript - 使用 Javascript 获取以前的日期