303 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			303 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 }),
 | 
						|
                    })
 | 
						|
                }
 | 
						|
            },
 | 
						|
        })
 | 
						|
    }
 | 
						|
}
 |