API Docs for: 1.0.1

File: js\grape\resource\sprite.js

define(['../class', '../env', './cacheable'], function (Class, Env, Cacheable) {
    function readUInt32(data) {
        var b1, b2, b3, b4;
        b1 = data[data.pos++] << 24;
        b2 = data[data.pos++] << 16;
        b3 = data[data.pos++] << 8;
        b4 = data[data.pos++];
        return b1 | b2 | b3 | b4;
    }

    function readSection(data) {
        var i, _i, chars;
        chars = [];
        for (i = _i = 0; _i < 4; i = ++_i) {
            chars.push(String.fromCharCode(data[data.pos++]));
        }
        return chars.join('');
    }

    function getImageSize(data) {
        //TODOv2 works only for png
        var chunkSize, section;
        data.pos = 8; //TODOv2 before this should be '..PNG...'
        while (data.pos < data.length) {
            chunkSize = readUInt32(data);
            section = readSection(data);
            if (section === 'IHDR') {
                return  {
                    width: readUInt32(data),
                    height: readUInt32(data)
                };
            } else {
                data.pos += chunkSize;
            }
        }
        throw new Error('Failed to determine image size');
    }

    /**
     * A sprite is an image or an animation. It can be defined as a part of a real image (tile sets).
     * When a sprite is an animation, the subsequent images have to be next to each other (left to right direction)
     *
     * @class Grape.Sprite
     * @uses Grape.Cacheable
     * @constructor
     * @param {String} url
     * @param {Object} opts Initial properties
     */
    return Class('Sprite', Cacheable, {
        init: function (url, opts) {
            opts = opts || {};
            /**
             * The left position of the sprite in the image.
             *
             * @property left
             * @type {Number}
             * @default 0
             */
            this.left = opts.left || 0;
            /**
             * The top position of the sprite in the image.
             *
             * @property top
             * @type {Number}
             * @default 0
             */
            this.top = opts.top || 0;
            /**
             * The left side of the sprite's bounding box
             *
             * @property leftBounding
             * @type {Number}
             * @default 0
             */
            this.leftBounding = opts.leftBounding || 0;
            /**
             * The top side of the sprite's bounding box
             *
             * @property topBounding
             * @type {Number}
             * @default 0
             */
            this.topBounding = opts.topBounding || 0;

            /**
             * The x coordinate of the sprite origin
             *
             * @property originX
             * @type {Number}
             * @default 0
             */
            this.originX = opts.originX || 0;
            /**
             * The y coordinate of the sprite origin
             *
             * @property originY
             * @type {Number}
             * @default 0
             */
            this.originY = opts.originY || 0;
            this.url = url;
            /**
             * The number of subimages (animation length). Subsequent images have to be arranged left to right.
             *
             * @property subimages
             * @type {Number}
             * @default 1
             */
            this.subimages = opts.subimages || 1;

            //if the following parameters are not set, they are set if the image is processed.
            /**
             * The width of the sprite. If not set, it will be calculated by the image width and the animation length.
             *
             * @property width
             * @type {Number}
             */
            this.width = opts.width;
            /**
             * The height of the sprite. If not set, it will be the height of the image.
             *
             * @property height
             * @type {Number}
             */
            this.height = opts.height;
            /**
             * The right side of the sprite's bounding box. If not set, it will be the image width.
             *
             * @property rightBounding
             * @type {Number}
             */
            this.rightBounding = opts.rightBounding;
            /**
             * The bottom side of the sprite's bounding box. If not set it will be the image height.
             *
             * @property bottomBounding
             * @type {Number}
             */
            this.bottomBounding = opts.bottomBounding;
        },
        'override loadResource': function (onFinish, onError) {
            if (Env.node) {
                /*global originalRequire*/
                var fs = originalRequire('fs');
                fs.readFile(this.url, function (err, file) {
                    if (err) {
                        onError();
                    } else {
                        onFinish(getImageSize(file));
                    }
                });
            } else {
                var img = document.createElement('img');
                img.onload = function () {
                    onFinish(img);
                };
                img.onerror = function () {
                    onError();
                };

                img.src = this.url;
            }
        },
        'override getResourceKey': function () {
            return this.url;
        },
        'override process': function (img) {
            this.img = img;
            if (this.width === undefined) {
                this.width = img.width / this.subimages;
            }
            if (this.height === undefined) {
                this.height = img.height;
            }
            if (this.rightBounding === undefined) {
                this.rightBounding = this.width;
            }
            if (this.bottomBounding === undefined) {
                this.bottomBounding = this.height;
            }
        }
    });
});