ritual.sh/static/js/button-generator/effects/border.js

139 lines
3.4 KiB
JavaScript

import { ButtonEffect } from '../effect-base.js';
/**
* Border effect
* Draws borders around the button with various styles
*/
export class BorderEffect extends ButtonEffect {
constructor() {
super({
id: 'border',
name: 'Border',
type: 'border',
category: 'Border',
renderOrder: 10
});
}
defineControls() {
return [
{
id: 'border-width',
type: 'range',
label: 'Border Width',
defaultValue: 2,
min: 0,
max: 5,
step: 1,
description: 'Width of border in pixels'
},
{
id: 'border-color',
type: 'color',
label: 'Border Color',
defaultValue: '#000000'
},
{
id: 'border-style',
type: 'select',
label: 'Border Style',
defaultValue: 'solid',
options: [
{ value: 'solid', label: 'Solid' },
{ value: 'inset', label: 'Inset (3D)' },
{ value: 'outset', label: 'Outset (3D)' },
{ value: 'ridge', label: 'Ridge' }
]
}
];
}
isEnabled(controlValues) {
const width = controlValues['border-width'] || 0;
return width > 0;
}
apply(context, controlValues, animState, renderData) {
const width = controlValues['border-width'] || 0;
if (width === 0) return;
const color = controlValues['border-color'] || '#000000';
const style = controlValues['border-style'] || 'solid';
if (style === 'solid') {
this.drawSolidBorder(context, width, color, renderData);
} else if (style === 'inset' || style === 'outset') {
this.draw3DBorder(context, width, style === 'outset', renderData);
} else if (style === 'ridge') {
this.drawRidgeBorder(context, width, renderData);
}
}
/**
* Draw solid border
*/
drawSolidBorder(context, width, color, renderData) {
context.strokeStyle = color;
context.lineWidth = width;
context.strokeRect(
width / 2,
width / 2,
renderData.width - width,
renderData.height - width
);
}
/**
* Draw 3D inset/outset border
*/
draw3DBorder(context, width, isOutset, renderData) {
const lightColor = isOutset ? '#ffffff' : '#000000';
const darkColor = isOutset ? '#000000' : '#ffffff';
// Top and left (light)
context.strokeStyle = lightColor;
context.lineWidth = width;
context.beginPath();
context.moveTo(0, renderData.height);
context.lineTo(0, 0);
context.lineTo(renderData.width, 0);
context.stroke();
// Bottom and right (dark)
context.strokeStyle = darkColor;
context.beginPath();
context.moveTo(renderData.width, 0);
context.lineTo(renderData.width, renderData.height);
context.lineTo(0, renderData.height);
context.stroke();
}
/**
* Draw ridge border (double 3D effect)
*/
drawRidgeBorder(context, width, renderData) {
// Outer ridge (light)
context.strokeStyle = '#ffffff';
context.lineWidth = width / 2;
context.strokeRect(
width / 4,
width / 4,
renderData.width - width / 2,
renderData.height - width / 2
);
// Inner ridge (dark)
context.strokeStyle = '#000000';
context.strokeRect(
(width * 3) / 4,
(width * 3) / 4,
renderData.width - width * 1.5,
renderData.height - width * 1.5
);
}
}
// Auto-register effect
export function register(generator) {
generator.registerEffect(new BorderEffect());
}