133 lines
4.7 KiB
JavaScript
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 }; |