You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, numSegments = 8, offsetX = 0, offsetY = 0, zoom = 1.0, reflectionStr = "true") {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Use naturalWidth and naturalHeight for the true dimensions of the image
// These represent the intrinsic dimensions of the image, ignoring any CSS/attribute scaling.
const imgWidth = originalImg.naturalWidth;
const imgHeight = originalImg.naturalHeight;
// Validate image dimensions. If the image isn't loaded or is invalid, dimensions might be 0.
if (imgWidth === 0 || imgHeight === 0) {
console.error("Image has zero dimensions or is not fully loaded. Cannot process.");
// Return a minimal, identifiable canvas to indicate an error.
canvas.width = 50;
canvas.height = 50;
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'white';
ctx.fillText("Error", 5, canvas.height / 2);
return canvas;
}
// Set canvas dimensions to match the original image
canvas.width = imgWidth;
canvas.height = imgHeight;
// Parse and validate parameters
const actualNumSegments = Math.max(2, Math.floor(Number(numSegments))); // Minimum 2 segments
const actualOffsetX = Number(offsetX); // User-defined horizontal shift from image center
const actualOffsetY = Number(offsetY); // User-defined vertical shift from image center
const actualZoom = Math.max(0.01, Number(zoom)); // Zoom factor, must be positive
const reflect = String(reflectionStr).toLowerCase() === "true"; // Boolean for reflecting alternate segments
const canvasCenterX = canvas.width / 2;
const canvasCenterY = canvas.height / 2;
const segmentAngle = (2 * Math.PI) / actualNumSegments; // Angle of each kaleidoscope wedge
// Determine a radius for the wedge vertices.
// This needs to be large enough so that the wedge, when drawn from the canvas center,
// covers the entire canvas area up to its corners.
// Math.max(canvas.width, canvas.height) ensures the circle circumscribes the canvas.
// A small multiplier adds safety margin for thin wedges or floating point inaccuracies.
const wedgeRadius = Math.max(canvas.width, canvas.height) * 1.1;
// Loop through each segment to draw it
for (let i = 0; i < actualNumSegments; i++) {
const currentSegmentRotation = i * segmentAngle;
ctx.save(); // Save canvas state before transforming for this segment
// 1. Transform the canvas for the current segment
// Move origin to the center of the canvas (kaleidoscope center)
ctx.translate(canvasCenterX, canvasCenterY);
// Rotate the coordinate system for this segment
ctx.rotate(currentSegmentRotation);
// Apply reflection for alternate segments if enabled
if (reflect && (i % 2 !== 0)) {
// Reflect across the segment's local Y-axis (its centerline)
// This flips the image horizontally within the segment's rotated frame.
ctx.scale(-1, 1);
}
// 2. Define the clipping path for the wedge shape of the segment
// The wedge is defined symmetrically around the (now rotated) X-axis.
// Apex at (0,0) in current transformed space.
// Other two vertices define the angular spread of segmentAngle.
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(
wedgeRadius * Math.cos(-segmentAngle / 2),
wedgeRadius * Math.sin(-segmentAngle / 2)
);
ctx.lineTo(
wedgeRadius * Math.cos(segmentAngle / 2),
wedgeRadius * Math.sin(segmentAngle / 2)
);
ctx.closePath();
ctx.clip(); // Apply clipping path: subsequent drawings only in this wedge
// 3. Draw the (transformed) source image within this clipped wedge
ctx.save(); // Save state before image-specific transformations (zoom, pan)
// Apply zoom to the image. Ctx.scale affects subsequent drawing operations.
ctx.scale(actualZoom, actualZoom);
// Pan the (now_zoomed) image.
// The point (imgWidth/2 + actualOffsetX, imgHeight/2 + actualOffsetY) in the *original image*
// coordinates is what we want to align with the current origin (0,0) of the transformed space.
// So, we translate the image by the negative of these values.
ctx.translate(
-(imgWidth / 2 + actualOffsetX),
-(imgHeight / 2 + actualOffsetY)
);
// Enable image smoothing for better quality when scaled/rotated.
// Disable if pixelated look is preferred.
ctx.imageSmoothingEnabled = true;
// Draw the original image. It will be drawn at (0,0) of the
// current scaled and translated coordinate system.
ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
ctx.restore(); // Restore from image-specific transforms (undo scale, translate)
// Clipping path is still active here.
ctx.restore(); // Restore from segment-specific transforms (undo translate, rotate, scale, clip)
// Clears transformations for the next segment.
}
return canvas; // Return the fully rendered kaleidoscope canvas
}
Free Image Tool Creator
Can't find the image tool you're looking for? Create one based on your own needs now!
The Image Kaleidoscope Filter Application allows users to transform images into visually striking kaleidoscope patterns. By adjusting parameters such as the number of segments, offset, zoom level, and reflection options, users can create unique and artistic interpretations of their original images. This tool is useful for graphic designers, artists, and hobbyists looking to enhance their artwork, develop eye-catching visuals for social media, or simply explore creativity with digital images.