2018-07-18 16:23:04 +00:00
|
|
|
/**
|
|
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
|
|
* @copyright 2018 Photon Storm Ltd.
|
|
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
|
|
|
*/
|
|
|
|
|
|
|
|
var Class = require('../../utils/Class');
|
|
|
|
var Components = require('../components');
|
|
|
|
var DOMElementRender = require('./DOMElementRender');
|
2018-07-18 23:22:38 +00:00
|
|
|
var GameObject = require('../GameObject');
|
2018-08-08 14:01:29 +00:00
|
|
|
var RemoveFromDOM = require('../../dom/RemoveFromDOM');
|
2018-07-18 23:22:38 +00:00
|
|
|
var Vector4 = require('../../math/Vector4');
|
2018-07-18 16:23:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @classdesc
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @class DOMElement
|
|
|
|
* @extends Phaser.GameObjects.GameObject
|
2018-10-10 09:49:13 +00:00
|
|
|
* @memberof Phaser.GameObjects
|
2018-07-18 16:23:04 +00:00
|
|
|
* @constructor
|
|
|
|
* @since 3.12.0
|
|
|
|
*
|
|
|
|
* @extends Phaser.GameObjects.Components.Alpha
|
|
|
|
* @extends Phaser.GameObjects.Components.BlendMode
|
2018-07-18 23:22:38 +00:00
|
|
|
* @extends Phaser.GameObjects.Components.ComputedSize
|
2018-07-18 16:23:04 +00:00
|
|
|
* @extends Phaser.GameObjects.Components.Depth
|
|
|
|
* @extends Phaser.GameObjects.Components.Origin
|
|
|
|
* @extends Phaser.GameObjects.Components.ScrollFactor
|
|
|
|
* @extends Phaser.GameObjects.Components.Transform
|
|
|
|
* @extends Phaser.GameObjects.Components.Visible
|
|
|
|
*
|
|
|
|
* @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time.
|
|
|
|
* @param {number} x - The horizontal position of this Game Object in the world.
|
|
|
|
* @param {number} y - The vertical position of this Game Object in the world.
|
2018-07-18 23:22:38 +00:00
|
|
|
* @param {(string|HTMLElement)} [element] - The DOM Element to use.
|
2018-07-18 16:23:04 +00:00
|
|
|
*/
|
|
|
|
var DOMElement = new Class({
|
|
|
|
|
|
|
|
Extends: GameObject,
|
|
|
|
|
|
|
|
Mixins: [
|
|
|
|
Components.Alpha,
|
|
|
|
Components.BlendMode,
|
2018-07-18 23:22:38 +00:00
|
|
|
Components.ComputedSize,
|
2018-07-18 16:23:04 +00:00
|
|
|
Components.Depth,
|
2018-07-18 23:22:38 +00:00
|
|
|
Components.Origin,
|
2018-07-18 16:23:04 +00:00
|
|
|
Components.ScrollFactor,
|
|
|
|
Components.Transform,
|
|
|
|
Components.Visible,
|
|
|
|
DOMElementRender
|
|
|
|
],
|
|
|
|
|
|
|
|
initialize:
|
|
|
|
|
|
|
|
function DOMElement (scene, x, y, element)
|
|
|
|
{
|
|
|
|
GameObject.call(this, scene, 'DOMElement');
|
|
|
|
|
|
|
|
this.parent = scene.sys.game.domContainer;
|
|
|
|
|
2018-07-19 12:22:13 +00:00
|
|
|
this.cache = scene.sys.cache.html;
|
|
|
|
|
2018-07-18 16:23:04 +00:00
|
|
|
this.node;
|
|
|
|
|
2018-07-18 23:22:38 +00:00
|
|
|
this.skewX = 0;
|
|
|
|
this.skewY = 0;
|
|
|
|
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d
|
|
|
|
this.rotate3d = new Vector4();
|
|
|
|
this.rotate3dAngle = 'deg';
|
|
|
|
|
2018-07-19 15:22:58 +00:00
|
|
|
this.handler = this.dispatchNativeEvent.bind(this);
|
|
|
|
|
2018-07-18 23:22:38 +00:00
|
|
|
this.setPosition(x, y);
|
|
|
|
|
|
|
|
if (element)
|
|
|
|
{
|
|
|
|
this.setElement(element);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
setSkew: function (x, y)
|
|
|
|
{
|
|
|
|
if (x === undefined) { x = 0; }
|
|
|
|
if (y === undefined) { y = x; }
|
|
|
|
|
|
|
|
this.skewX = x;
|
|
|
|
this.skewY = y;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-07-19 15:22:58 +00:00
|
|
|
perspective: {
|
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
|
|
|
return parseFloat(this.parent.style.perspective);
|
|
|
|
},
|
|
|
|
|
|
|
|
set: function (value)
|
|
|
|
{
|
|
|
|
this.parent.style.perspective = value + 'px';
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2018-07-18 23:22:38 +00:00
|
|
|
setPerspective: function (value)
|
|
|
|
{
|
|
|
|
// Sets it on the DOM Container!
|
|
|
|
this.parent.style.perspective = value + 'px';
|
|
|
|
|
|
|
|
return this;
|
2018-07-18 16:23:04 +00:00
|
|
|
},
|
|
|
|
|
2018-07-19 15:22:58 +00:00
|
|
|
addListener: function (events)
|
2018-07-19 12:22:13 +00:00
|
|
|
{
|
2018-07-19 15:22:58 +00:00
|
|
|
if (this.node)
|
2018-07-19 12:22:13 +00:00
|
|
|
{
|
2018-07-19 15:22:58 +00:00
|
|
|
events = events.split(' ');
|
|
|
|
|
|
|
|
for (var i = 0; i < events.length; i++)
|
|
|
|
{
|
|
|
|
this.node.addEventListener(events[i], this.handler, false);
|
|
|
|
}
|
2018-07-19 12:22:13 +00:00
|
|
|
}
|
|
|
|
|
2018-07-19 15:22:58 +00:00
|
|
|
return this;
|
|
|
|
},
|
2018-07-19 12:22:13 +00:00
|
|
|
|
2018-07-19 15:22:58 +00:00
|
|
|
removeListener: function (events)
|
|
|
|
{
|
|
|
|
if (this.node)
|
2018-07-19 12:22:13 +00:00
|
|
|
{
|
2018-07-19 15:22:58 +00:00
|
|
|
events = events.split(' ');
|
|
|
|
|
|
|
|
for (var i = 0; i < events.length; i++)
|
|
|
|
{
|
|
|
|
this.node.removeEventListener(events[i], this.handler);
|
|
|
|
}
|
2018-07-19 12:22:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
dispatchNativeEvent: function (event)
|
|
|
|
{
|
|
|
|
this.emit(event.type, event);
|
|
|
|
},
|
|
|
|
|
2018-07-18 23:22:38 +00:00
|
|
|
setElement: function (element)
|
2018-07-18 16:23:04 +00:00
|
|
|
{
|
|
|
|
var target;
|
|
|
|
|
|
|
|
if (typeof element === 'string')
|
|
|
|
{
|
|
|
|
target = document.getElementById(element);
|
|
|
|
}
|
|
|
|
else if (typeof element === 'object' && element.nodeType === 1)
|
|
|
|
{
|
|
|
|
target = element;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!target)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.node = target;
|
|
|
|
|
|
|
|
target.style.zIndex = '0';
|
2018-07-18 23:42:28 +00:00
|
|
|
target.style.display = 'inline';
|
2018-07-18 16:23:04 +00:00
|
|
|
target.style.position = 'absolute';
|
|
|
|
|
2018-07-19 12:22:13 +00:00
|
|
|
// Node handler
|
|
|
|
|
2018-07-19 15:22:58 +00:00
|
|
|
target.phaser = this;
|
2018-07-19 12:22:13 +00:00
|
|
|
|
2018-07-18 16:23:04 +00:00
|
|
|
if (this.parent)
|
|
|
|
{
|
|
|
|
this.parent.appendChild(target);
|
|
|
|
}
|
2018-07-18 23:22:38 +00:00
|
|
|
|
|
|
|
var nodeBounds = target.getBoundingClientRect();
|
|
|
|
|
|
|
|
this.setSize(nodeBounds.width || 0, nodeBounds.height || 0);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-07-18 23:42:28 +00:00
|
|
|
createFromCache: function (key, elementType)
|
|
|
|
{
|
2018-07-19 12:22:13 +00:00
|
|
|
return this.createFromHTML(this.cache.get(key), elementType);
|
2018-07-18 23:42:28 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
createFromHTML: function (html, elementType)
|
|
|
|
{
|
|
|
|
if (elementType === undefined) { elementType = 'div'; }
|
|
|
|
|
|
|
|
var element = document.createElement(elementType);
|
|
|
|
|
2018-07-19 15:22:58 +00:00
|
|
|
this.node = element;
|
|
|
|
|
|
|
|
element.style.zIndex = '0';
|
|
|
|
element.style.display = 'inline';
|
|
|
|
element.style.position = 'absolute';
|
|
|
|
|
|
|
|
// Node handler
|
|
|
|
|
|
|
|
element.phaser = this;
|
|
|
|
|
|
|
|
if (this.parent)
|
|
|
|
{
|
|
|
|
this.parent.appendChild(element);
|
|
|
|
}
|
|
|
|
|
2018-07-18 23:42:28 +00:00
|
|
|
element.innerHTML = html;
|
|
|
|
|
2018-07-19 15:22:58 +00:00
|
|
|
var nodeBounds = element.getBoundingClientRect();
|
|
|
|
|
|
|
|
this.setSize(nodeBounds.width || 0, nodeBounds.height || 0);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
getChildByProperty: function (property, value)
|
|
|
|
{
|
|
|
|
if (this.node)
|
|
|
|
{
|
|
|
|
var children = this.node.querySelectorAll('*');
|
|
|
|
|
|
|
|
for (var i = 0; i < children.length; i++)
|
|
|
|
{
|
|
|
|
if (children[i][property] === value)
|
|
|
|
{
|
|
|
|
return children[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
|
|
|
|
getChildByID: function (id)
|
|
|
|
{
|
|
|
|
return this.getChildByProperty('id', id);
|
|
|
|
},
|
|
|
|
|
|
|
|
getChildByName: function (name)
|
|
|
|
{
|
|
|
|
return this.getChildByProperty('name', name);
|
2018-07-18 23:42:28 +00:00
|
|
|
},
|
|
|
|
|
2018-07-18 23:22:38 +00:00
|
|
|
setText: function (text)
|
|
|
|
{
|
|
|
|
if (this.node)
|
|
|
|
{
|
|
|
|
this.node.innerText = text;
|
2018-08-08 14:01:29 +00:00
|
|
|
|
|
|
|
var nodeBounds = this.node.getBoundingClientRect();
|
|
|
|
|
|
|
|
this.setSize(nodeBounds.width, nodeBounds.height);
|
2018-07-18 23:22:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setHTML: function (html)
|
|
|
|
{
|
|
|
|
if (this.node)
|
|
|
|
{
|
|
|
|
this.node.innerHTML = html;
|
2018-08-08 14:01:29 +00:00
|
|
|
|
|
|
|
var nodeBounds = this.node.getBoundingClientRect();
|
|
|
|
|
|
|
|
this.setSize(nodeBounds.width, nodeBounds.height);
|
2018-07-18 23:22:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-07-19 15:22:58 +00:00
|
|
|
/**
|
|
|
|
* Compares the renderMask with the renderFlags to see if this Game Object will render or not.
|
|
|
|
*
|
|
|
|
* DOMElements always return `true` as they need to still set values during the render pass, even if not visible.
|
|
|
|
*
|
|
|
|
* @method Phaser.GameObjects.DOMElement#willRender
|
|
|
|
* @since 3.12.0
|
|
|
|
*
|
|
|
|
* @return {boolean} True if the Game Object should be rendered, otherwise false.
|
|
|
|
*/
|
|
|
|
willRender: function ()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
|
2018-07-18 23:22:38 +00:00
|
|
|
destroy: function ()
|
|
|
|
{
|
2018-08-08 14:01:29 +00:00
|
|
|
RemoveFromDOM(this.node);
|
2018-07-18 16:23:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
module.exports = DOMElement;
|