Skip to content

Commit

Permalink
feat: Added Rendering & Interactivity panels
Browse files Browse the repository at this point in the history
Fixes #121 & 120
  • Loading branch information
bfanger committed Sep 24, 2023
1 parent 6a6f9bb commit 4ac4032
Show file tree
Hide file tree
Showing 14 changed files with 323 additions and 44 deletions.
2 changes: 1 addition & 1 deletion apps/chrome-extension/src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": 3,
"name": "PixiJS Devtools",
"description": "Debug games and apps written with PixiJS",
"version": "2.6.1",
"version": "2.7.0",
"devtools_page": "pixi-devtools.html",
"icons": {
"16": "icon.png",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion apps/example-phaser-project/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const game = new Phaser.Game({
(globalThis as any).__PHASER_GAME__ = game; // eslint-disable-line

function preload(this: Phaser.Scene) {
this.load.setBaseURL("http://labs.phaser.io");
this.load.setBaseURL("/");

this.load.image("sky", "assets/skies/space3.png");
this.load.image("logo", "assets/sprites/phaser3-logo.png");
Expand Down
12 changes: 12 additions & 0 deletions apps/example-pixi-project/interactivity.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Interactivity - PixiJS Examples</title>
</head>
<body>
<script type="module" src="./src/interactivity.ts"></script>
</body>
</html>
85 changes: 85 additions & 0 deletions apps/example-pixi-project/src/interactivity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import * as PIXI from "pixi.js";

const app = new PIXI.Application({ resizeTo: window });
// eslint-disable-next-line no-underscore-dangle
(globalThis as any).__PIXI_APP__ = app;
document.body.appendChild(app.view as HTMLCanvasElement);

const background = PIXI.Sprite.from("https://pixijs.com/assets/bg_button.jpg");

background.width = app.screen.width;
background.height = app.screen.height;

app.stage.addChild(background);

const textureButton = PIXI.Texture.from("https://pixijs.com/assets/button.png");
const textureButtonDown = PIXI.Texture.from(
"https://pixijs.com/assets/button_down.png",
);
const textureButtonOver = PIXI.Texture.from(
"https://pixijs.com/assets/button_over.png",
);

type Button = PIXI.Sprite & { isdown: boolean; isOver: boolean };
const buttons = [];

const buttonPositions = [175, 75, 655, 75, 410, 325, 150, 465, 685, 445];

for (let i = 0; i < 5; i += 1) {
const button = new PIXI.Sprite(textureButton);

button.anchor.set(0.5);
button.x = buttonPositions[i * 2];
button.y = buttonPositions[i * 2 + 1];

button.eventMode = "static";
button.cursor = "pointer";

button
.on("pointerdown", onButtonDown)
.on("pointerup", onButtonUp)
.on("pointerupoutside", onButtonUp)
.on("pointerover", onButtonOver)
.on("pointerout", onButtonOut);

app.stage.addChild(button);

buttons.push(button);
}

buttons[0].scale.set(1.2);
buttons[2].rotation = Math.PI / 10;
buttons[3].scale.set(0.8);
buttons[4].scale.set(0.8, 1.2);
buttons[4].rotation = Math.PI;

function onButtonDown(this: Button) {
this.isdown = true;
this.texture = textureButtonDown;
this.alpha = 1;
}

function onButtonUp(this: Button) {
this.isdown = false;
if (this.isOver) {
this.texture = textureButtonOver;
} else {
this.texture = textureButton;
}
}

function onButtonOver(this: Button) {
this.isOver = true;
if (this.isdown) {
return;
}
this.texture = textureButtonOver;
}

function onButtonOut(this: Button) {
this.isOver = false;
if (this.isdown) {
return;
}
this.texture = textureButton;
}
2 changes: 1 addition & 1 deletion apps/firefox-extension/src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": 3,
"name": "PixiJS Devtools",
"description": "Debug games and apps written with PixiJS",
"version": "2.6.1",
"version": "2.7.0",
"devtools_page": "pixi-devtools.html",
"icons": {
"48": "icon.png",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@sveltejs/vite-plugin-svelte": "^2.4.6",
"@types/chrome": "^0.0.246",
"@types/firefox-webext-browser": "^111.0.2",
"@types/node": "^20.6.3",
"@types/node": "^20.6.4",
"@typescript-eslint/eslint-plugin": "^6.7.2",
"@typescript-eslint/parser": "^6.7.2",
"concurrently": "^8.2.1",
Expand Down
152 changes: 152 additions & 0 deletions packages/pixi-panel/src/ObjectProperties.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import NumberField from "blender-elements/src/NumberField/NumberField.svelte";
import Checkbox from "blender-elements/src/Checkbox/Checkbox.svelte";
import Property from "blender-elements/src/Property/Property.svelte";
import SelectMenu from "blender-elements/src/SelectMenu/SelectMenu.svelte";
import type { NodeProperties } from "./types";
export let props: NodeProperties;
Expand All @@ -23,6 +24,14 @@
$: visibilityPanel =
typeof props.alpha === "number" || typeof props.visible === "boolean";
$: renderPanel =
typeof props.sortableChildren === "boolean" ||
typeof props.zIndex === "number" ||
typeof props.cullable === "boolean";
$: interactivePanel =
typeof props.interactive === "boolean" ||
typeof props.interactiveChildren === "boolean";
let skewDimensionsPanel = "";
$: if (typeof props.width === "number" && typeof props.skewX === "number") {
Expand Down Expand Up @@ -196,6 +205,34 @@
</Checkbox>
</Property>
{/if}
</Panel>
{/if}
{#if renderPanel}
<Panel title="Rendering" bind:expanded={expanded.rendering}>
{#if typeof props.sortableChildren === "boolean"}
<Property>
<Checkbox
value={props.sortableChildren}
hint="If set to true, the container will sort its children by zIndex value"
on:change={(e) =>
dispatch("change", {
property: "sortableChildren",
value: e.detail,
})}
>
Sortable children
</Checkbox>
</Property>
{/if}
{#if typeof props.zIndex === "number"}
<Property label="Z Index">
<NumberField
value={props.zIndex}
on:change={(e) =>
dispatch("change", { property: "zIndex", value: e.detail })}
/>
</Property>
{/if}
{#if typeof props.cullable === "boolean"}
<Property>
<Checkbox
Expand All @@ -210,6 +247,7 @@
{/if}
</Panel>
{/if}

{#if skewDimensionsPanel}
<Panel title={skewDimensionsPanel} bind:expanded={expanded.skewDimensions}>
{#if typeof props.skewX === "number"}
Expand Down Expand Up @@ -260,3 +298,117 @@
{/if}
</Panel>
{/if}
{#if interactivePanel}
<Panel title="Interactivity" bind:expanded={expanded.interactive}>
{#if typeof props.eventMode === "string"}
<Property
label="Event mode"
hint="Enable interaction events for the DisplayObject. Touch, pointer and mouse. This now replaces the interactive property."
>
<SelectMenu
legend="Event Mode"
value={props.eventMode}
options={[
{ value: "none", label: "None" },
{ value: "passive", label: "Passive" },
{ value: "auto", label: "Auto" },
{ value: "static", label: "Static" },
{ value: "dynamic", label: "Dynamic" },
]}
on:change={(e) =>
dispatch("change", { property: "eventMode", value: e.detail })}
/>
</Property>
<Property label="Cursor">
<SelectMenu
legend="Cursor"
value={props.cursor ?? ""}
options={[
...(props.cursor ? [] : [{ value: "", label: "" }]),
{ value: "auto", label: "Auto" },
{ value: "default", label: "Default" },
{ value: "none", label: "None" },
{ value: "context-menu", label: "Context menu" },
{ value: "help", label: "Help" },
{ value: "pointer", label: "Pointer" },
{ value: "progress", label: "Progress" },
{ value: "wait", label: "Wait" },
{ value: "cell", label: "Cell" },
{ value: "crosshair", label: "Crosshair" },
{ value: "text", label: "Text" },
{ value: "vertical-text", label: "Vertical text" },
{ value: "alias", label: "Alias" },
{ value: "copy", label: "Copy" },
{ value: "move", label: "Move" },
{ value: "no-drop", label: "No drop" },
{ value: "not-allowed", label: "Not allowed" },
{ value: "all-scroll", label: "All scroll" },
{ value: "zoom-in", label: "Zoom in" },
{ value: "zoom-out", label: "Zoom out" },
{ value: "grab", label: "Grab" },
{ value: "grabbing", label: "Grabbing" },
// { value: "e-resize", label: "Resize (East)" },
// { value: "n-resize", label: "Resize (North)" },
// { value: "ne-resize", label: "Resize (North East)" },
// { value: "nw-resize", label: "Resize (North West)" },
// { value: "s-resize", label: "Resize (South)" },
// { value: "se-resize", label: "Resize (South East)" },
// { value: "sw-resize", label: "Resize (South West)" },
// { value: "w-resize", label: "Resize (West)" },
// { value: "ns-resize", label: "Resize (North South)" },
// { value: "ew-resize", label: "Resize (East West)" },
// { value: "nesw-resize", label: "Resize (North East South West)" },
// { value: "col-resize", label: "Resize (Column)" },
// { value: "nwse-resize", label: "Resize (North West South East)" },
// { value: "row-resize", label: "Resize (Row)" },
]}
on:change={(e) =>
dispatch("change", {
property: "cursor",
value: e.detail === "" ? undefined : e.detail,
})}
/>
</Property>
{/if}
{#if typeof props.interactive === "boolean"}
<Property>
<Checkbox
value={props.interactive}
hint="Enable interaction events for the DisplayObject. Touch, pointer and mouse"
on:change={(e) =>
dispatch("change", { property: "interactive", value: e.detail })}
>
Interactive
</Checkbox>
</Property>
{/if}

{#if typeof props.buttonMode === "boolean"}
<Property>
<Checkbox
value={props.buttonMode}
hint="If enabled, the mouse cursor use the pointer behavior when hovered over the displayObject if it is interactive Setting this changes the 'cursor' property to 'pointer'."
on:change={(e) =>
dispatch("change", { property: "buttonMode", value: e.detail })}
>
Button mode
</Checkbox>
</Property>
{/if}
{#if typeof props.interactiveChildren === "boolean"}
<Property>
<Checkbox
value={props.interactiveChildren}
hint="Determines if the children to the displayObject can be clicked/touched Setting this to false allows PixiJS to bypass a recursive hitTest function"
on:change={(e) =>
dispatch("change", {
property: "interactiveChildren",
value: e.detail,
})}
>
Interactive children
</Checkbox>
</Property>
{/if}
</Panel>
{/if}
2 changes: 2 additions & 0 deletions packages/pixi-panel/src/PropertiesArea.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
transformOrigin: true,
skewDimensions: true,
visibility: true,
rendering: true,
interactive: true,
font: true,
alignment: true,
spacer: true,
Expand Down
23 changes: 21 additions & 2 deletions packages/pixi-panel/src/pixi-devtools/pixiDevtoolsProperties.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { GameObjects } from "phaser";
import type { Application } from "pixi.js";
import type { Application, DisplayObject } from "pixi.js";
import type {
NodeProperties,
PixiDevtools,
Expand Down Expand Up @@ -119,7 +119,9 @@ export default function pixiDevtoolsProperties(devtools: PixiDevtools) {
objectDefs.push(...directProp(node, "alpha", "number"));
objectDefs.push(...directProp(node, "visible", "boolean"));
objectDefs.push(...directProp(node, "cullable", "boolean"));

objectDefs.push(...directProp(node, "sortableChildren", "boolean"));
objectDefs.push(...directProp(node, "zIndex", "number"));
objectDefs.push(...directProp(node, "interactiveChildren", "boolean"));
if (
"originX" in node &&
typeof node.originX === "number" &&
Expand All @@ -145,6 +147,23 @@ export default function pixiDevtoolsProperties(devtools: PixiDevtools) {
),
});
}
if (devtools.isPixi(node as UniversalNode)) {
const displayObject: DisplayObject = node as DisplayObject;
if (typeof displayObject.eventMode === "string") {
objectDefs.push(...directProp(node, "eventMode", "string"));
objectDefs.push({
key: "cursor",
get: () => displayObject.cursor,
set: (value) => {
displayObject.cursor = value;
},
});
} else {
objectDefs.push(...directProp(node, "interactive", "boolean"));
objectDefs.push(...directProp(node, "buttonMode", "boolean"));
}
}

// Text
const textDefs: PropertyMapping[] = [];

Expand Down
9 changes: 9 additions & 0 deletions packages/pixi-panel/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { GameObjects, Scene, Scenes } from "phaser";
import type {
Cursor,
DisplayObject,
EventMode,
TextStyleAlign,
TextStyleFontStyle,
TextStyleFontVariant,
Expand Down Expand Up @@ -71,6 +73,13 @@ export type NodeProperties = {
alpha?: number;
visible?: boolean;
cullable?: boolean;
sortableChildren?: boolean;
zIndex?: number;
interactive?: boolean;
cursor?: Cursor;
buttonMode?: boolean;
interactiveChildren?: boolean;
eventMode?: EventMode;
// Scene
speed?: number;
started?: boolean;
Expand Down
Loading

0 comments on commit 4ac4032

Please sign in to comment.