kinetic-slider
Version:
A WebGL-powered kinetic slider component using PIXI.js
211 lines (207 loc) • 8.1 kB
JavaScript
;
var pixiFilters = require('pixi-filters');
var gsap = require('gsap');
var ShaderResourceManager = require('../managers/ShaderResourceManager.cjs');
function createGlitchFilter(config) {
const shaderManager = ShaderResourceManager.ShaderResourceManager.getInstance();
const options = {};
if (config.average !== void 0) options.average = config.average;
if (config.direction !== void 0) options.direction = config.direction;
if (config.red !== void 0) options.red = config.red;
if (config.green !== void 0) options.green = config.green;
if (config.blue !== void 0) options.blue = config.blue;
if (config.slices !== void 0) options.slices = config.slices;
if (config.offset !== void 0) options.offset = config.offset;
if (config.minSize !== void 0) options.minSize = config.minSize;
if (config.sampleSize !== void 0) options.sampleSize = config.sampleSize;
if (config.seed !== void 0) options.seed = config.seed;
if (config.fillMode !== void 0) options.fillMode = config.fillMode;
const slicesStr = (options.slices || 5).toString();
const fillModeStr = (options.fillMode || 0).toString();
const shaderKey = `glitch-filter-${slicesStr}-${fillModeStr}`;
const filter = new pixiFilters.GlitchFilter(options);
try {
shaderManager.registerFilter(filter, shaderKey);
} catch (error) {
console.warn("Error registering glitch filter with shader manager:", error);
}
let animationInterval = null;
let currentTweens = [];
let currentTargets = {
red: { ...filter.red },
blue: { ...filter.blue },
green: { ...filter.green },
offset: filter.offset,
direction: filter.direction
};
const generateTargetValues = (baseOffset) => {
const variation = baseOffset * 0.6;
const redX = Math.random() * variation * 2 - variation + (config.red?.x || 0);
const redY = Math.random() * variation * 0.5 - variation * 0.25 + (config.red?.y || 0);
const blueX = Math.random() * variation * 2 - variation + (config.blue?.x || 0);
const blueY = Math.random() * variation * 0.5 - variation * 0.25 + (config.blue?.y || 0);
const greenX = config.green?.x || 0;
const greenY = config.green?.y || 0;
const offsetVariation = baseOffset * 0.4;
const newOffset = filter.offset + (Math.random() * offsetVariation * 2 - offsetVariation);
const directionChange = Math.random() > 0.7 ? Math.random() * 30 - 15 : 0;
const newDirection = ((filter.direction + directionChange) % 360 + 360) % 360;
return {
red: { x: redX, y: redY },
blue: { x: blueX, y: blueY },
green: { x: greenX, y: greenY },
// Add green channel
offset: Math.max(0, newOffset),
direction: newDirection
};
};
const updateAnimationInterval = (frequency, baseIntensity) => {
if (animationInterval !== null) {
window.clearInterval(animationInterval);
animationInterval = null;
}
for (const tween of currentTweens) {
tween.kill();
}
currentTweens = [];
if (frequency > 0 && config.animated) {
const interval = Math.floor(1e3 / frequency);
const transitionDuration = Math.min(interval * 0.8 / 1e3, 0.5);
animationInterval = window.setInterval(() => {
const targetValues = generateTargetValues(baseIntensity * 10);
currentTargets = { ...targetValues };
const shouldTweenRed = Math.random() > 0.3;
const shouldTweenBlue = Math.random() > 0.3;
const shouldTweenOffset = Math.random() > 0.5;
for (const tween of currentTweens) {
tween.kill();
}
currentTweens = [];
const tweenProps = {};
if (shouldTweenRed) {
tweenProps.red = targetValues.red;
} else {
filter.red = targetValues.red;
}
if (shouldTweenBlue) {
tweenProps.blue = targetValues.blue;
} else {
filter.blue = targetValues.blue;
}
if (shouldTweenOffset) {
tweenProps.offset = targetValues.offset;
} else {
filter.offset = targetValues.offset;
}
filter.direction = targetValues.direction;
if (Object.keys(tweenProps).length > 0) {
const eases = ["power1.inOut", "power2.inOut", "power3.in", "power2.out", "none"];
const ease = eases[Math.floor(Math.random() * eases.length)];
const duration = Math.max(0.05, Math.random() * transitionDuration);
const tween = gsap.gsap.to(filter, {
duration,
...tweenProps,
ease,
onComplete: () => {
if (Math.random() > 0.8) {
filter.refresh();
if (Math.random() > 0.7) {
filter.seed = Math.random() * 1e3;
}
}
}
});
currentTweens.push(tween);
} else {
filter.refresh();
}
if (Math.random() > 0.85) {
setTimeout(() => {
const miniJump = Math.random() * baseIntensity * 15;
filter.offset = filter.offset + miniJump;
if (Math.random() > 0.5) {
filter.direction = (filter.direction + (Math.random() * 90 - 45)) % 360;
}
setTimeout(() => {
filter.offset = currentTargets.offset;
filter.direction = currentTargets.direction;
}, Math.random() * 100 + 50);
}, Math.random() * (interval * 0.6));
}
}, interval);
}
};
const updateIntensity = (intensity) => {
const normalizedIntensity = Math.max(0, Math.min(10, intensity));
if (config.primaryProperty) {
switch (config.primaryProperty) {
case "slices":
filter.slices = 1 + Math.floor(normalizedIntensity * 2);
break;
case "offset":
filter.offset = normalizedIntensity * 20;
break;
case "direction":
filter.direction = normalizedIntensity * 36;
break;
case "red":
filter.red = { x: normalizedIntensity * 2, y: 0 };
break;
case "blue":
filter.blue = { x: -normalizedIntensity * 2, y: 0 };
break;
default:
filter.offset = normalizedIntensity * 20;
}
} else {
filter.offset = normalizedIntensity * 20;
}
if (config.refreshFrequency !== void 0) {
updateAnimationInterval(config.refreshFrequency, normalizedIntensity);
}
};
updateIntensity(config.intensity);
const reset = () => {
if (animationInterval !== null) {
window.clearInterval(animationInterval);
animationInterval = null;
}
for (const tween of currentTweens) {
tween.kill();
}
currentTweens = [];
filter.average = config.average !== void 0 ? config.average : false;
filter.red = config.red || { x: 0, y: 0 };
filter.green = config.green || { x: 0, y: 0 };
filter.blue = config.blue || { x: 0, y: 0 };
filter.offset = config.offset !== void 0 ? config.offset : 0;
filter.direction = config.direction !== void 0 ? config.direction : 0;
filter.fillMode = config.fillMode !== void 0 ? config.fillMode : 0;
filter.seed = config.seed !== void 0 ? config.seed : 0;
filter.slices = config.slices !== void 0 ? config.slices : 5;
filter.minSize = config.minSize !== void 0 ? config.minSize : 8;
filter.sampleSize = config.sampleSize !== void 0 ? config.sampleSize : 512;
if (config.intensity !== void 0) {
updateIntensity(config.intensity);
}
};
const dispose = () => {
if (animationInterval !== null) {
window.clearInterval(animationInterval);
animationInterval = null;
}
for (const tween of currentTweens) {
tween.kill();
}
currentTweens = [];
try {
shaderManager.releaseFilter(filter, shaderKey);
} catch (error) {
console.warn("Error releasing glitch filter shader:", error);
}
filter.destroy();
};
return { filter, updateIntensity, reset, dispose };
}
exports.createGlitchFilter = createGlitchFilter;
//# sourceMappingURL=glitchFilter.cjs.map