UNPKG

16.1 kBJavaScriptView Raw
1"use strict";
2var __extends = (this && this.__extends) || (function () {
3 var extendStatics = Object.setPrototypeOf ||
4 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6 return function (d, b) {
7 extendStatics(d, b);
8 function __() { this.constructor = d; }
9 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
10 };
11})();
12var __assign = (this && this.__assign) || Object.assign || function(t) {
13 for (var s, i = 1, n = arguments.length; i < n; i++) {
14 s = arguments[i];
15 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
16 t[p] = s[p];
17 }
18 return t;
19};
20var __rest = (this && this.__rest) || function (s, e) {
21 var t = {};
22 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
23 t[p] = s[p];
24 if (s != null && typeof Object.getOwnPropertySymbols === "function")
25 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
26 t[p[i]] = s[p[i]];
27 return t;
28};
29Object.defineProperty(exports, "__esModule", { value: true });
30var SideralObject_1 = require("./../SideralObject");
31var Tool_1 = require("./../Tool");
32var index_1 = require("./../index");
33/**
34 * SideralObject visible on screen
35 */
36var Module = (function (_super) {
37 __extends(Module, _super);
38 /* LIFECYCLE */
39 /**
40 * @constructor
41 */
42 function Module() {
43 var _this = _super.call(this) || this;
44 /**
45 * PIXI Container (a module must have a pixi container)
46 * @readonly
47 */
48 _this.container = new index_1.PIXI.Container();
49 /**
50 * Know if the module is clickable
51 * @private
52 */
53 _this._clickable = false;
54 /**
55 * Know if it is the first mouse hover event fired
56 * @private
57 */
58 _this._mouseHover = false;
59 /**
60 * Know if children must be sorted or not
61 * @private
62 */
63 _this._sortRequested = false;
64 _this.setProps({
65 x: 0,
66 y: 0,
67 vx: 0,
68 vy: 0,
69 width: 0,
70 height: 0,
71 angle: 0,
72 opacity: 1,
73 flip: false,
74 visible: true
75 });
76 _this.timers = _this.add(new SideralObject_1.TimerManager());
77 _this.signals.click = new SideralObject_1.Signal(_this, _this.onBindClick.bind(_this), _this.onRemoveClick.bind(_this));
78 _this.signals.doubleClick = new SideralObject_1.Signal(_this, _this.onBindClick.bind(_this), _this.onRemoveClick.bind(_this));
79 _this.signals.hover = new SideralObject_1.Signal(_this, _this.onBindClick.bind(_this), _this.onRemoveClick.bind(_this));
80 _this.signals.hoverStart = new SideralObject_1.Signal(_this, _this.onBindClick.bind(_this), _this.onRemoveClick.bind(_this));
81 _this.signals.hoverEnd = new SideralObject_1.Signal(_this, _this.onBindClick.bind(_this), _this.onRemoveClick.bind(_this));
82 return _this;
83 }
84 /**
85 * @initialize
86 * @override
87 */
88 Module.prototype.initialize = function (props) {
89 // We call the updateFollow to update the position of the module before create the Physic
90 if (props.follow) {
91 this.updateFollow(null, props.follow);
92 props.x = this.props.x;
93 props.y = this.props.y;
94 }
95 _super.prototype.initialize.call(this, props);
96 this.connect(this.signals.propChange, ["visible", "opacity"], this.onVisibilityChange.bind(this))
97 .connect(this.signals.propChange, "angle", this.updateContainerPosition.bind(this))
98 .connect(this.signals.propChange, ["x", "y"], this.onPositionChange.bind(this))
99 .connect(this.signals.propChange, ["width", "height"], this.onSizeChange.bind(this))
100 .connect(this.signals.propChange, "flip", this.onFlipChange.bind(this))
101 .connect(this.signals.update, this.updateFollow.bind(this), this.updateVelocity.bind(this));
102 this.onVisibilityChange();
103 this.updateContainerPosition();
104 };
105 /**
106 * @update
107 * @override
108 */
109 Module.prototype.update = function (tick) {
110 _super.prototype.update.call(this, tick);
111 if (this._mouseHover) {
112 this.signals.hover.dispatch();
113 }
114 };
115 /**
116 * @override
117 */
118 Module.prototype.kill = function () {
119 _super.prototype.kill.call(this);
120 this.removeContainer();
121 };
122 /* METHODS */
123 /**
124 * Remove the pixi Container
125 */
126 Module.prototype.removeContainer = function () {
127 if (this.container) {
128 this.container.destroy();
129 }
130 this.container = null;
131 };
132 /**
133 * Set a new position of the module
134 * @param x - The position in x axis
135 * @param y - The position in y axis
136 */
137 Module.prototype.position = function (x, y) {
138 x = typeof x === "undefined" ? this.props.x : x;
139 y = typeof y === "undefined" ? this.props.y : y;
140 if (!this.initialized) {
141 this.setProps({ x: x, y: y });
142 }
143 else {
144 this.props.x = x;
145 this.props.y = y;
146 }
147 };
148 /**
149 * Set a new size of the module
150 * @param width - The next width of the module
151 * @param height - The next height of the module
152 */
153 Module.prototype.size = function (width, height) {
154 width = typeof width === "undefined" ? this.props.width : width;
155 height = typeof height === "undefined" ? this.props.height : height;
156 if (!this.initialized) {
157 this.setProps({ width: width, height: height });
158 }
159 else {
160 this.props.width = width;
161 this.props.height = height;
162 }
163 };
164 /**
165 * Add an item to the current object. The item added will enter into the lifecycle of the object and will become a children
166 * of this object. The method "initialize" of the item will be called.
167 * @access public
168 * @param item - A SideralObject
169 * @param props - Props to merge to the item
170 * @param z - The z index of the item
171 * @returns The item initialized
172 */
173 Module.prototype.add = function (item, props, z) {
174 if (props === void 0) { props = {}; }
175 props = props || {};
176 if (typeof z !== "undefined") {
177 props.z = z;
178 }
179 _super.prototype.add.call(this, item, props);
180 if (item instanceof Module) {
181 if (typeof props.z !== "undefined") {
182 this.container.addChildAt(item.container, z);
183 }
184 else {
185 this.container.addChild(item.container);
186 }
187 }
188 return item;
189 };
190 /**
191 * This method is an helper to add a module. It is much faster than add when you must give a "x" and "y" properties
192 * @access public
193 * @param item - Module to add
194 * @param x - The position in x axis
195 * @param y - The position in y axis
196 * @param props - Other properties to merge to the module
197 * @param z - The z index of the item
198 * @returns The module initialize
199 */
200 Module.prototype.spawn = function (item, x, y, props, z) {
201 if (props === void 0) { props = {}; }
202 if (!(item instanceof Module)) {
203 throw new Error("Module.spawn : The item must ben an instance of Module");
204 }
205 props.x = x;
206 props.y = y;
207 return this.add(item, props, z);
208 };
209 /**
210 * Spawn multiple modules
211 * @param params - Parameters of the multiple spawn
212 */
213 Module.prototype.spawnMultiple = function (params) {
214 params.forEach(function (param) {
215 if (!param.props) {
216 param.props = {};
217 }
218 param.props.x = param.x;
219 param.props.y = param.y;
220 param.props.z = param.z;
221 });
222 return _super.prototype.addMultiple.call(this, params);
223 };
224 /**
225 * Create a new transition for the module
226 * @param type - Type of transition (it could be the name of a property to change or an Enum.TRANSITION)
227 * @param duration - The duration of transtion
228 * @param options - Options of transition (see ITransition)
229 */
230 Module.prototype.addTransition = function (type, duration, _a) {
231 var _this = this;
232 if (_a === void 0) { _a = {}; }
233 var from = _a.from, to = _a.to, complete = _a.complete, update = _a.update, options = __rest(_a, ["from", "to", "complete", "update"]);
234 from = typeof from === "undefined" ? this.props[type] : from,
235 to = typeof to === "undefined" ? this.props[type] : to;
236 if (typeof duration !== "number") {
237 throw Error("Module.addtransition: duration must be a number");
238 }
239 this.timers.addTimer(type, duration, complete, __assign({}, options, { update: function (tick, value, ratio) {
240 _this.props[type] = from + ((to - from) * ratio);
241 if (update) {
242 update(tick, value, ratio);
243 }
244 } }));
245 return this;
246 };
247 /**
248 * Swap the current PIXI container to another PIXI container. This is usefull if you want to change
249 * the PIXI Object without destroy children and parent relationship.
250 * @access protected
251 * @param nextContainer: PIXI Container
252 * @returns -
253 */
254 Module.prototype.swapContainer = function (nextContainer) {
255 var _this = this;
256 if (!this.parent || !(this.parent instanceof Module)) {
257 return null;
258 }
259 var containerIndex = this.parent.container.children.findIndex(function (child) { return child === _this.container; }), children = this.container.children.slice(0);
260 this.parent.container.removeChild(this.container);
261 this.container.destroy();
262 if (containerIndex > -1) {
263 this.parent.container.addChildAt(nextContainer, containerIndex);
264 }
265 else {
266 this.parent.container.addChild(nextContainer);
267 }
268 this.container = nextContainer;
269 children.forEach(function (child) { return _this.container.addChild(child); });
270 };
271 /**
272 * Use this method to follow this entity by an other entity
273 * @param centered - if True, the follower will be centered to the followed
274 * @param offsetX - Offset in x axis
275 * @param offsetY - Offset in y axis
276 * @param offsetFlipX - Set a special offset in x axis if the followed is flipped
277 * @returns Configuration object to follow this entity
278 */
279 Module.prototype.beFollowed = function (centered, offsetX, offsetY, offsetFlipX) {
280 if (centered === void 0) { centered = false; }
281 if (offsetX === void 0) { offsetX = 0; }
282 if (offsetY === void 0) { offsetY = 0; }
283 if (offsetFlipX === void 0) { offsetFlipX = null; }
284 return {
285 target: this,
286 centered: centered,
287 offsetX: offsetX,
288 offsetY: offsetY,
289 offsetFlipX: offsetFlipX
290 };
291 };
292 /**
293 * Get its position relative to the position of the scene
294 * @return The relative position
295 */
296 Module.prototype.getRelativePosition = function () {
297 var scene = this.context.scene;
298 if (scene && this.container) {
299 var point = this.container.toLocal(new index_1.PIXI.Point(scene.props.x, scene.props.y));
300 return { x: point.x * -1, y: point.y * -1 };
301 }
302 return { x: this.props.x, y: this.props.y };
303 };
304 /**
305 * Update the velocity of the module related to the tick
306 * @param tick - The tick
307 */
308 Module.prototype.updateVelocity = function (tick) {
309 this.props.x += this.props.vx * tick;
310 this.props.y += this.props.vy * tick;
311 };
312 /* EVENTS */
313 /**
314 * Event fired when "x" or "y" properties has changed
315 */
316 Module.prototype.onPositionChange = function () {
317 this.updateContainerPosition();
318 };
319 /**
320 * Event fired when "width" or "height" properties has changed
321 */
322 Module.prototype.onSizeChange = function () {
323 this.updateContainerPosition();
324 };
325 /**
326 * Update the position of the pixi container
327 */
328 Module.prototype.updateContainerPosition = function () {
329 if (this.container) {
330 this.container.pivot.set(this.props.width / 2, this.props.height / 2);
331 this.container.position.set(this.props.x + this.container.pivot.x, this.props.y + this.container.pivot.y);
332 this.container.rotation = Tool_1.Util.toRadians(this.props.angle);
333 }
334 };
335 /**
336 * Update the position of this entity if it follows a target
337 */
338 Module.prototype.updateFollow = function (tick, follow) {
339 follow = follow || this.props.follow;
340 if (follow) {
341 var offsetX = follow.offsetX, offsetY = follow.offsetY, offsetFlipX = follow.offsetFlipX, centered = follow.centered, target = follow.target;
342 this.props.x = target.props.x + (target.props.flip && offsetFlipX !== null ? offsetFlipX : offsetX) + (centered ? (target.props.width / 2) - (this.props.width / 2) : 0);
343 this.props.y = target.props.y + offsetY + (centered ? (target.props.height / 2) - (this.props.height / 2) : 0);
344 }
345 };
346 /**
347 * When "visible" or opacity property has changed
348 */
349 Module.prototype.onVisibilityChange = function () {
350 var _a = this.props, visible = _a.visible, opacity = _a.opacity;
351 if (!visible || opacity <= 0) {
352 this.container.visible = this.container.renderable = false;
353 }
354 else {
355 this.container.visible = this.container.renderable = true;
356 this.container.alpha = opacity;
357 }
358 };
359 /**
360 * When "flip" attribute change
361 */
362 Module.prototype.onFlipChange = function () {
363 this.container.scale.x = Math.abs(this.container.scale.x) * (this.props.flip ? -1 : 1);
364 this.updateContainerPosition();
365 };
366 /**
367 * Fired when a listener is added to the signal click
368 */
369 Module.prototype.onBindClick = function () {
370 var listeners = this.signals.click._listeners.length + this.signals.doubleClick._listeners.length;
371 if (!this._clickable && this.container && listeners >= 1) {
372 this.container.interactive = true;
373 this.container.buttonMode = true;
374 this._clickable = true;
375 this.container.on("click", this.signals.click.dispatch.bind(this.signals.click));
376 this.container.on("mouseout", this._onMouseOutFired.bind(this));
377 this.container.on("mouseover", this._onMouseOverFired.bind(this));
378 }
379 };
380 /**
381 * Fired when a listener is removed from the signal click
382 */
383 Module.prototype.onRemoveClick = function () {
384 var listeners = this.signals.click._listeners.length + this.signals.doubleClick._listeners.length;
385 if (this._clickable && this.container && !listeners) {
386 this.container.interactive = false;
387 this.container.buttonMode = false;
388 this._clickable = false;
389 this.container.off("click", this.signals.click.dispatch.bind(this));
390 this.container.off("mouseout", this._onMouseOutFired.bind(this));
391 this.container.off("mouseover", this._onMouseOverFired.bind(this));
392 }
393 };
394 /**
395 * When mousehover event from pixi is fired
396 * @private
397 */
398 Module.prototype._onMouseOverFired = function () {
399 this._mouseHover = true;
400 this.signals.hoverStart.dispatch();
401 };
402 /**
403 * When mouseout event from pixi is fired
404 * @private
405 */
406 Module.prototype._onMouseOutFired = function () {
407 this._mouseHover = false;
408 this.signals.hoverEnd.dispatch();
409 };
410 return Module;
411}(SideralObject_1.SideralObject));
412exports.Module = Module;