Implemented stacked button groups.
This commit is contained in:
@@ -245,7 +245,7 @@ const buttonGroup14 = new ButtonGroup({
|
||||
{label: 'Stacked button 7', action: event => console.log('clicked 7')},
|
||||
{label: 'Stacked button 8', action: event => console.log('clicked 8')}
|
||||
],
|
||||
stacked: true,
|
||||
stackPadding: 6,
|
||||
maxWidth: 620,
|
||||
app
|
||||
})
|
||||
@@ -263,18 +263,30 @@ const buttonGroup15 = new ButtonGroup({
|
||||
{icon: 'battery_charging_full', type: 'checkbox', iconColorActive: 0x9c71b7}
|
||||
],
|
||||
orientation: 'vertical',
|
||||
margin: 0,
|
||||
stacked: true,
|
||||
margin: 1,
|
||||
maxHeight: 200,
|
||||
app
|
||||
})
|
||||
|
||||
const buttons16 = []
|
||||
for (let i = 1; i < 51; i++) {
|
||||
buttons16.push({label: `Button ${i}`, stroke: Math.floor(Math.random() * 16777215), strokeWidth: 3, radius: 16})
|
||||
}
|
||||
const buttonGroup16 = new ButtonGroup({
|
||||
x: 90,
|
||||
y: 1040,
|
||||
buttons: buttons16,
|
||||
stackPadding: 3,
|
||||
maxWidth: 700,
|
||||
app
|
||||
})
|
||||
|
||||
app.scene.addChild(buttonGroup1, buttonGroup2, buttonGroup3)
|
||||
app.scene.addChild(buttonGroup4)
|
||||
app.scene.addChild(buttonGroup5, buttonGroup6)
|
||||
app.scene.addChild(buttonGroup7, buttonGroup8)
|
||||
app.scene.addChild(buttonGroup9, buttonGroup10, buttonGroup11, buttonGroup12, buttonGroup13)
|
||||
app.scene.addChild(buttonGroup14, buttonGroup15)
|
||||
app.scene.addChild(buttonGroup14, buttonGroup15, buttonGroup16)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+103
-33
@@ -42,10 +42,10 @@ export default class ButtonGroup extends PIXI.Container {
|
||||
* or a Theme object.
|
||||
* @param {number} [opts.minWidth=44] - Button: The minimum width of one button.
|
||||
* @param {number} [opts.minHeight=44] - Button: The minimum height of one button.
|
||||
* @param {number} [opts.maxWidth] - The maximum width of the button group. Only used if stacked is true and the orientation is horizontal.
|
||||
* @param {number} [opts.maxHeight] - The maximum height of the button group. Only used if stacked is true and the orientation is vertical.
|
||||
* @param {boolean} [opts.stacked=false] - If set to true, the buttons of the button group gets stacked if they are broader or higher than the maximum permitted width or height, depending on orientation.
|
||||
* @param {PIXI.Application} [opts.app] - The PixiJS Application. Must be set if you want to use the mousewheel to scroll your button group.
|
||||
* @param {number} [opts.maxWidth] - The maximum width of the button group. If the buttons are wider than the maximum width, the buttons get stacked. Note: The buttons can only be stacked if margin is not zero.
|
||||
* @param {number} [opts.maxHeight] - The maximum height of the button group. If the buttons are higher than the maximum height, the buttons get stacked. Note: The buttons can only be stacked if margin is not zero.
|
||||
* @param {number} [opts.stackPadding=10] - The padding for stacked buttons.
|
||||
* @param {PIXI.Application} [opts.app] - The PixiJS Application. Must be set if you want to use the mousewheel to scroll your button group. Only used when the buttons are stacked (with maxWidth or maxHeight).
|
||||
* @param {number} [opts.padding=Theme.padding] - Button: The inner spacing (distance from icon and/or label) the the border.
|
||||
* @param {number} [opts.margin=Theme.margin] - The outer spacing (distance from one button to the previous/next button).
|
||||
* @param {string} [opts.iconPosition=left] - Button: The position of the icon in relation to the label. Can be left or right.
|
||||
@@ -96,7 +96,7 @@ export default class ButtonGroup extends PIXI.Container {
|
||||
minHeight: 44,
|
||||
maxWidth: null,
|
||||
maxHeight: null,
|
||||
stacked: false,
|
||||
stackPadding: 10,
|
||||
app: null,
|
||||
padding: theme.padding,
|
||||
margin: theme.margin,
|
||||
@@ -159,6 +159,7 @@ export default class ButtonGroup extends PIXI.Container {
|
||||
// Buttons
|
||||
//-----------------
|
||||
let position = 0
|
||||
let index = 0
|
||||
|
||||
for (let it of this.opts.buttons) {
|
||||
delete it.x
|
||||
@@ -237,6 +238,9 @@ export default class ButtonGroup extends PIXI.Container {
|
||||
}
|
||||
|
||||
position += (this.opts.orientation === 'horizontal' ? button.width : button.height) + this.opts.margin
|
||||
|
||||
button.__initIndex = index
|
||||
index++
|
||||
}
|
||||
|
||||
if (this.opts.orientation === 'vertical') {
|
||||
@@ -256,7 +260,7 @@ export default class ButtonGroup extends PIXI.Container {
|
||||
|
||||
// interaction
|
||||
//--------------------
|
||||
if (this.opts.stacked) {
|
||||
if (this.opts.margin > 0 && (this.opts.maxWidth || this.opts.maxHeight)) {
|
||||
this.interactive = true
|
||||
this.on('pointerdown', this.onStart.bind(this))
|
||||
this.on('pointermove', this.onMove.bind(this))
|
||||
@@ -288,7 +292,6 @@ export default class ButtonGroup extends PIXI.Container {
|
||||
this.addChildAt(background, 0)
|
||||
|
||||
this.__initWidth = this.container.width
|
||||
this.__deltaWidth = this.container.width - this.opts.maxWidth
|
||||
}
|
||||
|
||||
return this
|
||||
@@ -308,9 +311,9 @@ export default class ButtonGroup extends PIXI.Container {
|
||||
//-----------------
|
||||
this.draw()
|
||||
|
||||
// stacked
|
||||
// stack
|
||||
//-----------------
|
||||
if (this.opts.stacked) {
|
||||
if (this.opts.margin > 0 && (this.opts.maxWidth || this.opts.maxHeight)) {
|
||||
this.stack()
|
||||
}
|
||||
|
||||
@@ -438,9 +441,7 @@ export default class ButtonGroup extends PIXI.Container {
|
||||
this.container.position.y = event.data.global.y + this.__delta.y
|
||||
}
|
||||
|
||||
if (this.opts.stacked) {
|
||||
this.stack()
|
||||
}
|
||||
this.stack()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,9 +516,7 @@ export default class ButtonGroup extends PIXI.Container {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.opts.stacked) {
|
||||
this.stack()
|
||||
}
|
||||
this.stack()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -534,35 +533,106 @@ export default class ButtonGroup extends PIXI.Container {
|
||||
*
|
||||
*/
|
||||
stack() {
|
||||
if (this.opts.maxWidth) {
|
||||
this._stackHorizontal()
|
||||
} else if (this.opts.maxHeight) {
|
||||
this._stackVertical()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
_stackHorizontal() {
|
||||
const sorted = []
|
||||
|
||||
let reverseCounter = this.buttons.length - 1
|
||||
|
||||
this.buttons.forEach((it, index) => {
|
||||
if (it.__originalPosition.x + this.container.x < 0) {
|
||||
const leftCorner = it.__originalPosition.x + this.container.x
|
||||
const rightCorner = it.__originalPosition.x + it.width
|
||||
const paddingLeft = index * this.opts.stackPadding
|
||||
const paddingRight = reverseCounter * this.opts.stackPadding
|
||||
if (leftCorner < paddingLeft) {
|
||||
// left border
|
||||
it.x = -this.container.x
|
||||
} else if (it.__originalPosition.x + it.width > Math.abs(this.container.x) + this.opts.maxWidth) {
|
||||
it.x = -this.container.x + paddingLeft
|
||||
} else if (rightCorner > -this.container.x + this.opts.maxWidth - paddingRight) {
|
||||
// right border
|
||||
it.x = Math.abs(this.container.x) + this.opts.maxWidth - it.width
|
||||
it.x = -this.container.x + this.opts.maxWidth - it.width - paddingRight
|
||||
} else {
|
||||
it.x = it.__originalPosition.x
|
||||
}
|
||||
|
||||
reverseCounter--
|
||||
|
||||
sorted.push(it)
|
||||
})
|
||||
|
||||
this.buttons.sort((a, b) => {
|
||||
const delta = Math.abs(this.container.x) + this.opts.maxWidth / 2
|
||||
const distanceA = Math.abs(a.x - delta)
|
||||
const distanceB = Math.abs(b.x - delta)
|
||||
if (distanceA > distanceB) {
|
||||
return -1
|
||||
} else if (distanceB > distanceA) {
|
||||
return 1
|
||||
const min = Math.min(...sorted.map(it => it.x))
|
||||
const max = Math.max(...sorted.map(it => it.x))
|
||||
const center = (min + max) / 2
|
||||
|
||||
// z-index
|
||||
sorted
|
||||
.sort((a, b) => {
|
||||
const distanceA = Math.abs(a.x - center)
|
||||
const distanceB = Math.abs(b.x - center)
|
||||
if (distanceA < distanceB) {
|
||||
return 1
|
||||
} else if (distanceA > distanceB) {
|
||||
return -1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
})
|
||||
.forEach(it => it.parent.addChild(it))
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
_stackVertical() {
|
||||
const sorted = []
|
||||
|
||||
let reverseCounter = this.buttons.length - 1
|
||||
|
||||
this.buttons.forEach((it, index) => {
|
||||
const topCorner = it.__originalPosition.y + this.container.y
|
||||
const bottomCorner = it.__originalPosition.y + it.height
|
||||
const paddingTop = index * this.opts.stackPadding
|
||||
const paddingBottom = reverseCounter * this.opts.stackPadding
|
||||
if (topCorner < paddingTop) {
|
||||
// top border
|
||||
it.y = -this.container.y + paddingTop
|
||||
} else if (bottomCorner > -this.container.y + this.opts.maxHeight - paddingBottom) {
|
||||
// bottom border
|
||||
it.y = -this.container.y + this.opts.maxHeight - it.height - paddingBottom
|
||||
} else {
|
||||
return 0
|
||||
it.y = it.__originalPosition.y
|
||||
}
|
||||
|
||||
reverseCounter--
|
||||
|
||||
sorted.push(it)
|
||||
})
|
||||
|
||||
this.buttons.forEach(it => {
|
||||
const parent = it.parent
|
||||
parent.removeChild(it)
|
||||
parent.addChild(it)
|
||||
})
|
||||
const min = Math.min(...sorted.map(it => it.y))
|
||||
const max = Math.max(...sorted.map(it => it.y))
|
||||
const center = (min + max) / 2
|
||||
|
||||
// z-index
|
||||
sorted
|
||||
.sort((a, b) => {
|
||||
const distanceA = Math.abs(a.y - center)
|
||||
const distanceB = Math.abs(b.y - center)
|
||||
if (distanceA < distanceB) {
|
||||
return 1
|
||||
} else if (distanceA > distanceB) {
|
||||
return -1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
})
|
||||
.forEach(it => it.parent.addChild(it))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user