88 lines
2.9 KiB
JavaScript
88 lines
2.9 KiB
JavaScript
import { ButtonEffect } from '../effect-base.js';
|
|
|
|
export class FlashTextEffect extends ButtonEffect {
|
|
constructor(textLineNumber = 1) {
|
|
const suffix = textLineNumber === 1 ? '' : '2';
|
|
super({
|
|
id: `text-flash${suffix}`,
|
|
name: `Flash Text ${textLineNumber}`,
|
|
type: textLineNumber === 1 ? 'text' : 'text2',
|
|
category: textLineNumber === 1 ? 'Text Line 1' : 'Text Line 2',
|
|
renderOrder: 1, // Execute very early, before all other text effects
|
|
textLineNumber: textLineNumber
|
|
});
|
|
this.textLineNumber = textLineNumber;
|
|
}
|
|
|
|
defineControls() {
|
|
const textLineNumber = this.textLineNumber || this.config?.textLineNumber || 1;
|
|
const suffix = textLineNumber === 1 ? '' : '2';
|
|
|
|
return [
|
|
{
|
|
id: `animate-text-flash${suffix}`,
|
|
type: 'checkbox',
|
|
label: 'Flash Visibility',
|
|
defaultValue: false
|
|
},
|
|
{
|
|
id: `flash-range${suffix}`,
|
|
type: 'range-dual',
|
|
label: 'Visible Frame Range',
|
|
defaultValueStart: textLineNumber === 1 ? 0 : 20,
|
|
defaultValueEnd: textLineNumber === 1 ? 19 : 39,
|
|
min: 0,
|
|
max: 39,
|
|
step: 1,
|
|
showWhen: `animate-text-flash${suffix}`,
|
|
description: 'Frame range where text is visible (0-39 frames total)'
|
|
}
|
|
];
|
|
}
|
|
|
|
isEnabled(controlValues) {
|
|
const suffix = this.textLineNumber === 1 ? '' : '2';
|
|
return controlValues[`animate-text-flash${suffix}`] === true;
|
|
}
|
|
|
|
apply(context, controlValues, animState, renderData) {
|
|
if (!animState) return; // Flash requires animation
|
|
|
|
const suffix = this.textLineNumber === 1 ? '' : '2';
|
|
const startFrame = controlValues[`flash-range${suffix}-start`] || 0;
|
|
const endFrame = controlValues[`flash-range${suffix}-end`] || 39;
|
|
|
|
// Check if current frame is within visible range
|
|
const isVisible = this.isFrameVisible(animState.frame, startFrame, endFrame);
|
|
|
|
// Store visibility state in renderData so other text effects can check it
|
|
const visibilityKey = `textFlashVisible${suffix}`;
|
|
renderData[visibilityKey] = isVisible;
|
|
|
|
// Also set globalAlpha (even though it gets restored, it helps during this effect's lifecycle)
|
|
if (!isVisible) {
|
|
context.globalAlpha = 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if frame is within visible range
|
|
* @param {number} frame - Current frame number (0-39)
|
|
* @param {number} startFrame - Start of visible range
|
|
* @param {number} endFrame - End of visible range
|
|
* @returns {boolean} - True if frame is in visible range
|
|
*/
|
|
isFrameVisible(frame, startFrame, endFrame) {
|
|
// Ensure start is less than or equal to end
|
|
const start = Math.min(startFrame, endFrame);
|
|
const end = Math.max(startFrame, endFrame);
|
|
|
|
return frame >= start && frame <= end;
|
|
}
|
|
}
|
|
|
|
// Auto-register effects for both text lines
|
|
export function register(generator) {
|
|
generator.registerEffect(new FlashTextEffect(1));
|
|
generator.registerEffect(new FlashTextEffect(2));
|
|
}
|