-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #257 from PrefectHQ/bar-sprites
Use textures and sprites for node bars
- Loading branch information
Showing
10 changed files
with
236 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { ColorSource, Container } from 'pixi.js' | ||
import { capFactory } from '@/factories/cap' | ||
import { rectangleFactory } from '@/factories/rectangle' | ||
|
||
type BarStyle = { | ||
width: number, | ||
height: number, | ||
background: ColorSource, | ||
radius: number, | ||
capLeft?: false, | ||
capRight?: false, | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type | ||
export async function barFactory() { | ||
const bar = new Container() | ||
const rectangle = await rectangleFactory() | ||
const { left, right, render: renderCaps } = await capFactory() | ||
|
||
bar.addChild(rectangle) | ||
bar.addChild(left) | ||
bar.addChild(right) | ||
|
||
async function render(style: BarStyle): Promise<Container> { | ||
const { width, x, visible } = getRectangleStyles(style) | ||
|
||
await renderCaps(style) | ||
|
||
rectangle.visible = visible | ||
rectangle.width = width | ||
rectangle.height = style.height | ||
rectangle.x = x | ||
|
||
left.visible = getCapVisibility(style.capLeft, style.radius) | ||
right.visible = getCapVisibility(style.capRight, style.radius) | ||
|
||
right.x = style.radius + width | ||
|
||
rectangle.tint = style.background | ||
left.tint = style.background | ||
right.tint = style.background | ||
|
||
return bar | ||
} | ||
|
||
function getCapVisibility(enabled: boolean | undefined, radius: number): boolean { | ||
if (radius === 0) { | ||
return false | ||
} | ||
|
||
return enabled ?? true | ||
} | ||
|
||
function getRectangleStyles(style: BarStyle): { width: number, x: number, visible: boolean } { | ||
const left = getCapVisibility(style.capLeft, style.radius) | ||
const right = getCapVisibility(style.capRight, style.radius) | ||
|
||
let caps = 0 | ||
|
||
if (left) { | ||
caps += style.radius | ||
} | ||
|
||
if (right) { | ||
caps += style.radius | ||
} | ||
|
||
const width = Math.max(style.width - caps, 0) | ||
const visible = width > 0 | ||
const x = left ? style.radius : 0 | ||
|
||
return { | ||
width, | ||
visible, | ||
x, | ||
} | ||
} | ||
|
||
return { | ||
bar, | ||
render, | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { useSubscription } from '@prefecthq/vue-compositions' | ||
import { Graphics, Rectangle, Sprite, Texture } from 'pixi.js' | ||
import { waitForApplication } from '@/objects' | ||
|
||
type CapStyle = { | ||
height: number, | ||
radius: number, | ||
} | ||
|
||
async function cap({ height, radius }: CapStyle): Promise<Texture> { | ||
const application = await waitForApplication() | ||
|
||
const graphic = new Graphics() | ||
graphic.beginFill('#fff') | ||
graphic.drawRoundedRect(0, 0, radius * 2, height, radius) | ||
graphic.endFill() | ||
|
||
const cap = application.renderer.generateTexture(graphic, { | ||
// drew a rounded rectangle and then just using half of the graphic to get just the left "cap" | ||
region: new Rectangle(0, 0, radius, height), | ||
|
||
// manually bumping up the resolution to keep the border radius from being blurry | ||
resolution: 10, | ||
}) | ||
|
||
return cap | ||
} | ||
|
||
type CapSprites = { | ||
left: Sprite, | ||
right: Sprite, | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type | ||
export function capFactory() { | ||
const left = new Sprite() | ||
const right = new Sprite() | ||
|
||
async function render(style: CapStyle): Promise<CapSprites> { | ||
const texture = (await useSubscription(cap, [style]).promise()).response | ||
left.texture = texture | ||
right.texture = texture | ||
|
||
right.anchor.x = 1 | ||
right.scale.x = -1 | ||
|
||
return { | ||
left, | ||
right, | ||
} | ||
} | ||
|
||
return { | ||
left, | ||
right, | ||
render, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { differenceInMilliseconds, millisecondsInSecond } from 'date-fns' | ||
import { Container } from 'pixi.js' | ||
import { DEFAULT_LINEAR_COLUMN_SIZE_PIXELS, DEFAULT_TIME_COLUMN_SIZE_PIXELS } from '@/consts' | ||
import { barFactory } from '@/factories/bar' | ||
import { RunGraphNode } from '@/models/RunGraph' | ||
import { waitForConfig } from '@/objects/config' | ||
import { layout } from '@/objects/layout' | ||
|
||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type | ||
export async function nodeBarFactory() { | ||
const config = await waitForConfig() | ||
const { bar, render: renderBar } = await barFactory() | ||
|
||
async function render(node: RunGraphNode): Promise<Container> { | ||
const { background = '#fff' } = config.styles.node(node) | ||
const { nodeHeight: height, nodeBorderRadius: radius } = config.styles | ||
const width = getTotalWidth(node, radius) | ||
const capLeft = node.state_type !== 'running' | ||
|
||
await renderBar({ | ||
width, | ||
height, | ||
radius, | ||
background, | ||
capLeft, | ||
}) | ||
|
||
return bar | ||
} | ||
|
||
function getTotalWidth(node: RunGraphNode, borderRadius: number): number { | ||
if (layout.horizontal === 'trace') { | ||
const right = node.start_time | ||
const left = node.end_time ?? new Date() | ||
const seconds = differenceInMilliseconds(left, right) / millisecondsInSecond | ||
const width = seconds * DEFAULT_TIME_COLUMN_SIZE_PIXELS | ||
|
||
// this means the min node size is 18px. Is that correct? | ||
return Math.max(width, borderRadius * 2) | ||
} | ||
|
||
return DEFAULT_LINEAR_COLUMN_SIZE_PIXELS | ||
} | ||
|
||
return { | ||
bar, | ||
render, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { useSubscription } from '@prefecthq/vue-compositions' | ||
import { Graphics, RenderTexture, Sprite } from 'pixi.js' | ||
import { waitForApplication } from '@/objects' | ||
|
||
async function rectangle(): Promise<RenderTexture> { | ||
const application = await waitForApplication() | ||
|
||
const rectangle = new Graphics() | ||
rectangle.beginFill('#fff') | ||
rectangle.drawRect(0, 0, 1, 1) | ||
rectangle.endFill() | ||
|
||
const texture = application.renderer.generateTexture(rectangle) | ||
|
||
return texture | ||
} | ||
|
||
export async function rectangleFactory(): Promise<Sprite> { | ||
const texture = (await useSubscription(rectangle).promise()).response | ||
|
||
return new Sprite(texture) | ||
} |
Oops, something went wrong.