目录
目录
一、原理
二、具体实现
(1)、创建画布
(2)、获取鼠标位置
(3)、创建线段类
(4)、创建主绘制类
(5)、绘制
(6)、效果图
三、源代码
1、原生js
2、vue3实现
一、原理
直线可以看成是一小段一小段的线段组成,并且两点确定一条直线;
首先当鼠标左键点击时候获取鼠标左键xy坐标,把当前获取得到的xy坐标赋值给线段起始点的坐标值,当鼠标移动后再获取新的鼠标位置x2和y2 再把获取得到到x2和y2赋值给线段的末尾点坐标值 ,之后两点连起来就是一段线段。之后再画一条线段,只要把前面那段线段的末尾点为起始点,再获取鼠标移动时候产生的新点,把两端相连就是一大段线段,如此重复。
canvas画线段:
ctx.beginPath();//创建绘制路径
ctx.moveTo(this.x,this.y);//第一个点
ctx.lineTo(this.x2,this.y2); //第二个点
ctx.strokeStyle="red" //设颜色
ctx.stroke(); //开始绘制(把前面点连接)
二、具体实现
如果不熟悉canvas标签的话可以看我上篇博客
(1)、创建画布
<canvas width="600" height="400" id="mycancas">
当前浏览器版本不支持,请升级
</canvas>
js获取画布
var canvas=document.getElementById("mycancas");
//得到画布的上下文,上下文有两个 2d和3d
//所有的图形绘制都是通过ctx属性或者方法进行设置的,和canvas标签没有关系了
var ctx=canvas.getContext("2d")
(2)、获取鼠标位置
创建鼠标工具类
//记录鼠标的状态
class MyMouseXy {
// 鼠标左键按下的坐标 也是画线段的开始坐标
static x;
static y;
//鼠标移动后的坐标 也是画线段的末端的坐标
static x2;
static y2;
//鼠标左键是否弹起
static ifmouseup=false;
}
通过cavan画布内的鼠标事件获取鼠标坐标,鼠标点击画布时候牵扯到绘画,放在了后面。
// 获取鼠标在画布移动的坐标
canvas.addEventListener("mousemove", function(XY){
MyMouseXy.x2=XY.offsetX;
MyMouseXy.y2=XY.offsetY;
})
//鼠标左键弹起时候
canvas.addEventListener("mouseup",function (XY){
//鼠标状态修改成弹起
console.log("鼠标弹起")
MyMouseXy.ifmouseup=true;
})
(3)、创建线段类
//创建线段类 多个线段对象相互连接就成为了点
class MyLine{
x2;
y2;
//构造方法 设置第一个点
constructor(x,y) {
this.x=x;
this.y=y;
}
//更新 设置第二点
LineUpdata=function (x,y){
this.x2=x;
this.y2=y;
}
//绘制
LineRraw=function (){
ctx.beginPath();
ctx.moveTo(this.x,this.y);//第一个点
ctx.lineTo(this.x2,this.y2); //点三个
ctx.strokeStyle="red" //设颜色
ctx.stroke(); //开始绘制(把前面点连接)
//这段线段绘制完成后 把当前线段的末尾点坐标赋值给下一段的起始点
MyMouseXy.x=this.x2;
MyMouseXy.y=this.y2;
}
}
(4)、创建主绘制类
为了结构更加工整 和可扩展性,我把绘制线段放到了一个类的方法中
//主绘制类,想要填加跟多的绘制图形 只需要添加方法 或者改变MyRraw.Rae的指向即可
class MyRraw{
//用于扩展绘制其他图形的 raew
static raew;
//绘制直线的方法Rae
static Rae =function () {
//通过监听器连续执行方法 把鼠标左键的点击时候的位置xy赋值给线段首点的坐标xy,再把鼠标移动后的点x2y2坐标赋值给线段末端点的坐标x2,y2 两点确定一条直线
this.raew = setInterval(() => {
//创建线段 把鼠标的点传入
let myline=new MyLine(MyMouseXy.x,MyMouseXy.y);
myline.LineUpdata(MyMouseXy.x2,MyMouseXy.y2);
//当鼠标左键弹起时候停止绘制
if(MyMouseXy.ifmouseup!=true) {
myline.LineRraw();
}
})
}
}
(5)、绘制
当鼠标点击时候调用主绘制类中的绘制方法执行绘制
//画布鼠标监听 按下 按下后绘制图形
canvas.addEventListener("mousedown",function (event){
MyMouseXy.ifmouseup=false;
//对于画线而言这是 鼠标按下时候获取
MyMouseXy.x=event.offsetX;
MyMouseXy.y=event.offsetY;
//调用主绘制类的绘制直线的方法,绘制不同的图形只需要 动态修改 MyRraw.Rae();方法即可
MyRraw.Rae();
})
(6)、效果图
三、源代码
1、原生js实现
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
canvas{
/* 设置画布边框 以及外边距*/
border: 1px solid;
margin: 100px 0 0 100px;
}
</style>
</head>
<body>
<canvas width="600" height="400" id="mycancas">
当前浏览器版本不支持,请升级
</canvas>
<button id="but1"> 清屏</button>
<script>
/**
* 如果想要实现图形变换操作
* 可以创建线段数组存储线段,对线段数组操作即可
* @type {HTMLElement}
*/
var canvas=document.getElementById("mycancas");
//得到画布的上下文,上下文有两个 2d和3d
//所有的图形绘制都是通过ctx属性或者方法进行设置的,和canvas标签没有关系了
var ctx=canvas.getContext("2d")
var but1=document.getElementById("but1");
//创建线段类 多个线段对象相互连接就成为了点
class MyLine{
x2;
y2;
//构造方法设置第一个点
constructor(x,y) {
this.x=x;
this.y=y;
}
//更新 设置第二给点
LineUpdata=function (x,y){
this.x2=x;
this.y2=y;
}
//绘制
LineRraw=function (){
ctx.beginPath();
ctx.moveTo(this.x,this.y);//第一个点
ctx.lineTo(this.x2,this.y2); //点三个
ctx.strokeStyle="red" //设颜色
ctx.stroke(); //开始绘制(把前面点连接)
//这段线段绘制完成后 把当前线段的末尾点坐标赋值给下一段的起始点
MyMouseXy.x=this.x2;
MyMouseXy.y=this.y2;
}
}
//记录鼠标的状态
class MyMouseXy {
// 鼠标左键按下的坐标 也是画线段的开始坐标
static x;
static y;
//鼠标移动后的坐标 也是画线段的末端的坐标
static x2;
static y2;
//鼠标左键是否弹起
static ifmouseup=false;
}
// 获取鼠标在画布移动的坐标
canvas.addEventListener("mousemove", function(XY){
MyMouseXy.x2=XY.offsetX;
MyMouseXy.y2=XY.offsetY;
})
//鼠标左键弹起时候
canvas.addEventListener("mouseup",function (XY){
//鼠标状态修改成谈起
console.log("鼠标弹起")
MyMouseXy.ifmouseup=true;
})
//主绘制类,想要填加跟多的绘制图形 只需要添加方法 或者改变MyRraw.Rae的指向即可
class MyRraw{
static raew;
//绘制直线的方法Rae
static Rae =function () {
//通过监听器连续执行方法 把鼠标左键的点击时候的位置xy赋值给线段首点的坐标xy,再把鼠标移动后的点x2y2坐标赋值给线段末端点的坐标x2,y2 两点确定一条直线
this.raew = setInterval(() => {
//创建线段 把鼠标的点传入
let myline=new MyLine(MyMouseXy.x,MyMouseXy.y);
myline.LineUpdata(MyMouseXy.x2,MyMouseXy.y2);
//当鼠标左键弹起时候停止绘制
if(MyMouseXy.ifmouseup!=true) {
myline.LineRraw();
}
})
}
}
//画布鼠标监听 按下 按下后绘制图形
canvas.addEventListener("mousedown",function (event){
MyMouseXy.ifmouseup=false;
//对于画线而言这是 鼠标按下时候获取
MyMouseXy.x=event.offsetX;
MyMouseXy.y=event.offsetY;
//调用主绘制类的绘制直线的方法,绘制不同的图形只需要 动态修改 MyRraw.Rae();方法即可
MyRraw.Rae();
})
//当 “清屏按钮被点击”
but1.onclick=function (){
console.log("被点击")
ctx.clearRect(0,0,canvas.width,canvas.height);
// ctx.clearRect(0,0,100,100);
}
</script>
</body>
</html>
2、vue3实现
<template>
<!-- 画布-->
<div class="Mydiv">
<canvas width="880" height="450" ref="canvas" @mousedown="MouDown" @mousemove="MouMove" @mouseup="isDraw=false" @mouseleave="isDraw=false">
浏览器版本过低,不支持canvas
</canvas>
</div>
<!-- <el-button type="danger" @click="clear">清除</el-button>-->
</template>
<script>
import {getCurrentInstance, onMounted, reactive,ref} from 'vue'
export default {
name: "MyCanvas",
setup(){
//定义获取节点
const canvas=ref(null);
let ctx=ref(null);
//用于捕捉是否绘画
let isDraw=ref(false);
//存储绘画线段的数据
//点
let pointes=reactive({
frst:{x:'',y:''}, //第一给点
allpointe:[],//全部
last:{x:'',y:''} //最后一个点
}
);
//线 //便于变形操作
let Lines=reactive([]);
//鼠标按下
function MouDown(mou) {
isDraw.value=true;
let point={x:'',y:''};
//第一个点(画线)
point.x=mou.offsetX;
point.y=mou.offsetY;
//
pointes.frst.x=mou.offsetX;
pointes.frst.y=mou.offsetY;
pointes.allpointe.push(point);
// ctx.value.fillRect(point.x,point.y,100,100);
}
//鼠标移动 具体绘画函数,
function MouMove(mou) {
if(isDraw.value==true) {
let point = {x: '', y: ''};
//保存鼠标移动的点
point.x = mou.offsetX;
point.y = mou.offsetY;
//下一个点(画线)
pointes.last.x= mou.offsetX;
pointes.last.y= mou.offsetY;
//把点初始化
pointes.allpointe.push(point);
//画线
lineDraw();
}
}
//绘画
function lineDraw(){
ctx.value.beginPath();
ctx.value.moveTo(pointes.frst.x,pointes.frst.y);
ctx.value.lineTo(pointes.last.x,pointes.last.y)
ctx.value.strokeStyle='red';
ctx.value.stroke();
//绘制结束后把下一个点给初始点
pointes.frst.x=pointes.last.x;
pointes.frst.y=pointes.last.y;
}
//清屏
function clear(){
// /ctx.clearRect(x,y,w,h); // (擦除一个矩形范围)
ctx.value.clearRect(0,0,800,450);
}
//初始化方法
onMounted(()=>{
//获取页面canvas绘画版本
canvas.value=getCurrentInstance().refs.canvas;
//获得画笔
ctx.value=canvas.value.getContext("2d");
//获取DOM节点
console.log(canvas);
// lineDraw();
})
return{
pointes,
MouDown,
isDraw,
canvas,
ctx,
Lines,
MouMove,
lineDraw,
clear
}
}
}
</script>
<style scoped>
canvas{
border: 1px solid;
position: absolute;
top: 20px;
left: 20px;
}
.Mydiv{
width: 900px;
height: 500px;
border: 1px solid;
}
</style>
仅供学习交流,有错误请在评论区指出文章来源:https://www.toymoban.com/news/detail-522924.html
觉得有用还请点个赞^_^文章来源地址https://www.toymoban.com/news/detail-522924.html
到了这里,关于原生js使用canvas实现鼠标绘制直线的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!