iwmlib/lib/pixi/popover.js

200 lines
5.4 KiB
JavaScript
Raw Permalink Normal View History

2019-03-21 09:57:27 +01:00
/**
2019-07-18 12:26:39 +02:00
*
2019-03-21 09:57:27 +01:00
*/
export default class Popover extends PIXI.Graphics {
2019-07-18 12:26:39 +02:00
constructor({
title = null,
text = null,
x = 0,
y = 0,
placement = 'top',
width = 250,
titleStyle = {},
2022-10-04 10:51:35 +02:00
textStyle = { fontSize: '1.6em' },
2019-07-18 12:26:39 +02:00
} = {}) {
2019-03-21 09:57:27 +01:00
super()
2019-07-18 12:26:39 +02:00
this.opts = {
title,
text,
x,
y,
placement,
width,
titleStyle,
2022-10-04 10:51:35 +02:00
textStyle,
2019-07-18 12:26:39 +02:00
}
2019-03-21 09:57:27 +01:00
this.padding = 12
let style = {
fontFamily: 'Arial',
fontSize: '2em',
stroke: '#f6f6f6',
strokeThickness: 3,
wordWrap: true,
2022-10-04 10:51:35 +02:00
wordWrapWidth: width - this.padding * 2,
2019-03-21 09:57:27 +01:00
}
2019-07-30 16:56:29 +02:00
this.titleTextStyle = new PIXI.TextStyle(Object.assign({}, style, titleStyle))
this.textTextStyle = new PIXI.TextStyle(Object.assign({}, style, textStyle))
2019-07-18 12:26:39 +02:00
2019-03-21 09:57:27 +01:00
if (title || text) {
this.setup()
this.draw()
this.positioning()
}
}
setup() {
this.removeChildren()
if (this.opts.title) {
this.titleText = new PIXI.Text(this.opts.title, this.titleTextStyle)
this.titleText.position.set(this.padding, this.padding)
this.addChild(this.titleText)
}
this.titleY = this.titleText ? this.titleText.y : 0
this.titleHeight = this.titleText ? this.titleText.height : 0
if (this.opts.text) {
this.textText = new PIXI.Text(this.opts.text, this.textTextStyle)
2019-07-30 16:56:29 +02:00
this.textText.position.set(this.padding, this.titleY + this.titleHeight + this.padding)
2019-03-21 09:57:27 +01:00
this.addChild(this.textText)
}
this.textY = this.textText ? this.textText.y : 0
this.textHeight = this.textText ? this.textText.height : 0
}
close() {
this.parent.removeChild(this)
}
draw() {
this.clear()
this.beginFill(0xffffff, 1)
2019-07-18 12:26:39 +02:00
this.lineStyle(1, 0x282828, 0.5)
2019-03-21 09:57:27 +01:00
// Draw rounded rectangle
const height = this.height + this.padding
this.drawRoundedRect(0, 0, this.opts.width, height, 8)
// Draw anchor
this.drawAnchor(this.opts.placement)
// Draw title background
if (this.opts.title) {
this.lineStyle(0)
this.beginFill(0xf7f7f7, 1)
let x = 1
2019-07-18 12:26:39 +02:00
let y = this.titleText.x + this.titleText.height + this.padding / 2
2019-03-21 09:57:27 +01:00
this.moveTo(x, y)
y = 9
this.lineTo(x, y)
this.quadraticCurveTo(x, y - 8, x + 8, y - 8)
x += this.opts.width - 7
y -= 8
this.lineTo(x, y)
this.quadraticCurveTo(x + 5, y, x + 5, y + 8)
x += 5
2019-07-18 12:26:39 +02:00
y += this.titleText.x + this.titleText.height + this.padding / 2
2019-03-21 09:57:27 +01:00
this.lineTo(x, y)
if (this.opts.text) {
x = 1
this.lineTo(x, y)
} else {
this.quadraticCurveTo(x, y, x - 5, y + 4)
x = 6
y += 4
this.lineTo(x, y)
this.quadraticCurveTo(x, y, x - 5, y - 4)
}
}
this.endFill()
}
drawAnchor(placement) {
let x = 0
let y = 0
switch (placement) {
case 'bottom':
if (this.opts.title) {
this.beginFill(0xf7f7f7, 1)
}
2019-07-18 12:26:39 +02:00
x = this.width / 2 - 10
2019-03-21 09:57:27 +01:00
y = 1
this.moveTo(x, y)
x += 10
y -= 10
this.lineTo(x, y)
x += 10
y += 10
this.lineTo(x, y)
break
case 'right':
x = 1
2019-07-18 12:26:39 +02:00
y = this.height / 2 - 10
2019-03-21 09:57:27 +01:00
if (this.titleY + this.titleHeight > y) {
this.beginFill(0xf7f7f7, 1)
}
this.moveTo(x, y)
x -= 10
y += 10
this.lineTo(x, y)
x += 10
y += 10
this.lineTo(x, y)
break
case 'left':
x = this.width - 2
2019-07-18 12:26:39 +02:00
y = this.height / 2 - 10
2019-03-21 09:57:27 +01:00
if (this.titleY + this.titleHeight > y) {
this.beginFill(0xf7f7f7, 1)
}
this.moveTo(x, y)
x += 10
y += 10
this.lineTo(x, y)
x -= 10
y += 10
this.lineTo(x, y)
break
default:
2019-07-18 12:26:39 +02:00
x = this.width / 2 - 10
2019-03-21 09:57:27 +01:00
y = this.height - 2
this.moveTo(x, y)
x += 10
y += 10
this.lineTo(x, y)
x += 10
y -= 10
this.lineTo(x, y)
break
}
}
positioning() {
const x = this.opts.x
const y = this.opts.y
switch (this.opts.placement) {
case 'bottom':
2019-07-18 12:26:39 +02:00
this.position.set(x - this.width / 2, y + 10)
2019-03-21 09:57:27 +01:00
break
case 'right':
2019-07-18 12:26:39 +02:00
this.position.set(x, y - this.height / 2)
2019-03-21 09:57:27 +01:00
break
case 'left':
2019-07-18 12:26:39 +02:00
this.position.set(x - this.width, y - this.height / 2)
2019-03-21 09:57:27 +01:00
break
default:
2019-07-18 12:26:39 +02:00
this.position.set(x - this.width / 2, y - this.height)
2019-03-21 09:57:27 +01:00
break
}
}
}