Jelajahi Sumber

[ts][pixi-v7] Add option to sync attachment visibility to slot object. See #2731.

Davide Tantillo 7 bulan lalu
induk
melakukan
6f8ed12686
1 mengubah file dengan 30 tambahan dan 16 penghapusan
  1. 30 16
      spine-ts/spine-pixi-v7/src/Spine.ts

+ 30 - 16
spine-ts/spine-pixi-v7/src/Spine.ts

@@ -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];
@@ -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;
@@ -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);
 	}
 	/**
@@ -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.
@@ -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
@@ -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;
@@ -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;