import {Point} from "../shape";
/**
* Container class.
*
* @class
* @memberof Pixel
*/
export default class Container {
/**
* Creates a container element.
*
* @class
* @param {CanvasRenderingContext2D} ctx - The screen every object is rendered to.
*/
constructor(ctx) {
/**
* Contains all sprites.
*
* @name Pixel.Container#stage
* @type {Pixel.Sprite[]}
*/
this.sprites = [];
/**
* Stores the background color.
*
* @name Pixel.Container#_backColor
* @type {string}
* @private
*/
this._backColor = "#FFFFFF";
/**
* Stores the canvas 2d context.
*
* @name Pixel.Container#ctx
* @type {CanvasRenderingContext2D}
*/
this.ctx = ctx;
/**
* I forgot what this is for but am to worried to get rid of it.
*
* @name Pixel.Container#container
* @type {boolean}
*/
this.container = true;
/**
* Stores all clickable regions on the screen.
*
* @name Pixel.Container#regions
* @type {object}
*/
this.regions = {};
/**
* All keyboard related functions exist here.
*
* @namespace Pixel.Container.keyboard
*/
this.keyboard = {};
/**
* Stores all events currently defined.
*
* @name Pixel.Container#_events
* @type {object}
* @private
*/
this._events = {};
/**
* Define keyboard event triggers.
*
* @function Pixel.Container.keyboard#on
* @param {string} name - Name of event.
* @param {Function} call - Function called whenever event occurs.
*/
this.keyboard.on = (name, call) => {
if (name === "keydown" || name === "keyup") {
this._events[name] = call;
}
else {
document["on" + name] = call;
}
};
}
/**
* Adds child to container.
*
* @function Pixel.Container#addChild
* @param {Pixel.Sprite} sprite - Sprite to add.
*/
addChild(sprite) {
this.sprites.push(sprite);
}
/**
* Locates and deletes a sprite saved in the container.
*
* @param {number} id - The ID of the sprite to be deleted.
*/
removeChild(id) {
for (let index in this.sprites) {
if (this.sprites[index].id === id) {
delete this.sprites[index];
}
}
}
/**
* Event handler.
*
* @function Pixel.Container#on
* @param {string} name - Name of event.
* @param {Function} call - Function called whenever event occurs.
*/
on(name, call) {
if (name === "mousemove" || name === "mousedown" || name === "click") {
this["on" + name] = call;
} else {
this.view.addEventListener(name, call);
}
};
/**
* Defines a new event that can be called.
*
* @function Pixel.Container#on
* @param {string} name
* @param {Function} func
*/
on(name, func) {
if (name === "mousemove" || name === "mousedown" || name === "click") {
this._events[name] = func;
} else {
this.view.addEventListener(name, call);
}
}
/**
* Gets the current mouse position.
*
* @private
* @function Pixel.Container#mousePos
* @param {DocumentEvent} event - The Document Event element.
* @param {HTMLCanvasElement} canvas - The canvas it gets the mouse position on.
* @returns {object} Returns the x and y in an object.
*/
mousePos(canvas, event) {
var rect = canvas.getBoundingClientRect(),
scaleX = canvas.width / rect.width,
scaleY = canvas.height / rect.height;
return {
x: (event.clientX - rect.left) * scaleX,
y: (event.clientY - rect.top) * scaleY
};
}
/**
* Changes the background color.
*
* @function Pixel.Container#background
* @param {string} color - The color, in hexidecimal or rgb.
*/
background(color) {
this._backColor = color;
}
/**
* Auto renders sprite.
*
* @function Pixel.Container#add
* @param {Pixel.Sprite|Pixel.SpriteSheet|Pixel.AnimatedSprite|Pixel.Map|Pixel.Rectangle|Pixel.Circle|Pixel.Text} sprite - Sprite to be rendered.
*/
add(sprite) {
return sprite.render(this.ctx);
}
/**
* Clears the screen.
*
* @private
* @function Pixel.Container#clear
*/
clear() {
this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
}
/**
* Adds clickable region to the stage.
*
* @function Pixel.Container#addHitRegion
* @param {object} opts - Options for hit region.
* @param {string} opts.name - Name of hit region.
* @param {Pixel.Point} opts.start - Start point of hit region.
* @param {Pixel.Point} opts.end - End point of hit region.
* @param {Function} call - Function called when region clicked.
*/
addHitRegion(opts, call) {
this.regions[opts.name] = new Object(Object.assign({call: call}, opts));
}
/**
* Moves all children into a Pixel.Stage element.
*
* @function Pixel.Container#cloneChildren
* @param {Pixel.Stage} base - Stage contents are moved to.
*/
cloneChildren(base) {
var con = this.contents;
for (var i in con) {
base.addChild(con[i]);
}
}
/**
* Renders all elements in container.
*
* @function Pixel.Container#render
*/
render() {
var con = this.sprites;
for (var i in con) {
con[i].render(this.ctx);
}
}
}