139 lines
3.4 KiB
JavaScript
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());
|
|
}
|