<template>
<div class="signature" @touchmove.prevent>
<div class="boardBox" ref="boardBox">
<canvas ref="board" id="canvas" @touchstart="mStart" @touchmove="mMove" @touchend="mEnd"></canvas>
</div>
<div class="bar" ref="barrie">
<div class="item" @click="goback">
<div class="ico">
</div>
<!-- <div class="text">取消</div> -->
<van-button style="width: 80px;" type="default">取消</van-button>
</div>
<div class="item" @click="clearCanvas">
<div class="ico">
</div>
<van-button style="width: 80px;" type="warning">重绘</van-button>
</div>
<div class="item" @click="getcanvas">
<div class="ico">
</div>
<van-button style="width: 80px;" type="primary">保存</van-button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {onMounted, reactive, ref} from "vue";
import {uploadFileApi} from "@/api/PublicApi";
import {base64toFile} from "@/utils/common";
const baseData = ref("")
const ctx = ref<any>(null)
const point = reactive({
x: 0,
y: 0
})
const moving = ref(false)
const mubHeight = ref(0)
const board = ref(); // 获取DOM
const boardBox = ref();
const barrie = ref()
/*初始化*/
onMounted(() => {
board.value.width = boardBox.value.offsetWidth; // 设置画布宽
board.value.height = boardBox.value.offsetHeight; // 设置画布高
ctx.value = board.value.getContext("2d"); // 二维绘图
ctx.value.strokeStyle = "#000"; // 颜色
ctx.value.lineWidth = 3; // 线条宽度
mubHeight.value = document.body.clientHeight - (boardBox.value.offsetHeight + barrie.value.offsetHeight)
})
// 滑动开始
const mStart = (e: any) => {
const x = e.touches[0].clientX - e.target.offsetLeft
const y = e.touches[0].clientY - mubHeight.value // 获取触摸点在画板(canvas)的坐标
// console.log(x, 555);
// console.log(y, 555);
point.x = x;
point.y = y;
ctx.value.beginPath();
moving.value = true;
}
// 滑动
const mMove = (e: any) => {
if (moving.value) {
mubHeight.value
const x = e.touches[0].clientX - e.target.offsetLeft
const y = e.touches[0].clientY - mubHeight.value; // 获取触摸点在画板(canvas)的坐标
ctx.value.moveTo(point.x, point.y); // 把路径移动到画布中的指定点,不创建线条(起始点)
ctx.value.lineTo(x, y); // 添加一个新点,然后创建从该点到画布中最后指定点的线条,不创建线条
ctx.value.stroke(); // 绘制
point.x = x;
point.y = y; // 重置点坐标为上一个坐标
}
}
// 滑动结束
const mEnd = () => {
if (moving.value) {
ctx.value.closePath(); // 停止绘制
moving.value = false; // 关闭绘制开关
}
}
// 保存
const getcanvas = () => {
//绘画转图片
const d = document.getElementById("canvas") as any
d.toDataURL("image/png");
d.toBlob(async (blobObj: any) => {
const file1 = new File([blobObj], "pic.png", {
type: blobObj.type,
lastModified: Date.now(),
});
convertImg(file1);
});
}
//旋转图片
const convertImg = (file: any) => {
var canvas1 = document.createElement("canvas");
var context1 = canvas1.getContext("2d") as any
var oReader = new FileReader();
oReader.readAsDataURL(file);
oReader.onload = function (e: any) {
var img = new Image() as any
img.src = e.target.result;
img.onload = function () {
// 图片原始尺寸
var originWidth = this.width;
var originHeight = this.height;
// 最大尺寸限制
var maxWidth = 1080,
maxHeight = 1080;
// 目标尺寸
var targetWidth = originWidth,
targetHeight = originHeight;
// 图片尺寸超过300x300的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
targetWidth = maxWidth;
targetHeight = Math.round(
maxWidth * (originHeight / originWidth)
);
} else {
targetHeight = maxHeight;
targetWidth = Math.round(
maxHeight * (originWidth / originHeight)
);
}
}
const type = "image/jpeg";
// canvas对图片进行缩放
canvas1.width = targetHeight;
canvas1.height = targetWidth;
// 旋转90度
context1.translate(0, 0);
context1.rotate(Math.PI / 2);
// (0,-imgHeight) 从旋转原理图那里获得的起始点
// context.clearRect(0, -targetHeight, targetWidth, targetHeight);
context1.drawImage(img, 0, -targetHeight, targetWidth, targetHeight);
// 将canvas的透明背景设置成白色
var imageData = context1.getImageData(
0,
0,
canvas1.width,
canvas1.height
);
for (var i = 0; i < imageData.data.length; i += 4) {
// 当该像素是透明的,则设置成白色
if (imageData.data[i + 3] == 0) {
imageData.data[i] = 255;
imageData.data[i + 1] = 255;
imageData.data[i + 2] = 255;
imageData.data[i + 3] = 255;
}
}
context1.putImageData(imageData, 0, 0);
const dataurl = canvas1.toDataURL(type);
baseData.value = dataurl;
let newFile = base64toFile(dataurl, "lll.png")
let param = new FormData()
param.append('file', newFile)
uploadFileApi(param).then((res: any) => {
console.log()
})
};
};
}
//清除画布
function clearCanvas() {
var c = document.getElementById("canvas") as any;
c.height = c.height;
ctx.value.lineWidth = 3;
}
//返回上一级
function goback() {
// router.go(-1)
}
</script>
<style scoped lang="scss">
.loadingtext {
transform: rotate(-90deg);
color: red;
}
// .item {
// -webkit-transform: rotate(-90deg);
// }
.text {
text-align: center;
}
.boardBox {
width: 100vw;
height: 90vh;
background: #f9f9f9;
}
.bar {
box-sizing: border-box;
padding: 0rem 1rem;
display: flex;
width: 100vw;
height: 10vh;
background-color: #ffffff;
justify-content: space-around;
align-items: center;
}
.shade {
width: 100vw;
height: 50vh;
position: fixed;
top: 0;
background-color: #333333;
z-index: 66666;
opacity: 0.9;
.minishade {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>
vue3.2 setup语法糖实现手写签名
猜你喜欢
转载自blog.csdn.net/weixin_42078172/article/details/128497663
今日推荐
周排行