首先,我们需要两张画布,一个展示选取图片的压缩图,一个展示截取后的图片(样式部分不做讲解)。代码如下:
<template>
<div>
<div>
<canvas>
您的浏览器不支持canvas,请升级最新版本
</canvas>
<p class="img-scale">
图片压缩:
<span></span>
</p>
<div>
<button type="button">Min</button>
<button type="button">-</button>
<button type="button">+</button>
<button type="button">Max</button>
</div>
<div>
选择图片
<input type="file">
</div>
</div>
<div>
<canvas>
您的浏览器不支持canvas,请升级最新版本
</canvas>
<p>
截图长度:
<span></span>
</p>
<button type="button">上传头像</button>
</div>
</div>
</template>
如图所示为初始效果,我们需要先隐藏第二张画布,以及调整图片的按钮组:
利用v-if指令,当图片选取成功(hasImgSrc = true)后,显示第二个画布,以及按钮,代码如下:
<template>
...
<div v-if="hasImgSrc">
<button type="button">Min</button>
<button type="button">-</button>
<button type="button">+</button>
<button type="button">Max</button>
</div>
...
<div v-show="hasImgSrc">
<canvas>
您的浏览器不支持canvas,请升级最新版本
</canvas>
<p>
截图长度:
<span></span>
</p>
<button type="button">上传头像</button>
</div>
...
</template>
这里选用 v-if 是因为选取图片时,不会频繁的切换,而隐藏第二个画布用 v-show 是因为 v-if 为 false 的时候会将Dom节点从文档流移除,而画布需要在mounted的时候进行初始化(若不在此初始化也可使用 v-if)。
接下来,我们需要画出默认图片(如上图所示),代码如下:
data () {
return {
originalCanvas: null, // 原图 画布
originalCtx: null, // 原图 上下文
originalImg: null, // 原图片的对象
cutCanvas: null, // 显示裁剪后图片的画布
cutCtx: null, // 裁图 画布 上下文
cutImg: null, // 裁剪后 图片的对象
originalCanvasWidth: 0, // 原图 压缩后 宽度
originalCanvasHeight: 0, // 原图 压缩后 高度
scaleSize: 300, // 原图压缩的尺寸
cutSize: 200, // 裁剪 正方形的宽高
hasImgSrc: false, // 是否有可裁剪图片
}
},
mounted () {
// 初始化 原图的画布
let originalCanvas = this.originalCanvas = this.$refs.originalCanvas
let originalCtx = this.originalCtx = originalCanvas.getContext('2d')
// 初始化 裁图 画布
let cutCanvas = this.cutCanvas = this.$refs.cutCanvas
this.cutCtx = cutCanvas.getContext('2d')
// 设置画布宽高
originalCanvas.width = this.originalCanvasWidth = this.scaleSize
originalCanvas.height = this.originalCanvasHeight = this.scaleSize
cutCanvas.width = this.cutSize
cutCanvas.height = this.cutSize
// 绘制默认图片
if (originalCanvas.getContext) {
let originalImg = this.originalImg = new Image()
originalImg.src &