New effects, refactor
This commit is contained in:
parent
4ac45367e5
commit
c0d6bee9c3
14 changed files with 1620 additions and 215 deletions
167
static/js/button-generator/effects/text-shadow.js
Normal file
167
static/js/button-generator/effects/text-shadow.js
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
import { ButtonEffect } from "../effect-base.js";
|
||||
|
||||
/**
|
||||
* Text Drop Shadow Effect
|
||||
* Renders text with a drop shadow underneath
|
||||
* This draws the shadow first, then standard text rendering draws on top
|
||||
*/
|
||||
export class TextShadowEffect extends ButtonEffect {
|
||||
constructor(textLineNumber = 1) {
|
||||
const suffix = textLineNumber === 1 ? "" : "2";
|
||||
super({
|
||||
id: `text-shadow${suffix}`,
|
||||
name: `Drop Shadow ${textLineNumber}`,
|
||||
type: textLineNumber === 1 ? "text" : "text2",
|
||||
category: textLineNumber === 1 ? "Text Line 1" : "Text Line 2",
|
||||
renderOrder: 19, // Before standard text (20), so shadow draws first
|
||||
textLineNumber: textLineNumber,
|
||||
});
|
||||
this.textLineNumber = textLineNumber;
|
||||
}
|
||||
|
||||
defineControls() {
|
||||
const textLineNumber =
|
||||
this.textLineNumber || this.config?.textLineNumber || 1;
|
||||
const suffix = textLineNumber === 1 ? "" : "2";
|
||||
|
||||
return [
|
||||
{
|
||||
id: `text${suffix}-shadow-enabled`,
|
||||
type: "checkbox",
|
||||
label: "Drop Shadow",
|
||||
defaultValue: false,
|
||||
description:
|
||||
"Add drop shadow to text - Not compatible with other text effects!!",
|
||||
},
|
||||
{
|
||||
id: `text${suffix}-shadow-color`,
|
||||
type: "color",
|
||||
label: "Shadow Color",
|
||||
defaultValue: "#000000",
|
||||
showWhen: `text${suffix}-shadow-enabled`,
|
||||
description: "Color of the shadow",
|
||||
},
|
||||
{
|
||||
id: `text${suffix}-shadow-blur`,
|
||||
type: "range",
|
||||
label: "Shadow Blur",
|
||||
defaultValue: 4,
|
||||
min: 0,
|
||||
max: 10,
|
||||
step: 1,
|
||||
showWhen: `text${suffix}-shadow-enabled`,
|
||||
description: "Blur radius of shadow",
|
||||
},
|
||||
{
|
||||
id: `text${suffix}-shadow-offset-x`,
|
||||
type: "range",
|
||||
label: "Shadow X Offset",
|
||||
defaultValue: 2,
|
||||
min: -10,
|
||||
max: 10,
|
||||
step: 1,
|
||||
showWhen: `text${suffix}-shadow-enabled`,
|
||||
description: "Horizontal shadow offset",
|
||||
},
|
||||
{
|
||||
id: `text${suffix}-shadow-offset-y`,
|
||||
type: "range",
|
||||
label: "Shadow Y Offset",
|
||||
defaultValue: 2,
|
||||
min: -10,
|
||||
max: 10,
|
||||
step: 1,
|
||||
showWhen: `text${suffix}-shadow-enabled`,
|
||||
description: "Vertical shadow offset",
|
||||
},
|
||||
{
|
||||
id: `text${suffix}-shadow-opacity`,
|
||||
type: "range",
|
||||
label: "Shadow Opacity",
|
||||
defaultValue: 0.8,
|
||||
min: 0,
|
||||
max: 1,
|
||||
step: 0.1,
|
||||
showWhen: `text${suffix}-shadow-enabled`,
|
||||
description: "Opacity of the shadow",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
isEnabled(controlValues) {
|
||||
const suffix = this.textLineNumber === 1 ? "" : "2";
|
||||
const textEnabled = controlValues[`text${suffix}-enabled`];
|
||||
const shadowEnabled = controlValues[`text${suffix}-shadow-enabled`];
|
||||
return textEnabled && shadowEnabled;
|
||||
}
|
||||
|
||||
apply(context, controlValues, animState, renderData) {
|
||||
const suffix = this.textLineNumber === 1 ? "" : "2";
|
||||
|
||||
const text = controlValues[`button-text${suffix}`] || "";
|
||||
if (!text) return;
|
||||
|
||||
// Get shadow settings
|
||||
const shadowColor =
|
||||
controlValues[`text${suffix}-shadow-color`] || "#000000";
|
||||
const shadowBlur = controlValues[`text${suffix}-shadow-blur`] || 4;
|
||||
const shadowOffsetX = controlValues[`text${suffix}-shadow-offset-x`] || 2;
|
||||
const shadowOffsetY = controlValues[`text${suffix}-shadow-offset-y`] || 2;
|
||||
const shadowOpacity = controlValues[`text${suffix}-shadow-opacity`] || 0.8;
|
||||
|
||||
// Get text rendering settings
|
||||
const fontSize = controlValues[`font-size${suffix}`] || 14;
|
||||
const fontFamily = controlValues[`font-family${suffix}`] || "Arial";
|
||||
const fontWeight = controlValues[`text${suffix}-bold`] ? "bold" : "normal";
|
||||
const fontStyle = controlValues[`text${suffix}-italic`]
|
||||
? "italic"
|
||||
: "normal";
|
||||
const textX = (controlValues[`text${suffix}-x`] || 50) / 100;
|
||||
const textY = (controlValues[`text${suffix}-y`] || 50) / 100;
|
||||
|
||||
// Convert hex to rgba
|
||||
const hexToRgba = (hex, alpha) => {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
if (result) {
|
||||
const r = parseInt(result[1], 16);
|
||||
const g = parseInt(result[2], 16);
|
||||
const b = parseInt(result[3], 16);
|
||||
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
||||
}
|
||||
return `rgba(0, 0, 0, ${alpha})`;
|
||||
};
|
||||
|
||||
// Set up text rendering
|
||||
context.font = `${fontStyle} ${fontWeight} ${fontSize}px "${fontFamily}"`;
|
||||
context.textAlign = "center";
|
||||
context.textBaseline = "middle";
|
||||
|
||||
// Calculate text position
|
||||
const x = renderData.width * textX;
|
||||
const y = renderData.height * textY;
|
||||
|
||||
// Draw the shadow using the shadow API
|
||||
// This will create a shadow underneath whatever we draw
|
||||
context.shadowColor = hexToRgba(shadowColor, shadowOpacity);
|
||||
context.shadowBlur = shadowBlur;
|
||||
context.shadowOffsetX = shadowOffsetX;
|
||||
context.shadowOffsetY = shadowOffsetY;
|
||||
|
||||
// Draw a solid shadow by filling with the shadow color
|
||||
// The shadow API will create the blur effect
|
||||
context.fillStyle = hexToRgba(shadowColor, shadowOpacity);
|
||||
context.fillText(text, x, y);
|
||||
|
||||
// Reset shadow for subsequent renders
|
||||
context.shadowColor = "transparent";
|
||||
context.shadowBlur = 0;
|
||||
context.shadowOffsetX = 0;
|
||||
context.shadowOffsetY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Export two instances for text line 1 and text line 2
|
||||
export function register(generator) {
|
||||
generator.registerEffect(new TextShadowEffect(1));
|
||||
generator.registerEffect(new TextShadowEffect(2));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue