|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- <template>
- <view class="container">
- <button @click="chooseImage">选择图片</button>
- <view class="canvas-container" v-if="imagePath">
- <canvas canvas-id="imageCanvas"
- :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"></canvas>
- <view :class="[
- 'crop-area',
- cropShape === 'circle' ? 'circle' : 'rectangle'
- ]" :style="{
- left: cropX + 'px',
- top: cropY + 'px',
- width: cropWidth + 'px',
- height: cropHeight + 'px'
- }" @touchstart="startDrag" @touchmove="drag" @touchend="endDrag"></view>
- </view>
- <view class="button-group">
- <button @click="changeCropShape">切换裁剪形状</button>
- <button @click="resetCanvas">重置画布</button>
- <button @click="cropImage">裁剪图片</button>
- </view>
- </view>
- </template>
-
- <script>
- export default {
- data() {
- return {
- imagePath: '',
- canvasWidth: 300,
- canvasHeight: 300,
- cropX: 50,
- cropY: 50,
- cropWidth: 200,
- cropHeight: 200,
- cropShape: 'rectangle',
- isDragging: false,
- startX: 0,
- startY: 0
- };
- },
- methods: {
- chooseImage() {
- uni.chooseImage({
- count: 1,
- success: (res) => {
- this.imagePath = res.tempFilePaths[0];
- this.drawImageOnCanvas();
- }
- });
- },
- drawImageOnCanvas() {
- const ctx = uni.createCanvasContext('imageCanvas', this);
- ctx.drawImage(this.imagePath, 0, 0, this.canvasWidth, this.canvasHeight);
- ctx.draw();
- },
- startDrag(e) {
- this.isDragging = true;
- this.startX = e.touches[0].clientX;
- this.startY = e.touches[0].clientY;
- },
- drag(e) {
- if (this.isDragging) {
- const deltaX = e.touches[0].clientX - this.startX;
- const deltaY = e.touches[0].clientY - this.startY;
- let newX = this.cropX + deltaX;
- let newY = this.cropY + deltaY;
-
- // 限制裁剪区域不超出图片范围
- newX = Math.max(0, Math.min(newX, this.canvasWidth - this.cropWidth));
- newY = Math.max(0, Math.min(newY, this.canvasHeight - this.cropHeight));
-
- this.cropX = newX;
- this.cropY = newY;
- this.startX = e.touches[0].clientX;
- this.startY = e.touches[0].clientY;
- }
- },
- endDrag() {
- this.isDragging = false;
- },
- changeCropShape() {
- this.cropShape = this.cropShape === 'rectangle' ? 'circle' : 'rectangle';
- },
- resetCanvas() {
- this.cropX = 50;
- this.cropY = 50;
- this.cropWidth = 200;
- this.cropHeight = 200;
- this.cropShape = 'rectangle';
- this.drawImageOnCanvas();
- },
- cropImage() {
- if (this.cropShape === 'rectangle') {
- uni.canvasToTempFilePath({
- canvasId: 'imageCanvas',
- x: this.cropX,
- y: this.cropY,
- width: this.cropWidth,
- height: this.cropHeight,
- success: (res) => {
- console.log('裁剪后的图片路径:', res.tempFilePath);
- uni.previewImage({
- urls: [res.tempFilePath]
- });
- },
- fail: (err) => {
- console.error('裁剪失败:', err);
- }
- }, this);
- } else {
- const ctx = uni.createCanvasContext('imageCanvas', this);
- const centerX = this.cropX + this.cropWidth / 2;
- const centerY = this.cropY + this.cropHeight / 2;
- const radius = Math.min(this.cropWidth, this.cropHeight) / 2;
-
- ctx.save();
- ctx.beginPath();
- ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
- ctx.clip();
- ctx.drawImage(this.imagePath, 0, 0, this.canvasWidth, this.canvasHeight);
- ctx.restore();
-
- ctx.draw(false, () => {
- uni.canvasToTempFilePath({
- canvasId: 'imageCanvas',
- x: centerX - radius,
- y: centerY - radius,
- width: 2 * radius,
- height: 2 * radius,
- success: (res) => {
- console.log('裁剪后的图片路径:', res.tempFilePath);
- uni.previewImage({
- urls: [res.tempFilePath]
- });
- },
- fail: (err) => {
- console.error('裁剪失败:', err);
- }
- }, this);
- });
- }
- }
- }
- };
- </script>
-
- <style scoped>
- .container {
- padding: 20px;
- }
-
- .canvas-container {
- position: relative;
- margin-top: 20px;
- }
-
- .crop-area {
- position: absolute;
- border: 2px dashed blue;
- box-sizing: border-box;
- }
-
- .circle {
- border-radius: 50%;
- }
-
- .button-group {
- margin-top: 20px;
- display: flex;
- justify-content: space-around;
- }
- </style>
|