You can edit the below JavaScript code to customize the image tool.
function processImage(
originalImg,
centerXPercent = 50,
centerYPercent = 50,
numTrajectories = 50,
maxTrajectoryLength = 100,
minTrajectoryLength = 20,
trajectoryThickness = 1,
trajectoryColor = 'rgba(255, 255, 255, 0.8)',
startOffset = 0
) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Set canvas dimensions to the original image's dimensions.
// It's assumed originalImg is loaded, so naturalWidth/Height are available.
// If originalImg is not loaded, naturalWidth/Height might be 0.
// The caller should ensure originalImg is loaded (e.g., via originalImg.onload).
canvas.width = originalImg.naturalWidth || 300; // Fallback width if naturalWidth is 0
canvas.height = originalImg.naturalHeight || 150; // Fallback height if naturalHeight is 0
// Draw the original image onto the canvas
if (originalImg.naturalWidth > 0 && originalImg.naturalHeight > 0) {
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
} else {
// Optionally, draw a placeholder if image is not loaded/invalid
ctx.fillStyle = '#cccccc';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#000000';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('Image not loaded', canvas.width / 2, canvas.height / 2);
}
// --- Parameter Parsing and Sanitization ---
let p_centerXPercent = parseFloat(centerXPercent);
if (isNaN(p_centerXPercent)) {
p_centerXPercent = 50; // Fallback to default from signature
}
let p_centerYPercent = parseFloat(centerYPercent);
if (isNaN(p_centerYPercent)) {
p_centerYPercent = 50; // Fallback to default from signature
}
const cx = (p_centerXPercent / 100) * canvas.width;
const cy = (p_centerYPercent / 100) * canvas.height;
let p_numTrajectories = parseInt(numTrajectories, 10);
// If p_numTrajectories is NaN or <0, the loop `for (let i = 0; i < p_numTrajectories; i++)` later
// will not execute, effectively drawing 0 trajectories. This is an acceptable outcome.
// No explicit fallback to default (e.g., 50) needed here, as 0 trajectories is a safe result of invalid input.
let p_minLen = parseFloat(minTrajectoryLength);
if (isNaN(p_minLen)) {
p_minLen = 20; // Fallback to default from signature
}
let p_maxLen = parseFloat(maxTrajectoryLength);
if (isNaN(p_maxLen)) {
p_maxLen = 100; // Fallback to default from signature
}
// Ensure minLength is not greater than maxLength, and lengths are not negative
if (p_minLen > p_maxLen) {
[p_minLen, p_maxLen] = [p_maxLen, p_minLen]; // Swap them
}
if (p_minLen < 0) p_minLen = 0;
if (p_maxLen < 0) p_maxLen = 0; // Will be at least p_minLen (so >=0) after check & potential swap
let p_thickness = parseFloat(trajectoryThickness);
// ctx.lineWidth will handle p_thickness. (NaN > 0) is false.
// If p_thickness is NaN or <=0, it will be set to 1 below.
const p_color = String(trajectoryColor); // Ensures color is a string
let p_startOffset = parseFloat(startOffset);
if (isNaN(p_startOffset) || p_startOffset < 0) {
p_startOffset = 0; // Fallback to 0 if NaN or negative
}
// --- End of Parameter Parsing and Sanitization ---
// Set line properties for the trajectories
ctx.strokeStyle = p_color;
ctx.lineWidth = (p_thickness > 0) ? p_thickness : 1; // Ensure lineWidth is positive, default to 1
ctx.lineCap = 'round'; // Options: 'butt', 'round', 'square'. 'round' gives softer ends.
// Draw the trajectories
// The loop condition handles p_numTrajectories being NaN, negative, or zero safely.
for (let i = 0; i < p_numTrajectories; i++) {
const angle = Math.random() * 2 * Math.PI; // Random angle (0 to 2*PI radians)
// Calculate a random length for this specific trajectory within the min/max range
const currentTrajectoryLength = p_minLen + Math.random() * (p_maxLen - p_minLen);
// Calculate start and end points of the trajectory line
const startX = cx + p_startOffset * Math.cos(angle);
const startY = cy + p_startOffset * Math.sin(angle);
const endX = cx + (p_startOffset + currentTrajectoryLength) * Math.cos(angle);
const endY = cy + (p_startOffset + currentTrajectoryLength) * Math.sin(angle);
// Draw the line
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.stroke();
}
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 Bullet Trajectory Filter Effect tool is designed to add visually striking bullet trajectory effects to images. Users can specify the number of trajectories, their lengths, thickness, and color, allowing for customization based on their creative vision. This tool is suitable for enhancing images in gaming, action photography, or graphic design, where a dynamic and action-packed aesthetic is desired. Whether you’re looking to create compelling graphics for promotional material or simply experimenting with artistic effects, this tool provides a versatile solution for adding unique visual elements to your images.