155 lines
4.2 KiB
JavaScript
155 lines
4.2 KiB
JavaScript
import Theme from './theme.js'
|
|
import AbstractPopup from './abstractpopup.js'
|
|
|
|
/**
|
|
* Class that represents a PixiJS Tooltip.
|
|
*
|
|
* @example
|
|
* // Create the app
|
|
* const app = new PIXIApp({
|
|
* view: canvas,
|
|
* width: 900,
|
|
* height: 250
|
|
* }).setup().run()
|
|
*
|
|
* // Add an DisplayObject to the app
|
|
* const circle = new PIXI.Graphics()
|
|
* circle.beginFill(0x5251a3)
|
|
* circle.drawCircle(50, 50, 40)
|
|
* app.scene.addChild(circle)
|
|
*
|
|
* const tooltip = new Tooltip({
|
|
* object: circle,
|
|
* container: app.scene,
|
|
* content: 'Das Gesetz ist der Freund des Schwachen.'
|
|
* })
|
|
*
|
|
* @class
|
|
* @extends AbstractPopup
|
|
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/tooltip.html|DocTest}
|
|
*/
|
|
export default class Tooltip extends AbstractPopup {
|
|
/**
|
|
* Creates an instance of a Tooltip.
|
|
*
|
|
* @constructor
|
|
* @param {object} [opts] - An options object to specify to style and behaviour of the tooltip.
|
|
* @param {number} [opts.minWidth=0] - The minimum width of the tooltip.
|
|
* @param {number} [opts.minHeight=0] - The minimum height of the tooltip.
|
|
* @param {number} [opts.padding=Theme.padding / 2] - The inner spacing of the tooltip.
|
|
* @param {PIXI.DisplayObject} opts.object - The object, where the tooltip should be displayed.
|
|
* @param {PIXI.DisplayObject} [opts.container=object] - The container where the tooltip should be attached to.
|
|
* @param {number} [opts.offsetLeft=8] - The horizontal shift of the tooltip.
|
|
* @param {number} [opts.offsetTop=-8] - The vertical shift of the tooltip.
|
|
* @param {number} [opts.delay=0] - A delay, after which the tooltip should be opened.
|
|
*/
|
|
constructor(opts = {}) {
|
|
const theme = Theme.fromString(opts.theme)
|
|
|
|
opts = Object.assign(
|
|
{},
|
|
{
|
|
minWidth: 0,
|
|
minHeight: 0,
|
|
padding: theme.padding / 2,
|
|
object: null,
|
|
container: null,
|
|
offsetLeft: 8,
|
|
offsetTop: -8,
|
|
delay: 0,
|
|
},
|
|
opts
|
|
)
|
|
|
|
opts.container = opts.container || opts.object
|
|
|
|
super(opts)
|
|
|
|
// setup
|
|
//-----------------
|
|
this.setup()
|
|
|
|
// layout
|
|
//-----------------
|
|
this.layout()
|
|
}
|
|
|
|
/**
|
|
* Creates children and instantiates everything.
|
|
*
|
|
* @private
|
|
* @return {Tooltip} A reference to the tooltip for chaining.
|
|
*/
|
|
setup() {
|
|
super.setup()
|
|
|
|
// bind events this
|
|
//-----------------
|
|
this.interactive = true
|
|
|
|
let mouseoverTooltip = false
|
|
|
|
this.on('mouseover', (e) => {
|
|
mouseoverTooltip = true
|
|
})
|
|
|
|
this.on('mouseout', (e) => {
|
|
mouseoverTooltip = false
|
|
if (!mouseoverObject) {
|
|
this.hide(() => {
|
|
this.opts.container.removeChild(this)
|
|
})
|
|
}
|
|
})
|
|
|
|
// bind events object
|
|
//-----------------
|
|
const object = this.opts.object
|
|
object.interactive = true
|
|
|
|
let mouseoverObject = false
|
|
|
|
object.on('mouseover', (e) => {
|
|
this.timeout = window.setTimeout(() => {
|
|
mouseoverObject = true
|
|
this.visible = true
|
|
this.opts.container.addChild(this)
|
|
this.setPosition(e)
|
|
}, this.opts.delay * 1000)
|
|
})
|
|
|
|
object.on('mousemove', (e) => {
|
|
if (mouseoverObject) {
|
|
this.setPosition(e)
|
|
}
|
|
})
|
|
|
|
object.on('mouseout', (e) => {
|
|
mouseoverObject = false
|
|
window.clearTimeout(this.timeout)
|
|
if (!mouseoverTooltip) {
|
|
this.hide(() => {
|
|
this.opts.container.removeChild(this)
|
|
})
|
|
}
|
|
})
|
|
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Calculates and sets the position of the tooltip.
|
|
*
|
|
* @private
|
|
* @return {Tooltip} A reference to the tooltip for chaining.
|
|
*/
|
|
setPosition(e) {
|
|
const position = e.data.getLocalPosition(this.opts.container)
|
|
|
|
this.x = position.x + this.opts.offsetLeft
|
|
this.y = position.y + this.opts.offsetTop - this.height
|
|
|
|
return this
|
|
}
|
|
}
|