iwmlib/lib/pixi/modal.js

208 lines
5.5 KiB
JavaScript
Raw Normal View History

2019-03-21 09:57:27 +01:00
import Theme from './theme.js'
2019-07-18 12:26:39 +02:00
import { InteractivePopup } from './popup.js'
2019-03-21 09:57:27 +01:00
/**
* Class that represents a PixiJS Modal.
2019-07-18 12:26:39 +02:00
*
2019-03-21 09:57:27 +01:00
* @example
* // Create the button and the modal when clicked
* const button = new Button({
* label: 'Show Modal',
* action: e => {
* const modal = new Modal({
* app: app,
* header: 'This is the header',
* content: 'This is the text.'
* })
* app.scene.addChild(modal)
* }
* })
*
* // Add the button to a DisplayObject
* app.scene.addChild(button)
*
* @class
* @extends PIXI.Container
* @extends InteractivePopup
* @see {@link http://pixijs.download/dev/docs/PIXI.Container.html|PIXI.Container}
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/modal.html|DocTest}
*/
export default class Modal extends PIXI.Container {
/**
* Creates an instance of a Modal.
2019-07-18 12:26:39 +02:00
*
2019-03-21 09:57:27 +01:00
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the modal.
* @param {number} [opts.id=auto generated] - The id of the modal.
* @param {PIXIApp} [opts.app=window.app] - The app where the modal belongs to.
* @param {number} [opts.backgroundFill=Theme.background] - The color of the background.
* @param {number} [opts.backgroundFillAlpha=0.6] - The opacity of the background.
* @param {boolean} [opts.closeOnBackground=true] - Should the modal be closed when the user clicks the
* background?
* @param {boolean} [opts.visible=true] - Is the modal initially visible (property visible)?
*/
constructor(opts = {}) {
super()
2019-07-18 12:26:39 +02:00
2019-03-21 09:57:27 +01:00
const theme = Theme.fromString(opts.theme)
this.theme = theme
2019-07-18 12:26:39 +02:00
this.opts = Object.assign(
{},
{
id: PIXI.utils.uid(),
app: window.app,
backgroundFill: theme.background,
backgroundFillAlpha: 0.6,
closeOnBackground: true,
2022-10-04 10:51:35 +02:00
visible: true,
2019-07-18 12:26:39 +02:00
},
opts
)
2019-03-21 09:57:27 +01:00
this.id = this.opts.id
this.background = null
this.popup = null
this.alpha = 0
this.visible = this.opts.visible
// setup
//-----------------
this.setup()
// layout
//-----------------
this.layout()
}
2019-07-18 12:26:39 +02:00
2019-03-21 09:57:27 +01:00
/**
* Creates children and instantiates everything.
2019-07-18 12:26:39 +02:00
*
2019-03-21 09:57:27 +01:00
* @private
* @return {Modal} A reference to the modal for chaining.
*/
setup() {
// interaction
//-----------------
this.interactive = true
2022-10-04 10:51:35 +02:00
this.on('added', (e) => {
2019-03-21 09:57:27 +01:00
if (this.visible) {
this.show()
}
})
// background
//-----------------
let background = new PIXI.Graphics()
this.background = background
this.addChild(this.background)
if (this.opts.closeOnBackground) {
background.interactive = true
2022-10-04 10:51:35 +02:00
background.on('pointerup', (e) => {
2019-03-21 09:57:27 +01:00
this.hide()
})
}
// popup
//-----------------
const popupOpts = Object.assign({}, this.opts, {
visible: true,
onHidden: () => {
this.hide()
2022-10-04 10:51:35 +02:00
},
2019-03-21 09:57:27 +01:00
})
let popup = new InteractivePopup(popupOpts)
this.popup = popup
this.addChild(popup)
popup.show()
return this
}
2019-07-18 12:26:39 +02:00
2019-03-21 09:57:27 +01:00
/**
* Should be called to refresh the layout of the modal. Can be used after resizing.
2019-07-18 12:26:39 +02:00
*
2019-03-21 09:57:27 +01:00
* @return {Modal} A reference to the modal for chaining.
*/
layout() {
const width = this.opts.app.size.width
const height = this.opts.app.size.height
// background
//-----------------
this.background.clear()
2019-07-30 16:56:29 +02:00
this.background.beginFill(this.opts.backgroundFill, this.opts.backgroundFillAlpha)
2019-03-21 09:57:27 +01:00
this.background.drawRect(0, 0, width, height)
this.background.endFill()
// position
this.popup.x = width / 2 - this.popup.width / 2
this.popup.y = height / 2 - this.popup.height / 2
return this
}
2019-07-18 12:26:39 +02:00
2019-03-21 09:57:27 +01:00
/**
* Shows the modal (sets his alpha values to 1).
2019-07-18 12:26:39 +02:00
*
2019-03-21 09:57:27 +01:00
* @return {Modal} A reference to the modal for chaining.
*/
show() {
2019-07-18 12:26:39 +02:00
TweenLite.to(this, this.theme.fast, {
alpha: 1,
2022-10-04 10:51:35 +02:00
onStart: () => (this.visible = true),
2019-07-18 12:26:39 +02:00
})
2019-03-21 09:57:27 +01:00
return this
}
2019-07-18 12:26:39 +02:00
2019-03-21 09:57:27 +01:00
/**
* Hides the modal (sets his alpha values to 0).
2019-07-18 12:26:39 +02:00
*
2019-03-21 09:57:27 +01:00
* @return {Modal} A reference to the modal for chaining.
*/
hide() {
2019-07-18 12:26:39 +02:00
TweenLite.to(this, this.theme.fast, {
alpha: 0,
2022-10-04 10:51:35 +02:00
onComplete: () => (this.visible = false),
2019-07-18 12:26:39 +02:00
})
2019-03-21 09:57:27 +01:00
return this
}
2019-07-18 12:26:39 +02:00
2019-03-21 09:57:27 +01:00
/**
* Sets or gets the header. The getter always returns a PIXI.Text object. The setter can receive
* a string or a PIXI.Text object.
2019-07-18 12:26:39 +02:00
*
2019-03-21 09:57:27 +01:00
* @member {string|PIXI.Text}
*/
get header() {
return this.popup.header
}
set header(value) {
this.opts.header = value
this.background.destroy()
this.popup.destroy()
this.setup().layout()
}
2019-07-18 12:26:39 +02:00
2019-03-21 09:57:27 +01:00
/**
* Sets or gets the content. The getter always returns an PIXI.DisplayObject. The setter can receive
* a string or a PIXI.DisplayObject.
2019-07-18 12:26:39 +02:00
*
2019-03-21 09:57:27 +01:00
* @member {string|PIXI.DisplayObject}
*/
get content() {
return this.popup.content
}
set content(value) {
this.opts.content = value
this.background.destroy()
this.popup.destroy()
this.setup().layout()
}
}