Spaces:
Running
on
L40S
Running
on
L40S
import { app } from "../../scripts/app.js"; | |
function binarySearch(max, getValue, match) { | |
let min = 0; | |
while (min <= max) { | |
let guess = Math.floor((min + max) / 2); | |
const compareVal = getValue(guess); | |
if (compareVal === match) | |
return guess; | |
if (compareVal < match) | |
min = guess + 1; | |
else | |
max = guess - 1; | |
} | |
return max; | |
} | |
export function fitString(ctx, str, maxWidth) { | |
let width = ctx.measureText(str).width; | |
const ellipsis = "…"; | |
const ellipsisWidth = measureText(ctx, ellipsis); | |
if (width <= maxWidth || width <= ellipsisWidth) { | |
return str; | |
} | |
const index = binarySearch(str.length, (guess) => measureText(ctx, str.substring(0, guess)), maxWidth - ellipsisWidth); | |
return str.substring(0, index) + ellipsis; | |
} | |
export function measureText(ctx, str) { | |
return ctx.measureText(str).width; | |
} | |
export function isLowQuality() { | |
var _a; | |
const canvas = app.canvas; | |
return (((_a = canvas.ds) === null || _a === void 0 ? void 0 : _a.scale) || 1) <= 0.5; | |
} | |
export function drawNodeWidget(ctx, options) { | |
const lowQuality = isLowQuality(); | |
const data = { | |
width: options.width, | |
height: options.height, | |
posY: options.posY, | |
lowQuality, | |
margin: 15, | |
colorOutline: LiteGraph.WIDGET_OUTLINE_COLOR, | |
colorBackground: LiteGraph.WIDGET_BGCOLOR, | |
colorText: LiteGraph.WIDGET_TEXT_COLOR, | |
colorTextSecondary: LiteGraph.WIDGET_SECONDARY_TEXT_COLOR, | |
}; | |
ctx.strokeStyle = options.colorStroke || data.colorOutline; | |
ctx.fillStyle = options.colorBackground || data.colorBackground; | |
ctx.beginPath(); | |
ctx.roundRect(data.margin, data.posY, data.width - data.margin * 2, data.height, lowQuality ? [0] : options.borderRadius ? [options.borderRadius] : [options.height * 0.5]); | |
ctx.fill(); | |
if (!lowQuality) { | |
ctx.stroke(); | |
} | |
return data; | |
} | |
export function drawRoundedRectangle(ctx, options) { | |
const lowQuality = isLowQuality(); | |
options = { ...options }; | |
ctx.strokeStyle = options.colorStroke || LiteGraph.WIDGET_OUTLINE_COLOR; | |
ctx.fillStyle = options.colorBackground || LiteGraph.WIDGET_BGCOLOR; | |
ctx.beginPath(); | |
ctx.roundRect(options.posX, options.posY, options.width, options.height, lowQuality ? [0] : options.borderRadius ? [options.borderRadius] : [options.height * 0.5]); | |
ctx.fill(); | |
!lowQuality && ctx.stroke(); | |
} | |
export function drawNumberWidgetPart(ctx, options) { | |
const arrowWidth = 9; | |
const arrowHeight = 10; | |
const innerMargin = 3; | |
const numberWidth = 32; | |
const xBoundsArrowLess = [0, 0]; | |
const xBoundsNumber = [0, 0]; | |
const xBoundsArrowMore = [0, 0]; | |
ctx.save(); | |
let posX = options.posX; | |
const { posY, height, value, textColor } = options; | |
const midY = posY + height / 2; | |
if (options.direction === -1) { | |
posX = posX - arrowWidth - innerMargin - numberWidth - innerMargin - arrowWidth; | |
} | |
ctx.fill(new Path2D(`M ${posX} ${midY} l ${arrowWidth} ${arrowHeight / 2} l 0 -${arrowHeight} L ${posX} ${midY} z`)); | |
xBoundsArrowLess[0] = posX; | |
xBoundsArrowLess[1] = arrowWidth; | |
posX += arrowWidth + innerMargin; | |
ctx.textAlign = "center"; | |
ctx.textBaseline = "middle"; | |
const oldTextcolor = ctx.fillStyle; | |
if (textColor) { | |
ctx.fillStyle = textColor; | |
} | |
ctx.fillText(fitString(ctx, value.toFixed(2), numberWidth), posX + numberWidth / 2, midY); | |
ctx.fillStyle = oldTextcolor; | |
xBoundsNumber[0] = posX; | |
xBoundsNumber[1] = numberWidth; | |
posX += numberWidth + innerMargin; | |
ctx.fill(new Path2D(`M ${posX} ${midY - arrowHeight / 2} l ${arrowWidth} ${arrowHeight / 2} l -${arrowWidth} ${arrowHeight / 2} v -${arrowHeight} z`)); | |
xBoundsArrowMore[0] = posX; | |
xBoundsArrowMore[1] = arrowWidth; | |
ctx.restore(); | |
return [xBoundsArrowLess, xBoundsNumber, xBoundsArrowMore]; | |
} | |
drawNumberWidgetPart.WIDTH_TOTAL = 9 + 3 + 32 + 3 + 9; | |
export function drawTogglePart(ctx, options) { | |
const lowQuality = isLowQuality(); | |
ctx.save(); | |
const { posX, posY, height, value } = options; | |
const toggleRadius = height * 0.36; | |
const toggleBgWidth = height * 1.5; | |
if (!lowQuality) { | |
ctx.beginPath(); | |
ctx.roundRect(posX + 4, posY + 4, toggleBgWidth - 8, height - 8, [height * 0.5]); | |
ctx.globalAlpha = app.canvas.editor_alpha * 0.25; | |
ctx.fillStyle = "rgba(255,255,255,0.45)"; | |
ctx.fill(); | |
ctx.globalAlpha = app.canvas.editor_alpha; | |
} | |
ctx.fillStyle = value === true ? "#89B" : "#888"; | |
const toggleX = lowQuality || value === false | |
? posX + height * 0.5 | |
: value === true | |
? posX + height | |
: posX + height * 0.75; | |
ctx.beginPath(); | |
ctx.arc(toggleX, posY + height * 0.5, toggleRadius, 0, Math.PI * 2); | |
ctx.fill(); | |
ctx.restore(); | |
return [posX, toggleBgWidth]; | |
} | |
export function drawInfoIcon(ctx, x, y, size = 12) { | |
ctx.save(); | |
ctx.beginPath(); | |
ctx.roundRect(x, y, size, size, [size * 0.1]); | |
ctx.fillStyle = "#2f82ec"; | |
ctx.strokeStyle = "#0f2a5e"; | |
ctx.fill(); | |
ctx.strokeStyle = "#FFF"; | |
ctx.lineWidth = 2; | |
const midX = x + size / 2; | |
const serifSize = size * 0.175; | |
ctx.stroke(new Path2D(` | |
M ${midX} ${y + size * 0.15} | |
v 2 | |
M ${midX - serifSize} ${y + size * 0.45} | |
h ${serifSize} | |
v ${size * 0.325} | |
h ${serifSize} | |
h -${serifSize * 2} | |
`)); | |
ctx.restore(); | |
} | |