canvas画布,手写电子签名,vue3+setup语法糖

6 篇文章 0 订阅
18 篇文章 0 订阅
<template>
	<div id="app">
		<div class="area">
			<canvas style="width: 100vw;height:200px;border:1px solid #ccc;" ref="canvas" @touchstart="touchStart"
				@touchmove="touchMove" @touchend="touchEnd">
			</canvas>
			<!-- <canvas ref="canvas"
            @mousedown="mouseDown"
            @mousemove="mouseMove"
            @mouseup="mouseUp">
    </canvas> -->
		</div>
		<button class="btn" @click="preview">预览</button>
		<button class="btn" @click="revert">撤销</button>
		<button class="btn" @click="clear">清空</button>
		<button class="btn" @click="save">保存</button>
		<button class="btn" @click="clip">裁剪</button>
		<div class="preview">
			<img src="" alt="">
		</div>
	</div>
</template>
  
<script setup>
import { onMounted, reactive, ref } from 'vue';

const canvas = ref(null)
const that = reactive({
	canvasRect: null, // 宽高clientRect数据
	ctx: null,  // 画笔对象
	startX: 0,
	startY: 0,
	endX: 0,
	endY: 0,
    lineWidth: 3,
	lineColor: '#000',
	isCrop: true, // 剪裁
	storageSteps: [], // 记录每步操作
	isDrawing: false, // 是否正在绘制
	isEmpty: true, // 画板是否为空
})
onMounted(() => {
	console.log('asas')
	init()
	// 在画板以外松开鼠标后冻结画笔
	document.onmouseup = () => {
		that.isDrawing = false
	}
})
const init = () => {
	const canvass = canvas.value;
	that.canvasRect = canvass.getBoundingClientRect();
	console.log('init', that.canvasRect)
	canvass.width = that.canvasRect.width;
	canvass.height = that.canvasRect.height;
	that.ctx = canvass.getContext('2d')
}
const touchStart = (e) => {
	e.preventDefault();
	that.startX = e.targetTouches[0].clientX - that.canvasRect.left;
	that.startY = e.targetTouches[0].clientY - that.canvasRect.top;
	that.endX = that.startX;
	that.endY = that.startY;
	draw();
}
const touchMove = (e) => {
	e.preventDefault();
	that.endX = e.targetTouches[0].clientX - that.canvasRect.left;
	that.endY = e.targetTouches[0].clientY - that.canvasRect.top;
	draw()
	that.startX = that.endX;
	that.startY = that.endY;
}
const touchEnd = (e) => {
	e.preventDefault();
	that.endX = e.changedTouches[0].clientX - that.canvasRect.left;
	that.endY = e.changedTouches[0].clientY - that.canvasRect.top;
	let imgData = that.ctx.getImageData(0, 0, that.canvasRect.width, that.canvasRect.height)
	console.log(imgData)
	that.storageSteps.push(imgData)
}
// 绘制
const draw = () => {
	that.ctx.beginPath();
	that.ctx.moveTo(that.startX, that.startY);
	that.ctx.lineTo(that.endX, that.endY);
	that.ctx.lineCap = 'round';
	that.ctx.lineJoin = 'round';
	that.ctx.lineWidth = that.lineWidth;
	that.ctx.strokeStyle = that.lineColor;
	that.ctx.stroke();
	that.ctx.closePath();
	that.isEmpty = false;
}

// 清空
const clear = () => {
	that.ctx.clearRect(0, 0, that.canvasRect.width, that.canvasRect.height);
	that.storageSteps = [];  // 清空清楚步骤记录
	that.isEmpty = true;  // 清空标记
}
// touched事件
const touchEnds = (e) => {
	e.preventDefault();
	that.endX = e.changedTouches[0].clientX - that.canvasRect.left;
	that.endY = e.changedTouches[0].clientY - that.canvasRect.top;
	let imgData = that.ctx.getImageData(0, 0, that.canvasRect.width, that.canvasRect.height) // 绘制结束记录当前画布信息
	console.log(imgData)
	that.storageSteps.push(imgData)
}

// 撤销
const revert = () => {
	that.storageSteps.pop()
	const len = that.storageSteps.length;
	if (len) {
		that.ctx.putImageData(that.storageSteps[len - 1], 0, 0);
	} else {
		clear()
	}
}
// 预览
const preview = () => {
	const base64 = canvas.value.toDataURL('image/png');
	console.log(base64)
	const img = document.querySelector('.preview img');
	img.src = base64;
	img.width = that.canvasRect.width;
	img.height = that.canvasRect.height;
}

// 保存
const save = () => {
	if (that.isEmpty) {
		console.log('画布为空!')
		return
	}
	const name = prompt('请输入名称', 'canvas签名');
	if (name && name.trim()) {
		const a = document.createElement('a');
		a.download = name;
		a.href = this.$refs.canvas.toDataURL('image/png');
		a.dispatchEvent(new MouseEvent('click'));
	}
}
</script>

适用于移动端

pc端使用只需要修改html中事件名即可

  • 1
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

502胶水205

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值