A Vue.js component that provides comprehensive image cropping functionality for Vue 2 applications.
—
Methods for controlling the VueCropper component programmatically, including crop operations, image transformations, and data extraction.
Methods for managing the cropping interface and crop box state.
/**
* Begin cropping mode and show crop box
*/
startCrop(): void;
/**
* Exit cropping mode and hide crop box
*/
stopCrop(): void;
/**
* Remove crop box and clear cropping area
*/
clearCrop(): void;
/**
* Generate automatic crop box based on current settings
* @param w - Optional crop box width
* @param h - Optional crop box height
*/
goAutoCrop(w?: number, h?: number): void;Usage Examples:
<template>
<div class="cropper-container">
<VueCropper ref="cropper" :img="imageUrl" />
<div class="controls">
<button @click="startCropping">Start Crop</button>
<button @click="stopCropping">Stop Crop</button>
<button @click="clearCropping">Clear Crop</button>
<button @click="autoGenerate">Auto Generate</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
imageUrl: '/path/to/image.jpg'
};
},
methods: {
startCropping() {
this.$refs.cropper.startCrop();
this.isCropping = true;
},
stopCropping() {
this.$refs.cropper.stopCrop();
this.isCropping = false;
},
clearCropping() {
this.$refs.cropper.clearCrop();
this.cropCleared = true;
},
autoGenerate() {
// First ensure auto crop settings are configured
this.$refs.cropper.goAutoCrop();
}
}
};
</script>Methods for manipulating the image display and orientation.
/**
* Scale/zoom the image
* @param delta - Positive values zoom in, negative values zoom out
*/
changeScale(delta: number): void;
/**
* Rotate image 90 degrees counter-clockwise
*/
rotateLeft(): void;
/**
* Rotate image 90 degrees clockwise
*/
rotateRight(): void;
/**
* Reset component to initial state
*/
refresh(): void;
/**
* Clear all rotation and reset to 0 degrees
*/
rotateClear(): void;
/**
* Manually change crop box dimensions
* @param w - New crop box width
* @param h - New crop box height
*/
changeCrop(w: number, h: number): void;
/**
* Position crop box programmatically
* @param event - Optional event object
* @param isMove - Optional move flag
*/
moveCrop(event?: Event, isMove?: boolean): void;Usage Examples:
<template>
<div class="image-editor">
<VueCropper ref="cropper" :img="imageUrl" />
<div class="transformation-controls">
<div class="zoom-controls">
<button @click="zoomIn">Zoom In</button>
<button @click="zoomOut">Zoom Out</button>
<button @click="resetZoom">Reset</button>
</div>
<div class="rotation-controls">
<button @click="rotateCounterClockwise">↺ Rotate Left</button>
<button @click="rotateClockwise">↻ Rotate Right</button>
</div>
<div class="general-controls">
<button @click="resetAll">Reset All</button>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
imageUrl: '/path/to/image.jpg',
currentZoom: 1
};
},
methods: {
zoomIn() {
this.$refs.cropper.changeScale(0.1);
this.currentZoom += 0.1;
},
zoomOut() {
this.$refs.cropper.changeScale(-0.1);
this.currentZoom = Math.max(0.1, this.currentZoom - 0.1);
},
resetZoom() {
// Reset to original scale
const resetAmount = 1 - this.currentZoom;
this.$refs.cropper.changeScale(resetAmount);
this.currentZoom = 1;
},
rotateCounterClockwise() {
this.$refs.cropper.rotateLeft();
this.rotationAngle = (this.rotationAngle - 90) % 360;
},
rotateClockwise() {
this.$refs.cropper.rotateRight();
this.rotationAngle = (this.rotationAngle + 90) % 360;
},
resetAll() {
this.$refs.cropper.refresh();
this.currentZoom = 1;
this.rotationAngle = 0;
},
resetRotation() {
this.$refs.cropper.rotateClear();
this.rotationAngle = 0;
},
setCropSize() {
// Set crop box to specific dimensions
this.$refs.cropper.changeCrop(300, 200);
}
}
};
</script>Methods for retrieving the cropped image data in different formats.
/**
* Get cropped image as base64 data URL
* @param callback - Function called with base64 string result
*/
getCropData(callback: (base64: string) => void): void;
/**
* Get cropped image as Blob object
* @param callback - Function called with Blob result
*/
getCropBlob(callback: (blob: Blob) => void): void;Usage Examples:
<template>
<div class="export-interface">
<VueCropper ref="cropper" :img="imageUrl" />
<div class="export-controls">
<button @click="downloadImage">Download Image</button>
<button @click="uploadToServer">Upload to Server</button>
<button @click="showPreview">Show Preview</button>
</div>
<div v-if="previewUrl" class="preview-result">
<h3>Cropped Result:</h3>
<img :src="previewUrl" alt="Cropped image" />
</div>
</div>
</template>
<script>
export default {
data() {
return {
imageUrl: '/path/to/image.jpg',
previewUrl: null
};
},
methods: {
downloadImage() {
this.$refs.cropper.getCropData((data) => {
// Create download link
const link = document.createElement('a');
link.href = data;
link.download = 'cropped-image.jpg';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
},
async uploadToServer() {
this.$refs.cropper.getCropBlob(async (blob) => {
const formData = new FormData();
formData.append('image', blob, 'cropped-image.jpg');
try {
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
if (response.ok) {
const result = await response.json();
console.log('Upload successful:', result);
this.$emit('upload-success', result);
} else {
throw new Error('Upload failed');
}
} catch (error) {
console.error('Upload error:', error);
this.$emit('upload-error', error);
}
});
},
showPreview() {
this.$refs.cropper.getCropData((data) => {
this.previewUrl = data;
});
}
}
};
</script>Methods for retrieving coordinate and dimension information.
/**
* Get image position relative to container
* @param x - Optional x coordinate parameter
* @param y - Optional y coordinate parameter
* @param scale - Optional scale parameter
* @returns Axis coordinates of the image
*/
getImgAxis(x?: number, y?: number, scale?: number): AxisData;
/**
* Get crop box position relative to container
* @returns Axis coordinates of the crop box
*/
getCropAxis(): AxisData;
interface AxisData {
x1: number; // top-left x coordinate
x2: number; // bottom-right x coordinate
y1: number; // top-left y coordinate
y2: number; // bottom-right y coordinate
}Usage Examples:
<template>
<div class="coordinate-inspector">
<VueCropper ref="cropper" :img="imageUrl" />
<div class="info-panel">
<button @click="updateCoordinates">Update Coordinates</button>
<div class="coordinates-display">
<h4>Image Coordinates:</h4>
<p>Top-left: ({{ imageCoords.x1 }}, {{ imageCoords.y1 }})</p>
<p>Bottom-right: ({{ imageCoords.x2 }}, {{ imageCoords.y2 }})</p>
<h4>Crop Box Coordinates:</h4>
<p>Top-left: ({{ cropCoords.x1 }}, {{ cropCoords.y1 }})</p>
<p>Bottom-right: ({{ cropCoords.x2 }}, {{ cropCoords.y2 }})</p>
<h4>Crop Dimensions:</h4>
<p>Width: {{ cropCoords.x2 - cropCoords.x1 }}px</p>
<p>Height: {{ cropCoords.y2 - cropCoords.y1 }}px</p>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
imageUrl: '/path/to/image.jpg',
imageCoords: { x1: 0, y1: 0, x2: 0, y2: 0 },
cropCoords: { x1: 0, y1: 0, x2: 0, y2: 0 }
};
},
methods: {
updateCoordinates() {
this.imageCoords = this.$refs.cropper.getImgAxis();
this.cropCoords = this.$refs.cropper.getCropAxis();
// Calculate additional metrics
const cropWidth = this.cropCoords.x2 - this.cropCoords.x1;
const cropHeight = this.cropCoords.y2 - this.cropCoords.y1;
const cropArea = cropWidth * cropHeight;
console.log('Crop area:', cropArea, 'pixels');
// Validate crop position
this.validateCropPosition();
},
validateCropPosition() {
const imgBounds = this.imageCoords;
const cropBounds = this.cropCoords;
const isWithinBounds =
cropBounds.x1 >= imgBounds.x1 &&
cropBounds.y1 >= imgBounds.y1 &&
cropBounds.x2 <= imgBounds.x2 &&
cropBounds.y2 <= imgBounds.y2;
if (!isWithinBounds) {
console.warn('Crop box extends beyond image boundaries');
}
}
}
};
</script>Read-only properties accessible via component reference.
/**
* Current crop box width in pixels
*/
readonly cropW: number;
/**
* Current crop box height in pixels
*/
readonly cropH: number;Usage Examples:
<template>
<div class="dimension-monitor">
<VueCropper ref="cropper" :img="imageUrl" />
<div class="live-dimensions">
<p>Live Crop Dimensions:</p>
<p>Width: {{ liveDimensions.width }}px</p>
<p>Height: {{ liveDimensions.height }}px</p>
<p>Aspect Ratio: {{ aspectRatio }}</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
imageUrl: '/path/to/image.jpg',
liveDimensions: { width: 0, height: 0 }
};
},
computed: {
aspectRatio() {
const { width, height } = this.liveDimensions;
if (height === 0) return 0;
return (width / height).toFixed(2);
}
},
mounted() {
// Poll for dimension changes
this.dimensionInterval = setInterval(() => {
if (this.$refs.cropper) {
this.liveDimensions = {
width: this.$refs.cropper.cropW || 0,
height: this.$refs.cropper.cropH || 0
};
}
}, 100);
},
beforeUnmount() {
if (this.dimensionInterval) {
clearInterval(this.dimensionInterval);
}
}
};
</script>Install with Tessl CLI
npx tessl i tessl/npm-vue-cropper