Skip to content

Commit

Permalink
[ts][pixi-v7] Add option to sync attachment visibility to slot object…
Browse files Browse the repository at this point in the history
…. See #2731.
  • Loading branch information
davidetan committed Jan 24, 2025
1 parent 2c00d86 commit 6f8ed12
Showing 1 changed file with 30 additions and 16 deletions.
46 changes: 30 additions & 16 deletions spine-ts/spine-pixi-v7/src/Spine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ export class Spine extends Container {
}
}

private slotsObject = new Map<Slot, Container>();
public slotsObject = new Map<Slot, { container: Container, followAttachmentTimeline: boolean }>();
private getSlotFromRef (slotRef: number | string | Slot): Slot {
let slot: Slot | null;
if (typeof slotRef === 'number') slot = this.skeleton.slots[slotRef];
Expand All @@ -349,13 +349,13 @@ export class Spine extends Container {
* @param slotRef - The slot index, or the slot name, or the Slot where the pixi object will be added to.
* @param pixiObject - The pixi Container to add.
*/
addSlotObject (slotRef: number | string | Slot, pixiObject: Container): void {
addSlotObject (slotRef: number | string | Slot, pixiObject: Container, options?: { followAttachmentTimeline?: boolean }): void {
let slot = this.getSlotFromRef(slotRef);
let oldPixiObject = this.slotsObject.get(slot);
if (oldPixiObject === pixiObject) return;
const oldPixiObject = this.slotsObject.get(slot)?.container;
if (oldPixiObject && oldPixiObject === pixiObject) return;

// search if the pixiObject was already in another slotObject
for (const [otherSlot, oldPixiObjectAnotherSlot] of this.slotsObject) {
for (const [otherSlot, { container: oldPixiObjectAnotherSlot }] of this.slotsObject) {
if (otherSlot !== slot && oldPixiObjectAnotherSlot === pixiObject) {
this.removeSlotObject(otherSlot, pixiObject);
break;
Expand All @@ -364,7 +364,10 @@ export class Spine extends Container {

if (oldPixiObject) this.removeChild(oldPixiObject);

this.slotsObject.set(slot, pixiObject);
this.slotsObject.set(slot, {
container: pixiObject,
followAttachmentTimeline: options?.followAttachmentTimeline || false,
});
this.addChild(pixiObject);
}
/**
Expand All @@ -374,8 +377,10 @@ export class Spine extends Container {
* @returns a Container if any, undefined otherwise.
*/
getSlotObject (slotRef: number | string | Slot): Container | undefined {
return this.slotsObject.get(this.getSlotFromRef(slotRef));
const element = this.slotsObject.get(this.getSlotFromRef(slotRef));
return element ? element.container : undefined;
}

/**
* Remove a slot object from the given slot.
* If `pixiObject` is passed and attached to the given slot, remove it from the slot.
Expand All @@ -385,7 +390,7 @@ export class Spine extends Container {
*/
removeSlotObject (slotRef: number | string | Slot, pixiObject?: Container): void {
let slot = this.getSlotFromRef(slotRef);
let slotObject = this.slotsObject.get(slot);
let slotObject = this.slotsObject.get(slot)?.container;
if (!slotObject) return;

// if pixiObject is passed, remove only if it is equal to the given one
Expand All @@ -404,13 +409,22 @@ export class Spine extends Container {
mask.destroy();
}
}
private updatePixiObject (pixiObject: Container, slot: Slot, zIndex: number) {
pixiObject.position.set(slot.bone.worldX, slot.bone.worldY);
pixiObject.scale.set(slot.bone.getWorldScaleX(), slot.bone.getWorldScaleY());
pixiObject.rotation = slot.bone.getWorldRotationX() * MathUtils.degRad;
pixiObject.zIndex = zIndex + 1;
pixiObject.alpha = this.skeleton.color.a * slot.color.a;

private updateSlotObject (element: { container: Container, followAttachmentTimeline: boolean }, slot: Slot, zIndex: number) {
const { container: slotObject, followAttachmentTimeline } = element

const followAttachmentValue = followAttachmentTimeline ? Boolean(slot.attachment) : true;
slotObject.visible = this.skeleton.drawOrder.includes(slot) && followAttachmentValue;

if (slotObject.visible) {
slotObject.position.set(slot.bone.worldX, slot.bone.worldY);
slotObject.scale.set(slot.bone.getWorldScaleX(), slot.bone.getWorldScaleY());
slotObject.rotation = slot.bone.getWorldRotationX() * MathUtils.degRad;
slotObject.zIndex = zIndex + 1;
slotObject.alpha = this.skeleton.color.a * slot.color.a;
}
}

private updateAndSetPixiMask (pixiMaskSource: PixiMaskSource | null, pixiObject: Container) {
if (Spine.clipper.isClipping() && pixiMaskSource) {
let mask = this.clippingSlotToPixiMasks[pixiMaskSource.slot.data.name] as Graphics;
Expand Down Expand Up @@ -464,9 +478,9 @@ export class Spine extends Container {
let pixiObject = this.slotsObject.get(slot);
let zIndex = i + slotObjectsCounter;
if (pixiObject) {
this.updatePixiObject(pixiObject, slot, zIndex + 1);
this.updateSlotObject(pixiObject, slot, zIndex + 1);
slotObjectsCounter++;
this.updateAndSetPixiMask(pixiMaskSource, pixiObject);
this.updateAndSetPixiMask(pixiMaskSource, pixiObject.container);
}

const useDarkColor = slot.darkColor != null;
Expand Down

0 comments on commit 6f8ed12

Please sign in to comment.