canvas画点、线

效果图如下:

<template><canvas ref="canvas" class="canvas" width="800" height="600"></canvas><hr /><button id="boldBtn" type="button" ref="boldBtn" @click="boldBtn_click">粗线条</button><button id="thinBtn" type="button" ref="thinBtn" @click="thinBtn_click">细线条</button><button id="saveBtn" type="button" ref="saveBtn" @click="saveBtn_click">保存签名</button><inputtype="color"name=""id="color"value=""ref="color"@input="colorChnage"/><button id="clearBtn" ref="clearBtn" @click="clearBtn_click">橡皮擦</button><button id="nullBtn" ref="nullBtn" @click="nullBtn_click">清空画布</button>
</template><script setup lang="ts">
import { ref, onMounted, reactive, Ref } from 'vue'
//1.获取画布和上下文对象
const canvas = ref<HTMLCanvasElement | null>(null)
let ctx = reactive<any>(null)
//2.获取输入框和按钮
//设置画笔的粗细:粗
const boldBtn = ref()
//设置画笔的粗细:细
const thinBtn = ref()
//保存签名
const saveBtn = ref()
//签名颜色选择
const color = ref()
//橡皮擦按钮
const clearBtn = ref()
//清空画布
const nullBtn = ref()
//设置允许绘制的变量
let isDraw = falseconst initContext = () => {if (canvas.value?.getContext) {ctx = canvas.value.getContext('2d')//画笔线条圆润ctx.lineJoin = 'round'ctx.lineCap = 'round'}
}const mouseListner = () => {//获取鼠标落下点的位置,将画笔移动到该处canvas.value!.onmousedown = (e) => {isDraw = truectx.beginPath()let x = e.pageX - canvas.value!.offsetLeftlet y = e.pageY - canvas.value!.offsetTopctx.moveTo(x, y)//console.log(x, y)}canvas.value!.onmousemove = (e) => {if (isDraw) {let x = e.pageX - canvas.value!.offsetLeftlet y = e.pageY - canvas.value!.offsetTopctx.lineTo(x, y)ctx.stroke()}}//鼠标离开画布结束绘画canvas.value!.onmouseleave = () => {isDraw = falsectx.closePath()}//鼠标弹起结束绘画canvas.value!.onmouseup = () => {isDraw = falsectx.closePath()}
}const boldBtn_click = () => {ctx.globalCompositeOperation = 'source-over'ctx.lineWidth = 20addClassStyle(boldBtn.value)
}const thinBtn_click = () => {ctx.globalCompositeOperation = 'source-over'ctx.lineWidth = 2addClassStyle(thinBtn.value)
}const saveBtn_click = () => {let urlData: string | undefined = canvas.value!.toDataURL()// let image: HTMLImageElement | undefined = new Image()// image.src = urlData// document.body.appendChild(image)let downloadA = document.createElement('a')downloadA.setAttribute('download', '炫酷签名')downloadA.href = urlDatadownloadA.click()
}const clearBtn_click = () => {ctx.globalCompositeOperation = 'destination-out'ctx.lineWidth = 30addClassStyle(clearBtn.value)
}const nullBtn_click = () => {ctx.clearRect(0, 0, 800, 600)addClassStyle(nullBtn.value)
}const addClassStyle = (thisBtn: any) => {boldBtn.value.classList.remove('active')thinBtn.value.classList.remove('active')clearBtn.value.classList.remove('active')nullBtn.value.classList.remove('active')thisBtn.classList.add('active')
}const colorChnage = () => {//console.log(color.value.value)ctx.strokeStyle = color.value.value
}onMounted(() => {initContext()mouseListner()
})
</script><style lang="less" scoped>
.canvas {border: 1px solid black;z-index: 10;
}
button.active {color: #fff;background-color: orange;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/185719.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【自留地】后端 - PHP - MySQL - Nginx - Python - Java

PHP ThinkPHP6入门手册 【精选】【汇总】ThinkPHP6入门手册_tp6手册_Rudon滨海渔村的博客-CSDN博客文章浏览阅读5.4k次。安装安装Composer【win】https://getcomposer.org/Composer-Setup.exe【Linux & MacOS】curl -sS https://getcomposer.org/installer | phpmv compo…

MPN – 制造零件号

S/4 1610 中的 MPN – 基于 NAST 的输出管理 我试图查找有关 MPN 设置的信息&#xff0c;但找不到详细的配置步骤。在浏览了一些信息和 help.sap 链接后&#xff0c;我能够在 S/4 1610 系统中配置 MPN 设置&#xff0c;这与使用旧输出类型&#xff08;Nast 和输出类型 NEU&…

有能一键批量转换,轻松将PDF、图片转为Word/Excel的软件吗?

随着数字化时代的到来&#xff0c;OCR技术在我们的生活中变得越来越重要。无论是从图片中提取文字&#xff0c;还是将PDF、图片格式的文件转换为Word或Excel格式&#xff0c;OCR软件都能够为我们提供极大的便利。然而&#xff0c;市面上的OCR软件种类繁多&#xff0c;哪一款软件…

2023年咸阳市《网络建设与运维》赛题解析------四、安全配置

安全配置 说明:IP地址按照题目给定的顺序用“ip/mask”表示,IPv4 any地址用0.0.0.0/0,IPv6 any地址用::/0,禁止用地址条目,否则按零分处理。 1.FW1配置IPv4 nat,实现集团产品1段IPv4访问Internet IPv4,转换ip/mask为200.200.200.16/28,保证每一个源IP产生的所有会话将…

3.6 Windows驱动开发:内核进程汇编与反汇编

在笔者上一篇文章《内核MDL读写进程内存》简单介绍了如何通过MDL映射的方式实现进程读写操作&#xff0c;本章将通过如上案例实现远程进程反汇编功能&#xff0c;此类功能也是ARK工具中最常见的功能之一&#xff0c;通常此类功能的实现分为两部分&#xff0c;内核部分只负责读写…

kubernetes学习笔记-概念

参考&#xff1a;https://kubernetes.io/zh-cn/docs/concepts/overview/ 概述 Kubernetes 是一个可移植、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态&#xff0c;其服务、…

如何将图片转为excel或word?(客户端)

演示软件&#xff1a;金鸣表格文字识别大师3.6.1&#xff08;新版本界面可能会略有不同&#xff09; 第一部分 将图片转为excel或文表混合的word 一般的软件要将图片转为可编辑的excel&#xff0c;都需要待识别的图片要有明显清晰的表格线&#xff0c;但我们程序现已克服了这…

小白也想写综述(一)

前言 在选择科研方向时&#xff0c;考虑自己的兴趣和职业目标是非常重要的&#xff1a; 综述论文的价值&#xff1a;撰写综述论文&#xff0c;尤其是在深度强化学习和区块链这样的前沿技术领域&#xff0c;能够帮助建立扎实的理论基础&#xff0c;并且对整个领域有一个全面的认…

java绘制心形爱心

java绘制心形爱心 绘制java心形的核心就是实现&#xff1a;上代码&#xff1a;可以直接复制使用生成效果heart() 展示效果heart2() 展示效果 下面实现另一个需求&#xff1a;需求描述要生成二维码&#xff0c;就要引入依赖&#xff1a;上代码效果&#xff1a;这个就是包含刘亦菲…

【Linux】Ubuntu16.04下安装python高版本--源码安装

Ubuntu16.04下完美安装python高版本及对应版本的pip 方法一:直接用命令安装python3.6&#xff08;但我没安装成功&#xff09; 好像是因为Ubuntu16.04的软件仓库&#xff08;源&#xff09;中python的最高版本就是python3.5&#xff0c;所以无法直接用apt来安装 #方法一 sudo…

设计模式(5)-使用设计模式实现简易版springIoc

自定义简易版springIoc 1 spring使用回顾 自定义spring框架前&#xff0c;先回顾一下spring框架的使用&#xff0c;从而分析spring的核心&#xff0c;并对核心功能进行模拟。 数据访问层。定义UserDao接口及其子实现类 public interface UserDao {public void add(); }public…

微信聊天审计软件,微信聊天记录监管系统

微信聊天审计软件&#xff0c;微信聊天记录监管系统 微信聊天已经成为人们工作中不可或缺的一部分。它不仅改变了我们的沟通方式&#xff0c;还为我们的工作带来了诸多便利。但同时也带来了一些安全风险&#xff0c;如信息泄露、不当言论等&#xff0c;然而&#xff0c;微信聊…