mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-15 01:48:06 +00:00
Compare commits
1 Commits
main
...
fix/codera
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe20f29b09 |
@@ -5494,11 +5494,12 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
* @todo Split tooltip from hover, so it can be drawn / eased separately
|
||||
*/
|
||||
drawLinkTooltip(ctx: CanvasRenderingContext2D, link: LinkSegment): void {
|
||||
ctx.save()
|
||||
const pos = link._pos
|
||||
ctx.fillStyle = 'black'
|
||||
ctx.beginPath()
|
||||
if (this.linkMarkerShape === LinkMarkerShape.Arrow) {
|
||||
const transform = ctx.getTransform()
|
||||
ctx.save()
|
||||
ctx.translate(pos[0], pos[1])
|
||||
// Assertion: Number.isFinite guarantees this is a number.
|
||||
if (Number.isFinite(link._centreAngle))
|
||||
@@ -5506,7 +5507,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
ctx.moveTo(-2, -3)
|
||||
ctx.lineTo(+4, 0)
|
||||
ctx.lineTo(-2, +3)
|
||||
ctx.setTransform(transform)
|
||||
ctx.restore()
|
||||
} else if (
|
||||
this.linkMarkerShape == null ||
|
||||
this.linkMarkerShape === LinkMarkerShape.Circle
|
||||
@@ -5517,10 +5518,16 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
|
||||
// @ts-expect-error TODO: Better value typing
|
||||
const { data } = link
|
||||
if (data == null) return
|
||||
if (data == null) {
|
||||
ctx.restore()
|
||||
return
|
||||
}
|
||||
|
||||
// @ts-expect-error TODO: Better value typing
|
||||
if (this.onDrawLinkTooltip?.(ctx, link, this) == true) return
|
||||
if (this.onDrawLinkTooltip?.(ctx, link, this) == true) {
|
||||
ctx.restore()
|
||||
return
|
||||
}
|
||||
|
||||
let text: string | null = null
|
||||
|
||||
@@ -5530,7 +5537,10 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
else if (data.toToolTip) text = data.toToolTip()
|
||||
else text = `[${data.constructor.name}]`
|
||||
|
||||
if (text == null) return
|
||||
if (text == null) {
|
||||
ctx.restore()
|
||||
return
|
||||
}
|
||||
|
||||
// Hard-coded tooltip limit
|
||||
text = text.substring(0, 30)
|
||||
@@ -5554,6 +5564,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
ctx.textAlign = 'center'
|
||||
ctx.fillStyle = '#CEC'
|
||||
ctx.fillText(text, pos[0], pos[1] - 15 - h * 0.3)
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -91,7 +91,7 @@ export function strokeShape(
|
||||
}
|
||||
|
||||
// Set up context
|
||||
const { lineWidth, strokeStyle } = ctx
|
||||
ctx.save()
|
||||
ctx.lineWidth = thickness
|
||||
ctx.globalAlpha = 0.8
|
||||
ctx.strokeStyle = color
|
||||
@@ -138,12 +138,7 @@ export function strokeShape(
|
||||
// Stroke the shape
|
||||
ctx.stroke()
|
||||
|
||||
// Reset context
|
||||
ctx.lineWidth = lineWidth
|
||||
ctx.strokeStyle = strokeStyle
|
||||
|
||||
// TODO: Store and reset value properly. Callers currently expect this behaviour (e.g. muted nodes).
|
||||
ctx.globalAlpha = 1
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,18 +211,24 @@ export function drawTextInArea({
|
||||
}: IDrawTextInAreaOptions) {
|
||||
const { left, right, bottom, width, centreX } = area
|
||||
|
||||
ctx.save()
|
||||
|
||||
// Text already fits
|
||||
const fullWidth = ctx.measureText(text).width
|
||||
if (fullWidth <= width) {
|
||||
ctx.textAlign = align
|
||||
const x = align === 'left' ? left : align === 'right' ? right : centreX
|
||||
ctx.fillText(text, x, bottom)
|
||||
ctx.restore()
|
||||
return
|
||||
}
|
||||
|
||||
// Need to truncate text
|
||||
const truncated = truncateTextToWidth(ctx, text, width)
|
||||
if (truncated.length === 0) return
|
||||
if (truncated.length === 0) {
|
||||
ctx.restore()
|
||||
return
|
||||
}
|
||||
|
||||
// Draw text - left-aligned to prevent bouncing during resize
|
||||
ctx.textAlign = 'left'
|
||||
@@ -238,4 +239,6 @@ export function drawTextInArea({
|
||||
ctx.textAlign = 'right'
|
||||
const ellipsis = truncated.at(-1)!
|
||||
ctx.fillText(ellipsis, right, bottom, ctx.measureText(ellipsis).width * 0.75)
|
||||
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
@@ -318,15 +318,9 @@ export abstract class SubgraphIONodeBase<
|
||||
| SubgraphOutput,
|
||||
editorAlpha?: number
|
||||
): void {
|
||||
const { lineWidth, strokeStyle, fillStyle, font, textBaseline } = ctx
|
||||
ctx.save()
|
||||
this.drawProtected(ctx, colorContext, fromSlot, editorAlpha)
|
||||
Object.assign(ctx, {
|
||||
lineWidth,
|
||||
strokeStyle,
|
||||
fillStyle,
|
||||
font,
|
||||
textBaseline
|
||||
})
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
/** @internal Leaves {@link ctx} dirty. */
|
||||
|
||||
@@ -39,8 +39,8 @@ export class AssetWidget
|
||||
options: DrawWidgetOptions
|
||||
) {
|
||||
const { width, showText = true } = options
|
||||
// Store original context attributes
|
||||
const { fillStyle, strokeStyle, textAlign } = ctx
|
||||
|
||||
ctx.save()
|
||||
|
||||
this.drawWidgetShape(ctx, options)
|
||||
|
||||
@@ -48,8 +48,7 @@ export class AssetWidget
|
||||
this.drawTruncatingText({ ctx, width, leftPadding: 0, rightPadding: 0 })
|
||||
}
|
||||
|
||||
// Restore original context attributes
|
||||
Object.assign(ctx, { textAlign, strokeStyle, fillStyle })
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
override onClick() {
|
||||
|
||||
@@ -62,8 +62,7 @@ export abstract class BaseSteppedWidget<
|
||||
ctx: CanvasRenderingContext2D,
|
||||
options: DrawWidgetOptions
|
||||
) {
|
||||
// Store original context attributes
|
||||
const { fillStyle, strokeStyle, textAlign } = ctx
|
||||
ctx.save()
|
||||
|
||||
this.drawWidgetShape(ctx, options)
|
||||
if (options.showText) {
|
||||
@@ -72,7 +71,6 @@ export abstract class BaseSteppedWidget<
|
||||
this.drawTruncatingText({ ctx, width: options.width })
|
||||
}
|
||||
|
||||
// Restore original context attributes
|
||||
Object.assign(ctx, { textAlign, strokeStyle, fillStyle })
|
||||
ctx.restore()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ export class BooleanWidget
|
||||
ctx: CanvasRenderingContext2D,
|
||||
options: DrawWidgetOptions
|
||||
) {
|
||||
ctx.save()
|
||||
|
||||
const { width, showText = true } = options
|
||||
const { height, y } = this
|
||||
const { margin } = BaseWidget
|
||||
@@ -28,6 +30,8 @@ export class BooleanWidget
|
||||
this.drawLabel(ctx, margin * 2)
|
||||
this.drawValue(ctx, width - 40)
|
||||
}
|
||||
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
drawLabel(ctx: CanvasRenderingContext2D, x: number): void {
|
||||
|
||||
@@ -25,8 +25,7 @@ export class ButtonWidget
|
||||
ctx: CanvasRenderingContext2D,
|
||||
{ width, showText = true, suppressPromotedOutline }: DrawWidgetOptions
|
||||
) {
|
||||
// Store original context attributes
|
||||
const { fillStyle, strokeStyle, textAlign } = ctx
|
||||
ctx.save()
|
||||
|
||||
const { height, y } = this
|
||||
const { margin } = BaseWidget
|
||||
@@ -48,8 +47,7 @@ export class ButtonWidget
|
||||
// Draw button text
|
||||
if (showText) this.drawLabel(ctx, width * 0.5)
|
||||
|
||||
// Restore original context attributes
|
||||
Object.assign(ctx, { textAlign, strokeStyle, fillStyle })
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
drawLabel(ctx: CanvasRenderingContext2D, x: number): void {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { t } from '@/i18n'
|
||||
|
||||
import type { IChartWidget } from '../types/widgets'
|
||||
import { BaseWidget } from './BaseWidget'
|
||||
import type { DrawWidgetOptions, WidgetEventOptions } from './BaseWidget'
|
||||
@@ -15,32 +13,7 @@ export class ChartWidget
|
||||
override type = 'chart' as const
|
||||
|
||||
drawWidget(ctx: CanvasRenderingContext2D, options: DrawWidgetOptions): void {
|
||||
const { width } = options
|
||||
const { y, height } = this
|
||||
|
||||
const { fillStyle, strokeStyle, textAlign, textBaseline, font } = ctx
|
||||
|
||||
ctx.fillStyle = this.background_color
|
||||
ctx.fillRect(15, y, width - 30, height)
|
||||
|
||||
ctx.strokeStyle = this.getOutlineColor(options.suppressPromotedOutline)
|
||||
ctx.strokeRect(15, y, width - 30, height)
|
||||
|
||||
ctx.fillStyle = this.text_color
|
||||
ctx.font = '11px monospace'
|
||||
ctx.textAlign = 'center'
|
||||
ctx.textBaseline = 'middle'
|
||||
|
||||
const text = `Chart: ${t('widgets.node2only')}`
|
||||
ctx.fillText(text, width / 2, y + height / 2)
|
||||
|
||||
Object.assign(ctx, {
|
||||
fillStyle,
|
||||
strokeStyle,
|
||||
textAlign,
|
||||
textBaseline,
|
||||
font
|
||||
})
|
||||
this.drawVueOnlyWarning(ctx, options, 'Chart')
|
||||
}
|
||||
|
||||
onClick(_options: WidgetEventOptions): void {
|
||||
|
||||
@@ -29,7 +29,7 @@ export class ColorWidget
|
||||
override type = 'color' as const
|
||||
|
||||
drawWidget(ctx: CanvasRenderingContext2D, options: DrawWidgetOptions): void {
|
||||
const { fillStyle, strokeStyle, textAlign } = ctx
|
||||
ctx.save()
|
||||
|
||||
this.drawWidgetShape(ctx, options)
|
||||
|
||||
@@ -62,7 +62,7 @@ export class ColorWidget
|
||||
ctx.textAlign = 'right'
|
||||
ctx.fillText(this.value || '#000000', swatchX - 8, y + height * 0.7)
|
||||
|
||||
Object.assign(ctx, { textAlign, strokeStyle, fillStyle })
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
onClick({ e, node, canvas }: WidgetEventOptions): void {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { t } from '@/i18n'
|
||||
|
||||
import type { IFileUploadWidget } from '../types/widgets'
|
||||
import { BaseWidget } from './BaseWidget'
|
||||
import type { DrawWidgetOptions, WidgetEventOptions } from './BaseWidget'
|
||||
@@ -15,32 +13,7 @@ export class FileUploadWidget
|
||||
override type = 'fileupload' as const
|
||||
|
||||
drawWidget(ctx: CanvasRenderingContext2D, options: DrawWidgetOptions): void {
|
||||
const { width } = options
|
||||
const { y, height } = this
|
||||
|
||||
const { fillStyle, strokeStyle, textAlign, textBaseline, font } = ctx
|
||||
|
||||
ctx.fillStyle = this.background_color
|
||||
ctx.fillRect(15, y, width - 30, height)
|
||||
|
||||
ctx.strokeStyle = this.getOutlineColor(options.suppressPromotedOutline)
|
||||
ctx.strokeRect(15, y, width - 30, height)
|
||||
|
||||
ctx.fillStyle = this.text_color
|
||||
ctx.font = '11px monospace'
|
||||
ctx.textAlign = 'center'
|
||||
ctx.textBaseline = 'middle'
|
||||
|
||||
const text = `Fileupload: ${t('widgets.node2only')}`
|
||||
ctx.fillText(text, width / 2, y + height / 2)
|
||||
|
||||
Object.assign(ctx, {
|
||||
fillStyle,
|
||||
strokeStyle,
|
||||
textAlign,
|
||||
textBaseline,
|
||||
font
|
||||
})
|
||||
this.drawVueOnlyWarning(ctx, options, 'Fileupload')
|
||||
}
|
||||
|
||||
onClick(_options: WidgetEventOptions): void {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { t } from '@/i18n'
|
||||
|
||||
import type { IGalleriaWidget } from '../types/widgets'
|
||||
import { BaseWidget } from './BaseWidget'
|
||||
import type { DrawWidgetOptions, WidgetEventOptions } from './BaseWidget'
|
||||
@@ -15,32 +13,7 @@ export class GalleriaWidget
|
||||
override type = 'galleria' as const
|
||||
|
||||
drawWidget(ctx: CanvasRenderingContext2D, options: DrawWidgetOptions): void {
|
||||
const { width } = options
|
||||
const { y, height } = this
|
||||
|
||||
const { fillStyle, strokeStyle, textAlign, textBaseline, font } = ctx
|
||||
|
||||
ctx.fillStyle = this.background_color
|
||||
ctx.fillRect(15, y, width - 30, height)
|
||||
|
||||
ctx.strokeStyle = this.getOutlineColor(options.suppressPromotedOutline)
|
||||
ctx.strokeRect(15, y, width - 30, height)
|
||||
|
||||
ctx.fillStyle = this.text_color
|
||||
ctx.font = '11px monospace'
|
||||
ctx.textAlign = 'center'
|
||||
ctx.textBaseline = 'middle'
|
||||
|
||||
const text = `Galleria: ${t('widgets.node2only')}`
|
||||
ctx.fillText(text, width / 2, y + height / 2)
|
||||
|
||||
Object.assign(ctx, {
|
||||
fillStyle,
|
||||
strokeStyle,
|
||||
textAlign,
|
||||
textBaseline,
|
||||
font
|
||||
})
|
||||
this.drawVueOnlyWarning(ctx, options, 'Galleria')
|
||||
}
|
||||
|
||||
onClick(_options: WidgetEventOptions): void {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { t } from '@/i18n'
|
||||
|
||||
import type { IImageCompareWidget } from '../types/widgets'
|
||||
import { BaseWidget } from './BaseWidget'
|
||||
import type { DrawWidgetOptions, WidgetEventOptions } from './BaseWidget'
|
||||
@@ -15,32 +13,7 @@ export class ImageCompareWidget
|
||||
override type = 'imagecompare' as const
|
||||
|
||||
drawWidget(ctx: CanvasRenderingContext2D, options: DrawWidgetOptions): void {
|
||||
const { width } = options
|
||||
const { y, height } = this
|
||||
|
||||
const { fillStyle, strokeStyle, textAlign, textBaseline, font } = ctx
|
||||
|
||||
ctx.fillStyle = this.background_color
|
||||
ctx.fillRect(15, y, width - 30, height)
|
||||
|
||||
ctx.strokeStyle = this.getOutlineColor(options.suppressPromotedOutline)
|
||||
ctx.strokeRect(15, y, width - 30, height)
|
||||
|
||||
ctx.fillStyle = this.text_color
|
||||
ctx.font = '11px monospace'
|
||||
ctx.textAlign = 'center'
|
||||
ctx.textBaseline = 'middle'
|
||||
|
||||
const text = `ImageCompare: ${t('widgets.node2only')}`
|
||||
ctx.fillText(text, width / 2, y + height / 2)
|
||||
|
||||
Object.assign(ctx, {
|
||||
fillStyle,
|
||||
strokeStyle,
|
||||
textAlign,
|
||||
textBaseline,
|
||||
font
|
||||
})
|
||||
this.drawVueOnlyWarning(ctx, options, 'ImageCompare')
|
||||
}
|
||||
|
||||
onClick(_options: WidgetEventOptions): void {
|
||||
|
||||
@@ -35,8 +35,7 @@ export class KnobWidget extends BaseWidget<IKnobWidget> implements IKnobWidget {
|
||||
ctx: CanvasRenderingContext2D,
|
||||
{ width, showText = true, suppressPromotedOutline }: DrawWidgetOptions
|
||||
): void {
|
||||
// Store original context attributes
|
||||
const { fillStyle, strokeStyle, textAlign } = ctx
|
||||
ctx.save()
|
||||
|
||||
const { y } = this
|
||||
const { margin } = BaseWidget
|
||||
@@ -177,8 +176,7 @@ export class KnobWidget extends BaseWidget<IKnobWidget> implements IKnobWidget {
|
||||
)
|
||||
}
|
||||
|
||||
// Restore original context attributes
|
||||
Object.assign(ctx, { textAlign, strokeStyle, fillStyle })
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
onClick(): void {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { t } from '@/i18n'
|
||||
|
||||
import type { IMarkdownWidget } from '../types/widgets'
|
||||
import { BaseWidget } from './BaseWidget'
|
||||
import type { DrawWidgetOptions, WidgetEventOptions } from './BaseWidget'
|
||||
@@ -15,32 +13,7 @@ export class MarkdownWidget
|
||||
override type = 'markdown' as const
|
||||
|
||||
drawWidget(ctx: CanvasRenderingContext2D, options: DrawWidgetOptions): void {
|
||||
const { width } = options
|
||||
const { y, height } = this
|
||||
|
||||
const { fillStyle, strokeStyle, textAlign, textBaseline, font } = ctx
|
||||
|
||||
ctx.fillStyle = this.background_color
|
||||
ctx.fillRect(15, y, width - 30, height)
|
||||
|
||||
ctx.strokeStyle = this.getOutlineColor(options.suppressPromotedOutline)
|
||||
ctx.strokeRect(15, y, width - 30, height)
|
||||
|
||||
ctx.fillStyle = this.text_color
|
||||
ctx.font = '11px monospace'
|
||||
ctx.textAlign = 'center'
|
||||
ctx.textBaseline = 'middle'
|
||||
|
||||
const text = `Markdown: ${t('widgets.node2only')}`
|
||||
ctx.fillText(text, width / 2, y + height / 2)
|
||||
|
||||
Object.assign(ctx, {
|
||||
fillStyle,
|
||||
strokeStyle,
|
||||
textAlign,
|
||||
textBaseline,
|
||||
font
|
||||
})
|
||||
this.drawVueOnlyWarning(ctx, options, 'Markdown')
|
||||
}
|
||||
|
||||
onClick(_options: WidgetEventOptions): void {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { t } from '@/i18n'
|
||||
|
||||
import type { IMultiSelectWidget } from '../types/widgets'
|
||||
import { BaseWidget } from './BaseWidget'
|
||||
import type { DrawWidgetOptions, WidgetEventOptions } from './BaseWidget'
|
||||
@@ -15,32 +13,7 @@ export class MultiSelectWidget
|
||||
override type = 'multiselect' as const
|
||||
|
||||
drawWidget(ctx: CanvasRenderingContext2D, options: DrawWidgetOptions): void {
|
||||
const { width } = options
|
||||
const { y, height } = this
|
||||
|
||||
const { fillStyle, strokeStyle, textAlign, textBaseline, font } = ctx
|
||||
|
||||
ctx.fillStyle = this.background_color
|
||||
ctx.fillRect(15, y, width - 30, height)
|
||||
|
||||
ctx.strokeStyle = this.getOutlineColor(options.suppressPromotedOutline)
|
||||
ctx.strokeRect(15, y, width - 30, height)
|
||||
|
||||
ctx.fillStyle = this.text_color
|
||||
ctx.font = '11px monospace'
|
||||
ctx.textAlign = 'center'
|
||||
ctx.textBaseline = 'middle'
|
||||
|
||||
const text = `MultiSelect: ${t('widgets.node2only')}`
|
||||
ctx.fillText(text, width / 2, y + height / 2)
|
||||
|
||||
Object.assign(ctx, {
|
||||
fillStyle,
|
||||
strokeStyle,
|
||||
textAlign,
|
||||
textBaseline,
|
||||
font
|
||||
})
|
||||
this.drawVueOnlyWarning(ctx, options, 'MultiSelect')
|
||||
}
|
||||
|
||||
onClick(_options: WidgetEventOptions): void {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { t } from '@/i18n'
|
||||
|
||||
import type { ISelectButtonWidget } from '../types/widgets'
|
||||
import { BaseWidget } from './BaseWidget'
|
||||
import type { DrawWidgetOptions, WidgetEventOptions } from './BaseWidget'
|
||||
@@ -15,32 +13,7 @@ export class SelectButtonWidget
|
||||
override type = 'selectbutton' as const
|
||||
|
||||
drawWidget(ctx: CanvasRenderingContext2D, options: DrawWidgetOptions): void {
|
||||
const { width } = options
|
||||
const { y, height } = this
|
||||
|
||||
const { fillStyle, strokeStyle, textAlign, textBaseline, font } = ctx
|
||||
|
||||
ctx.fillStyle = this.background_color
|
||||
ctx.fillRect(15, y, width - 30, height)
|
||||
|
||||
ctx.strokeStyle = this.getOutlineColor(options.suppressPromotedOutline)
|
||||
ctx.strokeRect(15, y, width - 30, height)
|
||||
|
||||
ctx.fillStyle = this.text_color
|
||||
ctx.font = '11px monospace'
|
||||
ctx.textAlign = 'center'
|
||||
ctx.textBaseline = 'middle'
|
||||
|
||||
const text = `SelectButton: ${t('widgets.node2only')}`
|
||||
ctx.fillText(text, width / 2, y + height / 2)
|
||||
|
||||
Object.assign(ctx, {
|
||||
fillStyle,
|
||||
strokeStyle,
|
||||
textAlign,
|
||||
textBaseline,
|
||||
font
|
||||
})
|
||||
this.drawVueOnlyWarning(ctx, options, 'SelectButton')
|
||||
}
|
||||
|
||||
onClick(_options: WidgetEventOptions): void {
|
||||
|
||||
@@ -22,8 +22,7 @@ export class SliderWidget
|
||||
ctx: CanvasRenderingContext2D,
|
||||
{ width, showText = true, suppressPromotedOutline }: DrawWidgetOptions
|
||||
) {
|
||||
// Store original context attributes
|
||||
const { fillStyle, strokeStyle, textAlign } = ctx
|
||||
ctx.save()
|
||||
|
||||
const { height, y } = this
|
||||
const { margin } = BaseWidget
|
||||
@@ -67,8 +66,7 @@ export class SliderWidget
|
||||
)
|
||||
}
|
||||
|
||||
// Restore original context attributes
|
||||
Object.assign(ctx, { textAlign, strokeStyle, fillStyle })
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,8 +24,8 @@ export class TextWidget
|
||||
options: DrawWidgetOptions
|
||||
) {
|
||||
const { width, showText = true } = options
|
||||
// Store original context attributes
|
||||
const { fillStyle, strokeStyle, textAlign } = ctx
|
||||
|
||||
ctx.save()
|
||||
|
||||
this.drawWidgetShape(ctx, options)
|
||||
|
||||
@@ -33,8 +33,7 @@ export class TextWidget
|
||||
this.drawTruncatingText({ ctx, width, leftPadding: 0, rightPadding: 0 })
|
||||
}
|
||||
|
||||
// Restore original context attributes
|
||||
Object.assign(ctx, { textAlign, strokeStyle, fillStyle })
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
override onClick({ e, node, canvas }: WidgetEventOptions) {
|
||||
|
||||
@@ -432,7 +432,7 @@ export class CanvasPathRenderer {
|
||||
const angle = Math.atan2(posB.y - posA.y, posB.x - posA.x)
|
||||
|
||||
// Draw arrow triangle (matching original shape)
|
||||
const transform = ctx.getTransform()
|
||||
ctx.save()
|
||||
ctx.translate(posA.x, posA.y)
|
||||
ctx.rotate(angle)
|
||||
ctx.fillStyle = color
|
||||
@@ -441,7 +441,7 @@ export class CanvasPathRenderer {
|
||||
ctx.lineTo(0, +7)
|
||||
ctx.lineTo(+5, -3)
|
||||
ctx.fill()
|
||||
ctx.setTransform(transform)
|
||||
ctx.restore()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -803,20 +803,19 @@ export class CanvasPathRenderer {
|
||||
): void {
|
||||
if (!link.centerPos) return
|
||||
|
||||
ctx.save()
|
||||
ctx.beginPath()
|
||||
|
||||
if (
|
||||
context.style.centerMarkerShape === 'arrow' &&
|
||||
link.centerAngle !== undefined
|
||||
) {
|
||||
const transform = ctx.getTransform()
|
||||
ctx.translate(link.centerPos.x, link.centerPos.y)
|
||||
ctx.rotate(link.centerAngle)
|
||||
// The math is off, but it currently looks better in chromium (from original)
|
||||
ctx.moveTo(-3.2, -5)
|
||||
ctx.lineTo(7, 0)
|
||||
ctx.lineTo(-3.2, 5)
|
||||
ctx.setTransform(transform)
|
||||
} else {
|
||||
// Default to circle
|
||||
ctx.arc(link.centerPos.x, link.centerPos.y, 5, 0, Math.PI * 2)
|
||||
@@ -824,15 +823,14 @@ export class CanvasPathRenderer {
|
||||
|
||||
// Apply disabled pattern or color
|
||||
if (link.disabled && context.patterns?.disabled) {
|
||||
const { fillStyle, globalAlpha } = ctx
|
||||
ctx.fillStyle = context.patterns.disabled
|
||||
ctx.globalAlpha = 0.75
|
||||
ctx.fill()
|
||||
ctx.globalAlpha = globalAlpha
|
||||
ctx.fillStyle = fillStyle
|
||||
} else {
|
||||
ctx.fillStyle = color
|
||||
ctx.fill()
|
||||
}
|
||||
|
||||
ctx.restore()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user