赞
踩
啥也不说了直接上代码
- <template>
- <div>
- <div class="block-panel">
- <canvas ref="canvas" class="canvas" @mousedown="beginningDraw"
- @mouseup="endingDraw"@mouseleave="drawLeave" @mousemove="drawing"
- v-show="!isSaved"></canvas>
- <div class="picture" v-show="isSaved">
- <img :src="picture" alt="签名异常">
- </div>
- <div class="btns-box">
- <div style="text-align: center">
- <el-button type="plain" @click="canvasUndo">撤销</el-button>
- <el-button type="plain" @click="canvasRedo">反撤销</el-button>
- </div>
- <div style="text-align: center">
- <el-button type="primary" @click="canvasClear">清空</el-button>
- <el-button type="primary" @click="signAgain">重新签</el-button>
- <el-button type="primary" @click="saveAsImg">保存</el-button>
- </div>
- </div>
- </div>
- </div>
- </template>
- import axios from "axios"
- export default {
- data(){
- return{
- // 图片路径
- picture: '',
- // 画布
- emptyCanvas: '',
- // 画布操作记录
- step: -1,
- canvas: '',
- // 画布操作历史
- canvasHistory: [],
- // 画布参数
- obj: {},
- // 是否已保存生成图片
- isSaved: false
- }
- },
- mounted(){
- this.init()
- this.canvasInit()
- },
- methods: {
- /**
- * 初始化画布数据
- */
- init(){
- this.canvas = this.$refs.canvas
- this.obj = {
- canvas: this.canvas,
- context: this.canvas.getContext("2d"),
- isWrite: false, //是否开始
- lastWriteTime: -1,
- lastWriteSpeed: 0,
- lastWriteWidth: 0,
- canvasWidth: 800, // canvas宽
- canvasHeight: 400, // canvase高
- bgColor: '#fff', // 背景色
- borderWidth: 2, // 网格线宽度
- borderColor: "#fff", //网格颜色
- lastPoint: {}, //
- writeWidth: 2, //基础轨迹宽度
- maxWriteWidth: 30, // 写字模式最大线宽
- minWriteWidth: 1, // 写字模式最小线宽
- writeColor: '#000', // 轨迹颜色
- isWriteName: true // 签名模式
- }
- },
- /**
- * 设置画布线条宽度
- */
- setLineWidth(){
- let nowTime = new Date().getTime();
- let diffTime = nowTime - this.obj.lastWriteTime;
- this.obj.lastWriteTime = nowTime;
- let returnNum = this.obj.minWriteWidth + (this.obj.maxWriteWidth - this.obj.minWriteWidth) * diffTime / 30;
- if(returnNum < this.obj.minWriteWidth) {
- returnNum = this.obj.minWriteWidth;
- } else if(returnNum > this.obj.maxWriteWidth) {
- returnNum = this.obj.maxWriteWidth;
- }
-
- returnNum = returnNum.toFixed(2);
- //写字模式和签名模式
- if(this.obj.isWriteName){
- this.obj.context.lineWidth = this.obj.writeWidth;
- }else{
- this.obj.context.lineWidth = this.obj.lastWriteWidth = this.obj.lastWriteWidth / 4 * 3 + returnNum / 4;
- }
- },
- /**
- * 画布中书写
- */
- writing(point){
- this.obj.context.beginPath();
- this.obj.context.moveTo(this.obj.lastPoint.x, this.obj.lastPoint.y);
- this.obj.context.lineTo(point.x, point.y);
- this.setLineWidth();
- this.obj.context.stroke();
- this.obj.lastPoint = point;
- this.obj.context.closePath();
- },
- /**
- * 书写样式
- */
- writeContextStyle() {
- this.obj.context.beginPath();
- this.obj.context.strokeStyle = this.obj.writeColor;
- this.obj.context.lineCap = 'round';
- this.obj.context.lineJoin = "round";
- },
- /**
- * 开始书写
- */
- writeBegin(point) {
- this.obj.isWrite = true;
- this.obj.lastWriteTime = new Date().getTime();
- this.obj.lastPoint = point;
- this.writeContextStyle();
- },
- /**
- * 结束书写
- */
- writeEnd(type = 0) {
- //新增记录
- if (type == 1) {
- this.step++;
- if (this.step < this.canvasHistory.length) {
- this.canvasHistory.length = this.step; // 截断数组
- }
- this.canvasHistory.push(this.canvas.toDataURL("image/png")); // 添加新的绘制到历史记录
- console.log(this.step);
- }
- //end
- this.obj.isWrite = false;
- },
- /**
- * 清空画板
- */
- canvasClear() {
- this.obj.context.strokeStyle = '#fff';
- this.obj.context.clearRect(0, 0, this.obj.canvasWidth, this.obj.canvasHeight);
- this.step = -1
- this.canvasHistory = []
- if(!this.obj.isWriteName) {
- this.obj.context.beginPath();
- var size = this.obj.borderWidth / 2;
- //画外面的框
- this.obj.context.moveTo(size, size);
- this.obj.context.lineTo(this.obj.canvasWidth - size, size);
- this.obj.context.lineTo(this.obj.canvasWidth - size, this.obj.canvasHeight - size);
- this.obj.context.lineTo(size, this.obj.canvasHeight - size);
- this.obj.context.closePath();
- this.obj.context.lineWidth = this.obj.borderWidth;
- this.obj.context.strokeStyle = this.obj.borderColor;
- this.obj.context.stroke();
- //画里面的框
- this.obj.context.moveTo(0, 0);
- this.obj.context.lineTo(this.obj.canvasWidth, this.obj.canvasHeight);
- this.obj.context.lineTo(this.obj.canvasWidth, this.obj.canvasHeight / 2);
- this.obj.context.lineTo(this.obj.canvasWidth, this.obj.canvasHeight / 2);
- this.obj.context.lineTo(0, this.obj.canvasHeight / 2);
- this.obj.context.lineTo(0, this.obj.canvasHeight);
- this.obj.context.lineTo(this.obj.canvasWidth, 0);
- this.obj.context.lineTo(this.obj.canvasWidth / 2, 0);
- this.obj.context.lineTo(this.obj.canvasWidth / 2, this.obj.canvasHeight);
- this.obj.context.stroke();
- }
- },
- /**
- * 保存图片 格式base64
- */
- saveAsImg() {
- // 将cavase生成base64文件
- let imageSrc = this.canvas.toDataURL("image/png");
- if(imageSrc == this.emptyCanvas) {
- alert('请先书写')
- } else {
- this.isSaved = true
- // console.log('提交的内容===>', imageSrc)
- // 将base64转成file格式
- let blob = this.dataURLtoBlob(imageSrc);
- let file = this.blobToFile(blob, "imgName");
- // 将blob图片转化路径图片
- this.picture = window.URL.createObjectURL(file)
- console.log('this.picture', this.picture)
- let formData = new FormData()
- formData.append('file', this.picture)
- axios({
- method: 'post',
- url: '/user/12345',
- data: formData
- })
- }
- },
- /**
- * 初始化画布并备份
- */
- canvasInit() {
- this.canvas.width = this.obj.canvasWidth;
- this.canvas.height = this.obj.canvasHeight;
- this.emptyCanvas = this.canvas.toDataURL("image/png");
- },
- /**
- * 撤销
- */
- canvasUndo() {
- console.log(this.step)
- if (this.step >= 0) {
- this.step--;
- this.obj.context.clearRect(0, 0, this.obj.canvasWidth, this.obj.canvasHeight);
- if (this.step < 0) {
- return false
- }
- let canvasPic = new Image();
- canvasPic.src = this.canvasHistory[this.step];
- canvasPic.addEventListener('load', () => {
- this.obj.context.drawImage(canvasPic, 0, 0);
- });
- } else {
- console.log('不能再继续撤销了');
- }
- },
- /**
- * 反撤销
- */
- canvasRedo() {
- if (this.step < this.canvasHistory.length - 1) {
- this.step++;
- let canvasPic = new Image();
- canvasPic.src = this.canvasHistory[this.step];
- canvasPic.addEventListener('load', () => {
- this.obj.context.clearRect(0, 0, this.obj.canvasWidth, this.obj.canvasHeight);
- this.obj.context.drawImage(canvasPic, 0, 0);
- });
- } else {
- console.log('已经是最新的记录了');
- }
- },
- setWidth(){
- //宽度铺满
- width = document.body.clientWidth;
- console.log(width);
- this.obj.canvasWidth =width;
-
- },
- beginningDraw(e){
- let point = {
- x: e.offsetX || e.clientX,
- y: e.offsetY || e.clientY
- };
- this.writeBegin(point);
- },
- endingDraw(e){
- let point = {
- x: e.offsetX,
- y: e.offsetY
- };
- this.writeEnd(1);
- },
- drawLeave(e){
- let point = {
- x: e.offsetX,
- y: e.offsetY
- };
- this.writeEnd();
- },
- drawing(e){
- if(this.obj.isWrite) {
- let point = {
- x: e.offsetX,
- y: e.offsetY
- };
- this.writing(point);
- }
- },
- signAgain(){
- this.isSaved = false
- this.picture = ''
- this.canvasClear()
- },
- dataURLtoBlob(dataurl){
- let arr = dataurl.split(','),
- mime = arr[0].match(/:(.*?);/)[1],
- bstr = atob(arr[1]),
- n = bstr.length,
- u8arr = new Uint8Array(n);
- while(n--) {
- u8arr[n] = bstr.charCodeAt(n);
- }
- return new Blob([u8arr], {
- type: mime
- });
- },
- blobToFile(theBlob, fileName) {
- theBlob.lastModifiedDate = new Date().toLocaleDateString();
- theBlob.name = fileName;
- return theBlob;
- }
- }
- }
- .block-panel {
- display: flex;
- align-items: center;
- justify-content: space-between;
- &>.canvas {
- border: 1px solid #303133;
- }
- &>.picture{
- width: 800px;
- height: 400px;
- }
- &>.btns-box {
- padding-right: 20px;
- &>div{
- margin-bottom: 10px;
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。