Lightningbeam/src/utils.js

133 lines
4.7 KiB
JavaScript

function titleCase(str) {
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
}
function getMousePositionFraction(event, element) {
const rect = element.getBoundingClientRect(); // Get the element's position and size
if (element.classList.contains('horizontal-grid')) {
// If the element has the "horizontal-grid" class, calculate the horizontal position (X)
const xPos = event.clientX - rect.left; // Mouse X position relative to the element
const fraction = xPos / rect.width; // Fraction of the width
return Math.min(Math.max(fraction, 0), 1); // Ensure the fraction is between 0 and 1
} else if (element.classList.contains('vertical-grid')) {
// If the element has the "vertical-grid" class, calculate the vertical position (Y)
const yPos = event.clientY - rect.top; // Mouse Y position relative to the element
const fraction = yPos / rect.height; // Fraction of the height
return Math.min(Math.max(fraction, 0), 1); // Ensure the fraction is between 0 and 1
}
return 0; // If neither class is present, return 0 (or handle as needed)
}
function getKeyframesSurrounding(frames, index) {
let lastKeyframeBefore = undefined;
let firstKeyframeAfter = undefined;
// Find the last keyframe before the given index
for (let i = index - 1; i >= 0; i--) {
if (frames[i].frameType === "keyframe") {
lastKeyframeBefore = i;
break;
}
}
// Find the first keyframe after the given index
for (let i = index + 1; i < frames.length; i++) {
if (frames[i].frameType === "keyframe") {
firstKeyframeAfter = i;
break;
}
}
return { lastKeyframeBefore, firstKeyframeAfter };
}
function invertPixels(ctx, width, height) {
// Create an off-screen canvas for the pattern
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
// Define the size of the repeating pattern (2x2 pixels)
const patternSize = 2;
patternCanvas.width = patternSize;
patternCanvas.height = patternSize;
// Create the alternating pattern (regular and inverted pixels)
function createInvertedPattern() {
const patternData = patternContext.createImageData(patternSize, patternSize);
const data = patternData.data;
// Fill the pattern with alternating colors (inverted every other pixel)
for (let i = 0; i < patternSize; i++) {
for (let j = 0; j < patternSize; j++) {
const index = (i * patternSize + j) * 4;
// Determine if we should invert the color
if ((i + j) % 2 === 0 || j%2===0) {
data[index] = 0; // Red
data[index + 1] = 0; // Green
data[index + 2] = 0; // Blue
data[index + 3] = 255; // Alpha
} else {
data[index] = 255; // Red (inverted)
data[index + 1] = 255; // Green (inverted)
data[index + 2] = 255; // Blue (inverted)
data[index + 3] = 255; // Alpha
}
}
}
// Set the pattern on the off-screen canvas
patternContext.putImageData(patternData, 0, 0);
return patternCanvas;
}
// Create the pattern using the function
const pattern = ctx.createPattern(createInvertedPattern(), 'repeat');
// Draw a rectangle with the pattern
ctx.globalCompositeOperation = "difference"
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, width, height);
ctx.globalCompositeOperation = "source-over"
}
function lerp(a, b, t) {
return a + (b - a) * t;
}
function lerpColor(color1, color2, t) {
// Convert hex color to RGB
const hexToRgb = (hex) => {
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
return { r, g, b };
};
// Convert RGB to hex color
const rgbToHex = (r, g, b) => {
return `#${(1 << 24 | (r << 16) | (g << 8) | b).toString(16).slice(1).toUpperCase()}`;
};
// Get RGB values of both colors
const start = hexToRgb(color1);
const end = hexToRgb(color2);
// Calculate the interpolated RGB values
const r = Math.round(start.r + (end.r - start.r) * t);
const g = Math.round(start.g + (end.g - start.g) * t);
const b = Math.round(start.b + (end.b - start.b) * t);
// Convert the interpolated RGB back to hex
return rgbToHex(r, g, b);
}
function camelToWords(camelCaseString) {
// Insert a space before each uppercase letter and make it lowercase
const words = camelCaseString.replace(/([A-Z])/g, ' $1').toLowerCase();
// Capitalize the first letter of each word
return words.replace(/\b\w/g, char => char.toUpperCase());
}
export { titleCase, getMousePositionFraction, getKeyframesSurrounding, invertPixels, lerp, lerpColor, camelToWords };