You can edit the below JavaScript code to customize the image tool.
/**
* Applies an Astrolabe Filter Effect to an image.
* This effect overlays astrolabe-like geometric patterns (circles, radial lines)
* onto the image and can optionally apply a sepia tone.
* The lines are blended with the image using an 'overlay' composite operation
* to create a more integrated "filter" look.
*
* @param {HTMLImageElement} originalImg The original image element. It's assumed to be loaded.
* @param {string} lineColor Color of the astrolabe lines (e.g., "gold", "rgba(255,215,0,0.7)"). Default is "rgba(220, 180, 100, 0.6)".
* @param {number} mainLineWidth Main thickness of the lines in pixels. Default is 2.
* @param {number} numConcentricCircles Number of inner concentric circles. Default is 5.
* @param {number} numRadialLines Number of radial lines. Default is 12.
* @param {number} applySepia Apply sepia tone to the image (1 for true, 0 for false). Default is 1.
* @param {number} addEccentricCircle Add an eccentric circle, reminiscent of an astrolabe's rete (1 for true, 0 for false). Default is 1.
* @param {number} eccentricCircleOffsetFactor Offset of the eccentric circle's center from the main center, as a fraction of the system's maximum radius. Default is 0.25.
* @param {number} eccentricCircleAngleDeg Angle in degrees for the offset direction of the eccentric circle (0 is right, -90 is up). Default is -30.
* @param {number} eccentricCircleRadiusFactor Radius of the eccentric circle, as a fraction of the system's maximum radius. Default is 0.7.
* @returns {HTMLCanvasElement} A new canvas element with the astrolabe filter effect applied.
*/
function processImage(
originalImg,
lineColor = "rgba(220, 180, 100, 0.6)",
mainLineWidth = 2,
numConcentricCircles = 5,
numRadialLines = 12,
applySepia = 1,
addEccentricCircle = 1,
eccentricCircleOffsetFactor = 0.25,
eccentricCircleAngleDeg = -30,
eccentricCircleRadiusFactor = 0.7
) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const imgWidth = originalImg.naturalWidth || originalImg.width;
const imgHeight = originalImg.naturalHeight || originalImg.height;
if (imgWidth === 0 || imgHeight === 0) {
console.error("Image not loaded or dimensions are zero.");
canvas.width = 200; // A small default size for error display
canvas.height = 150;
ctx.fillStyle = '#DDDDDD'; // Light gray background
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#333333'; // Dark text color
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = '14px Arial';
ctx.fillText("Error: Image Invalid", canvas.width / 2, canvas.height / 2);
return canvas;
}
canvas.width = imgWidth;
canvas.height = imgHeight;
// 1. Draw Image (with Sepia if enabled)
if (applySepia === 1) {
ctx.filter = 'sepia(100%)';
}
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
ctx.filter = 'none'; // Reset filter: important so it doesn't affect subsequent drawing operations
// 2. Prepare for drawing astrolabe lines
ctx.globalCompositeOperation = 'overlay'; // Blends lines with the image for a filter-like effect
ctx.strokeStyle = lineColor;
ctx.lineCap = 'round'; // Makes line ends look a bit softer
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
// Define radii for different parts of the astrolabe design
const maxDimension = Math.min(centerX, centerY);
const maxRadiusSystem = maxDimension * 0.85; // Radius for the main system of lines (concentric, radial)
const outerRingRadius = maxDimension * 0.9; // Radius for the main outer ring (limb)
// 3. Draw Concentric Circles
if (numConcentricCircles > 0 && maxRadiusSystem > 0 && mainLineWidth > 0) {
ctx.lineWidth = mainLineWidth;
for (let i = 1; i <= numConcentricCircles; i++) {
const radius = (maxRadiusSystem / numConcentricCircles) * i;
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
ctx.stroke();
}
}
// 4. Draw Radial Lines
if (numRadialLines > 0 && maxRadiusSystem > 0 && mainLineWidth > 0) {
ctx.lineWidth = mainLineWidth;
let radialStartRadius = 0;
// Calculate starting radius for radial lines (to avoid cluttering the center)
if (numConcentricCircles > 0 && isFinite(maxRadiusSystem / numConcentricCircles)) {
radialStartRadius = (maxRadiusSystem / numConcentricCircles) * 0.5; // Start from half the radius of the first circle
}
for (let i = 0; i < numRadialLines; i++) {
const angle = (2 * Math.PI / numRadialLines) * i;
const startX = centerX + radialStartRadius * Math.cos(angle);
const startY = centerY + radialStartRadius * Math.sin(angle);
const endX = centerX + maxRadiusSystem * Math.cos(angle); // Radials extend to the edge of the main system
const endY = centerY + maxRadiusSystem * Math.sin(angle);
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.stroke();
}
}
// 5. Draw the main outer ring (Limb)
if (outerRingRadius > 0 && mainLineWidth > 0) {
ctx.lineWidth = Math.max(1, mainLineWidth * 2.5); // Make it significantly thicker
ctx.beginPath();
ctx.arc(centerX, centerY, outerRingRadius, 0, 2 * Math.PI);
ctx.stroke();
}
// 6. Draw an eccentric circle (part of the "Rete" stylization)
if (addEccentricCircle === 1 && maxRadiusSystem > 0 && mainLineWidth > 0) {
ctx.lineWidth = Math.max(1, mainLineWidth * 1.2); // Slightly thicker than standard lines
const eccentricOffset = maxRadiusSystem * eccentricCircleOffsetFactor;
const angleRad = eccentricCircleAngleDeg * Math.PI / 180; // Convert degrees to radians
const eccentricCenterX = centerX + eccentricOffset * Math.cos(angleRad);
const eccentricCenterY = centerY + eccentricOffset * Math.sin(angleRad);
const eccentricRadius = maxRadiusSystem * eccentricCircleRadiusFactor;
if (eccentricRadius > 0) {
ctx.beginPath();
ctx.arc(eccentricCenterX, eccentricCenterY, eccentricRadius, 0, 2 * Math.PI);
ctx.stroke();
}
}
// 7. Draw a central "pin"
// Switch to 'source-over' for the pin to make it appear solid on top
ctx.globalCompositeOperation = 'source-over';
if (mainLineWidth > 0) {
ctx.fillStyle = lineColor; // Use lineColor for fill; its alpha will be respected
ctx.beginPath();
const pinRadius = Math.max(1, mainLineWidth * 1.5);
ctx.arc(centerX, centerY, pinRadius, 0, 2 * Math.PI);
ctx.fill();
// Optional: Add a subtle border to the pin for definition
if (pinRadius > 1) { // Only if pin is large enough for a border
ctx.strokeStyle = 'rgba(0,0,0,0.25)'; // Subtle dark border
ctx.lineWidth = Math.max(0.5, mainLineWidth * 0.2);
ctx.stroke();
}
}
// Ensure globalCompositeOperation is reset to default if it was changed
ctx.globalCompositeOperation = 'source-over';
return 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 Astrolabe Filter Effect Tool allows users to apply a unique astrolabe-like filter effect to their images. This tool overlays intricate geometric patterns—such as circles and radial lines—onto images, creating an artistic and visually striking look. Users can customize various parameters, including the color and thickness of the lines, the number of concentric circles and radial lines, and even apply a sepia tone for a classic finish. This tool is ideal for enhancing photos for creative projects, designing themed graphics, or simply adding an artistic flair to personal images.