304 lines
9.6 KiB
JavaScript
304 lines
9.6 KiB
JavaScript
|
import Theme from './theme.js'
|
||
|
|
||
|
/**
|
||
|
* Class that represents a PixiJS Progress.
|
||
|
*
|
||
|
* @example
|
||
|
* // Create the progress
|
||
|
* const progress = new Progress({
|
||
|
* app: app
|
||
|
* })
|
||
|
*
|
||
|
* // Add the progress to a DisplayObject
|
||
|
* app.scene.addChild(progress)
|
||
|
*
|
||
|
* @class
|
||
|
* @extends PIXI.Container
|
||
|
* @see {@link http://pixijs.download/dev/docs/PIXI.Container.html|PIXI.Container}
|
||
|
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/progress.html|DocTest}
|
||
|
*/
|
||
|
export default class Progress extends PIXI.Container {
|
||
|
|
||
|
/**
|
||
|
* Creates an instance of a Progress.
|
||
|
*
|
||
|
* @constructor
|
||
|
* @param {object} [opts] - An options object to specify to style and behaviour of the progress.
|
||
|
* @param {number} [opts.id=auto generated] - The id of the progress.
|
||
|
* @param {PIXIApp} [opts.app=window.app] - The app where the progress belongs to.
|
||
|
* @param {number} [opts.width] - The width of the progress bar. When not set, the width is the size of the app
|
||
|
* minus 2 * opts.margin.
|
||
|
* @param {number} [opts.height=2] - The height of the progress bar.
|
||
|
* @param {string|Theme} [opts.theme=dark] - The theme to use for this progress. Possible values are dark, light, red
|
||
|
* or a Theme object.
|
||
|
* @param {number} [opts.margin=100] - The outer spacing to the edges of the app.
|
||
|
* @param {number} [opts.padding=0] - The inner spacing (distance from icon and/or label) to the border.
|
||
|
* @param {number} [opts.fill=Theme.fill] - The color of the progress background as a hex value.
|
||
|
* @param {number} [opts.fillAlpha=Theme.fillAlpha] - The alpha value of the background.
|
||
|
* @param {number} [opts.fillActive=Theme.primaryColor] - The color of the progress background when activated.
|
||
|
* @param {number} [opts.fillActiveAlpha=Theme.fillActiveAlpha] - The alpha value of the background when activated.
|
||
|
* @param {number} [opts.stroke=Theme.stroke] - The color of the border as a hex value.
|
||
|
* @param {number} [opts.strokeWidth=0] - The width of the border in pixel.
|
||
|
* @param {number} [opts.strokeAlpha=Theme.strokeAlpha] - The alpha value of the border.
|
||
|
* @param {number} [opts.strokeActive=Theme.strokeActive] - The color of the border when activated.
|
||
|
* @param {number} [opts.strokeActiveWidth=0] - The width of the border in pixel when activated.
|
||
|
* @param {number} [opts.strokeActiveAlpha=Theme.strokeActiveAlpha] - The alpha value of the border when activated.
|
||
|
* @param {boolean} [opts.background=false] - The alpha value of the border when activated.
|
||
|
* @param {number} [opts.backgroundFill=Theme.background] - A textstyle object for the styling of the label. See PIXI.TextStyle
|
||
|
* for possible options.
|
||
|
* @param {number} [opts.backgroundFillAlpha=1] - A textstyle object for the styling of the label when the
|
||
|
* progress is activated. See PIXI.TextStyle for possible options.
|
||
|
* @param {number} [opts.radius=Theme.radius] - The radius of the four corners of the progress (which is a rounded rectangle).
|
||
|
* @param {boolean} [opts.destroyOnComplete=true] - Should the progress bar destroy itself after reaching 100 %?
|
||
|
* @param {boolean} [opts.visible=true] - Is the progress initially visible (property visible)?
|
||
|
*/
|
||
|
constructor(opts = {}) {
|
||
|
|
||
|
super()
|
||
|
|
||
|
const theme = Theme.fromString(opts.theme)
|
||
|
this.theme = theme
|
||
|
|
||
|
this.opts = Object.assign({}, {
|
||
|
id: PIXI.utils.uid(),
|
||
|
app: window.app,
|
||
|
width: null,
|
||
|
height: 2,
|
||
|
margin: 100,
|
||
|
padding: 0,
|
||
|
fill: theme.fill,
|
||
|
fillAlpha: theme.fillAlpha,
|
||
|
fillActive: theme.primaryColor,
|
||
|
fillActiveAlpha: theme.fillActiveAlpha,
|
||
|
stroke: theme.stroke,
|
||
|
strokeWidth: 0,
|
||
|
strokeAlpha: theme.strokeAlpha,
|
||
|
strokeActive: theme.strokeActive,
|
||
|
strokeActiveWidth: 0,
|
||
|
strokeActiveAlpha: theme.strokeActiveAlpha,
|
||
|
background: false,
|
||
|
backgroundFill: theme.background,
|
||
|
backgroundFillAlpha: 1,
|
||
|
radius: theme.radius,
|
||
|
destroyOnComplete: true,
|
||
|
visible: true
|
||
|
}, opts)
|
||
|
|
||
|
this.id = this.opts.id
|
||
|
|
||
|
this.background = null
|
||
|
this.bar = null
|
||
|
this.barActive = null
|
||
|
|
||
|
this.alpha = 0
|
||
|
|
||
|
this.visible = this.opts.visible
|
||
|
|
||
|
this._progress = 0
|
||
|
|
||
|
// setup
|
||
|
//-----------------
|
||
|
this.setup()
|
||
|
|
||
|
// layout
|
||
|
//-----------------
|
||
|
this.layout()
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Creates children and instantiates everything.
|
||
|
*
|
||
|
* @private
|
||
|
* @return {Progress} A reference to the progress for chaining.
|
||
|
*/
|
||
|
setup() {
|
||
|
|
||
|
// interaction
|
||
|
//-----------------
|
||
|
this.on('added', e => {
|
||
|
this.show()
|
||
|
})
|
||
|
|
||
|
// background
|
||
|
//-----------------
|
||
|
if (this.opts.background) {
|
||
|
const background = new PIXI.Graphics()
|
||
|
this.background = background
|
||
|
this.addChild(background)
|
||
|
}
|
||
|
|
||
|
// bar
|
||
|
//-----------------
|
||
|
const bar = new PIXI.Graphics()
|
||
|
this.bar = bar
|
||
|
this.addChild(bar)
|
||
|
|
||
|
const barActive = new PIXI.Graphics()
|
||
|
this.barActive = barActive
|
||
|
this.bar.addChild(barActive)
|
||
|
|
||
|
return this
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Should be called to refresh the layout of the progress. Can be used after resizing.
|
||
|
*
|
||
|
* @return {Progress} A reference to the progress for chaining.
|
||
|
*/
|
||
|
layout() {
|
||
|
|
||
|
const width = this.opts.app.size.width
|
||
|
const height = this.opts.app.size.height
|
||
|
|
||
|
// background
|
||
|
//-----------------
|
||
|
if (this.opts.background) {
|
||
|
this.background.clear()
|
||
|
this.background.beginFill(this.opts.backgroundFill, this.opts.backgroundFillAlpha)
|
||
|
this.background.drawRect(0, 0, width, height)
|
||
|
this.background.endFill()
|
||
|
}
|
||
|
|
||
|
this.draw()
|
||
|
|
||
|
return this
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Draws the canvas.
|
||
|
*
|
||
|
* @private
|
||
|
* @return {Progress} A reference to the progress for chaining.
|
||
|
*/
|
||
|
draw() {
|
||
|
|
||
|
this.bar.clear()
|
||
|
this.barActive.clear()
|
||
|
|
||
|
this.drawBar()
|
||
|
this.drawBarActive()
|
||
|
|
||
|
return this
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Draws the bar.
|
||
|
*
|
||
|
* @private
|
||
|
* @return {Progress} A reference to the progress for chaining.
|
||
|
*/
|
||
|
drawBar() {
|
||
|
|
||
|
const width = this.opts.app.size.width
|
||
|
const height = this.opts.app.size.height
|
||
|
|
||
|
this.radius = this.opts.radius
|
||
|
if ((this.radius * 2) > this.opts.height) {
|
||
|
this.radius = this.opts.height / 2
|
||
|
}
|
||
|
|
||
|
const wantedWidth = this.opts.width || (width - (2 * this.opts.margin))
|
||
|
const wantedHeight = this.opts.height
|
||
|
|
||
|
this.bar.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha)
|
||
|
this.bar.beginFill(this.opts.fill, this.opts.fillAlpha)
|
||
|
if (this.radius > 1) {
|
||
|
this.bar.drawRoundedRect(0, 0, wantedWidth, wantedHeight, this.radius)
|
||
|
} else {
|
||
|
this.bar.drawRect(0, 0, wantedWidth, wantedHeight)
|
||
|
}
|
||
|
this.bar.endFill()
|
||
|
|
||
|
this.bar.x = width / 2 - this.bar.width / 2
|
||
|
this.bar.y = height / 2 - this.bar.height / 2
|
||
|
|
||
|
return this
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Draws the active bar.
|
||
|
*
|
||
|
* @private
|
||
|
* @return {Progress} A reference to the progress for chaining.
|
||
|
*/
|
||
|
drawBarActive() {
|
||
|
|
||
|
const wantedWidth = this.bar.width - (2 * this.opts.padding)
|
||
|
const wantedHeight = this.bar.height - (2 * this.opts.padding)
|
||
|
|
||
|
const barActiveWidth = wantedWidth * this._progress / 100
|
||
|
|
||
|
this.barActive.lineStyle(this.opts.strokeActiveWidth, this.opts.strokeActive, this.opts.strokeActiveAlpha)
|
||
|
this.barActive.beginFill(this.opts.fillActive, this.opts.fillActiveAlpha)
|
||
|
if (barActiveWidth > 0) {
|
||
|
if (this.radius > 1) {
|
||
|
this.barActive.drawRoundedRect(0, 0, barActiveWidth, wantedHeight, this.radius)
|
||
|
} else {
|
||
|
this.barActive.drawRect(0, 0, barActiveWidth, wantedHeight)
|
||
|
}
|
||
|
}
|
||
|
this.barActive.endFill()
|
||
|
|
||
|
this.barActive.x = this.opts.padding
|
||
|
this.barActive.y = this.opts.padding
|
||
|
|
||
|
return this
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Shows the progress (sets his alpha values to 1).
|
||
|
*
|
||
|
* @return {Progress} A reference to the progress for chaining.
|
||
|
*/
|
||
|
show() {
|
||
|
TweenLite.to(this, this.theme.fast, {alpha: 1})
|
||
|
|
||
|
return this
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Hides the progress (sets his alpha values to 1).
|
||
|
*
|
||
|
* @return {Progress} A reference to the progress for chaining.
|
||
|
*/
|
||
|
hide() {
|
||
|
TweenLite.to(this, this.theme.fast, {alpha: 0, onComplete: () => this.visible = false})
|
||
|
|
||
|
return this
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets or sets the progress. Has to be a number between 0 and 100.
|
||
|
*
|
||
|
* @member {number}
|
||
|
*/
|
||
|
get progress() {
|
||
|
return this._progress
|
||
|
}
|
||
|
set progress(value) {
|
||
|
|
||
|
value = Math.round(value)
|
||
|
|
||
|
if (value < 0) {
|
||
|
value = 0
|
||
|
}
|
||
|
|
||
|
if (value > 100) {
|
||
|
value = 100
|
||
|
}
|
||
|
|
||
|
TweenLite.to(this, this.theme.normal, {
|
||
|
_progress: value,
|
||
|
onUpdate: () => this.draw(),
|
||
|
onComplete: () => {
|
||
|
if (value === 100 && this.opts.destroyOnComplete) {
|
||
|
TweenLite.to(this, this.theme.fast, {
|
||
|
alpha: 0,
|
||
|
onComplete: () => this.destroy({children: true})
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|