Automatic image thumbnail creation with customizable dimensions, processing queue, and support for various image sources.
Generate thumbnails for image files with configurable dimensions and processing.
/**
* Create thumbnail for a file
* @param file - File object to create thumbnail for
* @param callback - Optional callback function called when thumbnail is ready
*/
createThumbnail(file: File, callback?: (dataUrl: string) => void): void;
/**
* Create thumbnail from image URL
* @param file - File object associated with the thumbnail
* @param imageUrl - URL of the image to create thumbnail from
* @param callback - Optional callback function called when thumbnail is ready
* @param crossOrigin - Cross-origin setting for image loading
*/
createThumbnailFromUrl(
file: File,
imageUrl: string,
callback?: (dataUrl: string) => void,
crossOrigin?: string
): void;Usage Examples:
const dropzone = new Dropzone("#my-dropzone", {
url: "/upload",
createImageThumbnails: true,
thumbnailWidth: 200,
thumbnailHeight: 200,
maxThumbnailFilesize: 10 // MB
});
// Create thumbnail manually
dropzone.on("addedfile", function(file) {
if (file.type.startsWith("image/")) {
dropzone.createThumbnail(file, function(dataUrl) {
console.log("Thumbnail created for:", file.name);
// Use custom thumbnail display
const img = document.createElement("img");
img.src = dataUrl;
img.className = "custom-thumbnail";
file.previewElement.appendChild(img);
});
}
});
// Create thumbnail from URL
const file = { name: "external-image.jpg", type: "image/jpeg" };
dropzone.createThumbnailFromUrl(
file,
"https://example.com/image.jpg",
function(dataUrl) {
console.log("Thumbnail created from URL");
// Display thumbnail
},
"anonymous" // CORS setting
);Configure thumbnail generation behavior and appearance.
interface ThumbnailOptions {
/** Whether to create image thumbnails automatically */
createImageThumbnails?: boolean;
/** Maximum file size for thumbnail generation in MB */
maxThumbnailFilesize?: number;
/** Thumbnail width in pixels */
thumbnailWidth?: number;
/** Thumbnail height in pixels */
thumbnailHeight?: number;
/** Custom resize function for thumbnail dimensions */
resize?: (file: File) => {
srcX: number; // Source X coordinate
srcY: number; // Source Y coordinate
srcWidth: number; // Source width
srcHeight: number; // Source height
trgX: number; // Target X coordinate
trgY: number; // Target Y coordinate
trgWidth: number; // Target width
trgHeight: number; // Target height
};
}Usage Examples:
// Basic thumbnail configuration
const dropzone = new Dropzone("#my-dropzone", {
url: "/upload",
createImageThumbnails: true,
thumbnailWidth: 150,
thumbnailHeight: 150,
maxThumbnailFilesize: 5 // Only create thumbnails for files < 5MB
});
// Custom resize logic
const customResizeDropzone = new Dropzone("#custom-resize", {
url: "/upload",
createImageThumbnails: true,
thumbnailWidth: 200,
thumbnailHeight: 200,
resize: function(file) {
// Custom resize calculation for square thumbnails
const size = Math.min(file.width, file.height);
const x = (file.width - size) / 2;
const y = (file.height - size) / 2;
return {
srcX: x,
srcY: y,
srcWidth: size,
srcHeight: size,
trgX: 0,
trgY: 0,
trgWidth: this.options.thumbnailWidth,
trgHeight: this.options.thumbnailHeight
};
}
});
// Disable thumbnails for large files
const selectiveDropzone = new Dropzone("#selective-thumbnails", {
url: "/upload",
createImageThumbnails: true,
maxThumbnailFilesize: 2, // 2MB limit
init: function() {
this.on("addedfile", function(file) {
if (file.size > 2 * 1024 * 1024 && file.type.startsWith("image/")) {
console.log("Skipping thumbnail for large file:", file.name);
// Show placeholder instead
const placeholder = document.createElement("div");
placeholder.className = "thumbnail-placeholder";
placeholder.textContent = "Large image";
file.previewElement.appendChild(placeholder);
}
});
}
});Internal thumbnail processing queue to manage thumbnail generation efficiently.
/**
* Add file to thumbnail generation queue
* @param file - File to add to thumbnail queue
*/
_enqueueThumbnail(file: File): void;
/**
* Process the thumbnail generation queue
*/
_processThumbnailQueue(): void;
// Internal properties
_thumbnailQueue: File[]; // Queue of files waiting for thumbnail generation
_processingThumbnail: boolean; // Whether a thumbnail is currently being processedUsage Examples:
const dropzone = new Dropzone("#my-dropzone", {
url: "/upload",
createImageThumbnails: true,
init: function() {
// Monitor thumbnail queue
const originalEnqueue = this._enqueueThumbnail;
this._enqueueThumbnail = function(file) {
console.log("Adding to thumbnail queue:", file.name);
console.log("Queue length:", this._thumbnailQueue.length);
originalEnqueue.call(this, file);
};
// Monitor queue processing
const originalProcess = this._processThumbnailQueue;
this._processThumbnailQueue = function() {
console.log("Processing thumbnail queue, length:", this._thumbnailQueue.length);
originalProcess.call(this);
};
}
});
// Custom thumbnail queue management
function prioritizeThumbnails(dropzone, priorityFiles) {
// Move priority files to front of thumbnail queue
priorityFiles.forEach(priorityFile => {
const index = dropzone._thumbnailQueue.indexOf(priorityFile);
if (index > 0) {
dropzone._thumbnailQueue.splice(index, 1);
dropzone._thumbnailQueue.unshift(priorityFile);
}
});
// Process queue if not already processing
if (!dropzone._processingThumbnail) {
dropzone._processThumbnailQueue();
}
}Events related to thumbnail generation and processing.
/**
* Thumbnail generated successfully
* @param file - File for which thumbnail was generated
* @param dataUrl - Data URL of the generated thumbnail
*/
on("thumbnail", (file: File, dataUrl: string) => void): void;Usage Examples:
const dropzone = new Dropzone("#my-dropzone", {
url: "/upload",
createImageThumbnails: true
});
// Handle thumbnail generation
dropzone.on("thumbnail", function(file, dataUrl) {
console.log("Thumbnail ready for:", file.name);
// Custom thumbnail display
const container = file.previewElement;
const img = container.querySelector("img") || document.createElement("img");
img.src = dataUrl;
img.className = "dropzone-thumbnail";
img.alt = file.name;
// Add thumbnail to container if not already there
if (!container.contains(img)) {
container.appendChild(img);
}
// Store thumbnail data on file object
file.thumbnailData = dataUrl;
// Optional: Create multiple thumbnail sizes
createAdditionalThumbnails(file, dataUrl);
});
function createAdditionalThumbnails(file, originalDataUrl) {
const sizes = [
{ width: 64, height: 64, name: "small" },
{ width: 128, height: 128, name: "medium" },
{ width: 256, height: 256, name: "large" }
];
sizes.forEach(size => {
resizeImage(originalDataUrl, size.width, size.height)
.then(resizedData => {
file[`thumbnail_${size.name}`] = resizedData;
console.log(`${size.name} thumbnail created for:`, file.name);
});
});
}
function resizeImage(dataUrl, width, height) {
return new Promise((resolve) => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const img = new Image();
img.onload = function() {
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
resolve(canvas.toDataURL());
};
img.src = dataUrl;
});
}Advanced thumbnail processing including iOS fixes and custom image handling.
// Internal utility functions (exposed for advanced usage)
/**
* Detect vertical squash in iOS images (iOS 6/7 bug fix)
* @param img - Image element to check
*/
detectVerticalSquash(img: HTMLImageElement): number;
/**
* Draw image with iOS fixes applied
* @param ctx - Canvas 2D context
* @param img - Image to draw
* @param sx - Source X coordinate
* @param sy - Source Y coordinate
* @param sw - Source width
* @param sh - Source height
* @param dx - Destination X coordinate
* @param dy - Destination Y coordinate
* @param dw - Destination width
* @param dh - Destination height
*/
drawImageIOSFix(
ctx: CanvasRenderingContext2D,
img: HTMLImageElement,
sx: number, sy: number, sw: number, sh: number,
dx: number, dy: number, dw: number, dh: number
): void;Usage Examples:
const dropzone = new Dropzone("#my-dropzone", {
url: "/upload",
createImageThumbnails: true,
// Custom resize function with iOS handling
resize: function(file) {
const info = {
srcX: 0,
srcY: 0,
srcWidth: file.width,
srcHeight: file.height,
trgX: 0,
trgY: 0,
trgWidth: this.options.thumbnailWidth,
trgHeight: this.options.thumbnailHeight
};
// Apply aspect ratio preservation
const sourceAspect = file.width / file.height;
const targetAspect = info.trgWidth / info.trgHeight;
if (sourceAspect > targetAspect) {
// Source is wider, crop width
info.srcWidth = file.height * targetAspect;
info.srcX = (file.width - info.srcWidth) / 2;
} else {
// Source is taller, crop height
info.srcHeight = file.width / targetAspect;
info.srcY = (file.height - info.srcHeight) / 2;
}
return info;
}
});
// Custom thumbnail processing with canvas
function createCustomThumbnail(file, callback) {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const img = new Image();
img.onload = function() {
// Set canvas size
canvas.width = 200;
canvas.height = 200;
// Handle iOS image squashing
const verticalSquashRatio = detectVerticalSquash(img);
// Draw with iOS fix
drawImageIOSFix(
ctx, img,
0, 0, img.naturalWidth, img.naturalHeight,
0, 0, 200, 200 / verticalSquashRatio
);
// Apply custom effects
ctx.globalAlpha = 0.8;
ctx.fillStyle = "rgba(0, 0, 0, 0.1)";
ctx.fillRect(0, 0, 200, 200);
callback(canvas.toDataURL());
};
img.src = URL.createObjectURL(file);
}
// Use custom thumbnail processing
dropzone.on("addedfile", function(file) {
if (file.type.startsWith("image/")) {
createCustomThumbnail(file, function(dataUrl) {
// Use the custom thumbnail
file.customThumbnail = dataUrl;
});
}
});Integration with Dropzone's preview template system.
// Default thumbnail template elements
interface ThumbnailTemplate {
/** Main preview element containing thumbnail */
previewElement: HTMLElement;
/** Image element for thumbnail display */
thumbnailElement: HTMLImageElement;
/** Filename display element */
filenameElement: HTMLElement;
/** File size display element */
filesizeElement: HTMLElement;
}Usage Examples:
// Custom preview template with thumbnail integration
const dropzone = new Dropzone("#my-dropzone", {
url: "/upload",
createImageThumbnails: true,
previewTemplate: `
<div class="dz-preview dz-file-preview">
<div class="dz-image">
<img data-dz-thumbnail />
</div>
<div class="dz-details">
<div class="dz-filename"><span data-dz-name></span></div>
<div class="dz-size"><span data-dz-size></span></div>
</div>
<div class="dz-progress">
<span class="dz-upload" data-dz-uploadprogress></span>
</div>
<div class="dz-error-message"><span data-dz-errormessage></span></div>
<div class="dz-success-mark">✓</div>
<div class="dz-error-mark">✗</div>
</div>
`,
init: function() {
this.on("thumbnail", function(file, dataUrl) {
// Thumbnail automatically inserted into [data-dz-thumbnail] element
console.log("Thumbnail integrated with template for:", file.name);
// Add custom thumbnail effects
const thumbnailEl = file.previewElement.querySelector("[data-dz-thumbnail]");
if (thumbnailEl) {
thumbnailEl.style.borderRadius = "8px";
thumbnailEl.style.transition = "transform 0.2s";
thumbnailEl.addEventListener("mouseover", function() {
this.style.transform = "scale(1.05)";
});
thumbnailEl.addEventListener("mouseout", function() {
this.style.transform = "scale(1)";
});
}
});
}
});