前端基于canvas通过touch事件来绘制箭头的方法

2 篇文章 0 订阅

基于canvas通过touch事件来画箭头的方法

**

注意:我用的是touch事件,需要在f12中将切换为ipad才可以看到效果

**

目前在看到的一般只是直接生成出一个箭头,不是真正画笔画出它的效果,下方是使用touch事件完成的demo源码,当然如果您喜欢,也可以将它换成其他的事件来触发。

touch事件在windows网页中无效不知道怎么处理的朋友们,可以进入f12开发者工具中,点击下图圆圈位置,选择iPad查看
在这里插入图片描述

梳理思路:

画线的难度不高,我们的问题一般都纠结在箭头的画法

我们首先要知道箭头指向的方向与箭头头部展开大小的夹角进行运算

我们需要:起始点坐标,结束点坐标,箭头开叉的尾部两个点的坐标

整理完需求,我们先针对没使用过Math算过角度的兄台展示个简单的小例子

举个例子:

我们都知道坐标点(1,1)与(0,0)的夹角为45°

我们怎么通过js程序来得到它的角度?

我们可以通过公式

Math.atan2(y,x) 来得出弧度

而弧度转为角度的公式为:

Math.atan2(y, x) * 180 / Math.PI

不多逼逼,直接根据公式上代码:

	var x0=0;
	var y0=0;
	var x1=1;
	var y1=1;
	var res = Math.atan2(y1-y0,x1-x0)*180/Math.PI;
	console.log(res);//打印得到45°

由上可知我们拿到了角度为45°,此处需要注意的是,谁减谁不要搞错了,用结束位置减去起始位置得到的是我们想拿到的角度,如果上方变为(y0-y1,x0-x1),此处的结果为-135°

然而在js中,我们要拿到它夹角

角= 弧度 * Math.PI / 180

既然这样:

再假定我们的点为(0,0)和(1,0),可以知道角度为0,我们主要是想拿到它箭头开叉两边的尾部点的位置
在这里插入图片描述

假设箭头开叉的大小设定为30°,尝试着写一下逻辑:

//我们假设点为(0,0)和(1,0)
var fromX = 0;
var fromY = 0;
var toX = 1;
var toY = 0;
var color = "#f00";
function drawAngle(ctx,fromX,fromY,toX,toY){
   var arrow1_x, arrow1_y, arrow2_x, arrow2_y; //定义箭头开叉的尾部两个点的坐标
    var customAngle = 30; //箭头开叉的大小设定为30°
    var arrowLangth = 20; //箭头长度为20
    var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI; //拿到起始点与结束点的夹角,因为我们用起始点减去结束点的坐标,所以目前为180°,为什么用180°不用0°呢,因为在下方的arrow1_x部分如果是0°的话,需要有减法运算,这样的话,反方向画线的时候会有问题,所以都使用加法,这个了解一下就可以了,如果不理解,建议使用0°试一下,如果改成0°的话,下方arrow1_x和arrow2_x的赋值过程中需要把后面toX+X变为toX-X
    var angle1 = angle + customAngle; //箭头上方的线与中间直线的角度
    var angle2 = angle - customAngle; //箭头下方的线与中间直线的角度
    //JS中sin和cos的参数都为弧度,不要直接把角度传进去
    var X1 = arrowLangth * Math.cos(angle1 * Math.PI / 180); //得到上方开叉的尾部到中间直线的X轴的长度
    var Y1 = arrowLangth * Math.sin(angle1 * Math.PI / 180); //得到上方开叉的尾部到中间直线Y轴(切线)的长度
    var X2 = arrowLangth * Math.cos(angle2 * Math.PI / 180); //得到下方开叉的尾部到中间直线的X轴的长度
    var Y2 = arrowLangth * Math.sin(angle2 * Math.PI / 180); //得到下方开叉的尾部到中间直线Y轴(切线)的长度
    console.log(X1 + "||" + X2);
    arrow1_x = toX + X1; //上方开叉的尾部点的x坐标
    arrow1_y = toY + Y1; //上方开叉的尾部点的y坐标
    arrow2_x = toX + X2; //下方开叉的尾部点的x坐标
    arrow2_y = toY + Y2; //下方开叉的尾部点的y坐标
    //虚线(中间那条长线)
    ctx.beginPath();
    ctx.setLineDash([15, 5]); //虚线
    ctx.moveTo(fromX, fromY); //起始点
    ctx.lineTo(toX, toY); //结束点
    ctx.strokeStyle = color; //虚线颜色
    ctx.stroke();
    //画上边箭头线
    ctx.beginPath();
    ctx.setLineDash([]);
    ctx.moveTo(arrow1_x, arrow1_y); //上箭头坐标
    ctx.lineTo(toX, toY);
    ctx.lineTo(arrow2_x, arrow2_y); //下箭头坐标
    ctx.strokeStyle = color;
    ctx.stroke();
}

可以直接使用的Demo:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <!-- <meta name="apple-mobile-web-app-capable" content="yes" /> -->
    <link rel="shortcut icon" href="#">
    <script src="static/vendors/jquery/jquery.min.js"></script>
    <link rel="stylesheet" type="text/css" href="static/vendors/bootstrap/bootstrap.css">
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
    <style type="text/css">
    * {
        margin: 0;
        padding: 0;
    }
    html,
    body {
        width: 100vw;
        height: 70vh;
        background-color: skyblue;
    }
    </style>
</head>

<body>
    <div id="body_" style="width: 100%;height: 100%;box-sizing: border-box;">
        <div id="centerBox" style="width: 960px;height: 540px;margin:0 auto;margin-top: 20px;background: url('./img/1.jpg') center 0;background-size: cover;border:solid 1px #000;" ontouchmove="return false;">
            <canvas id="my" style="border: 0px solid #f00;width: 960px;height: 540px;position: absolute;z-index: 9;"></canvas>
        </div>
    </div>
</body>
<script type="text/javascript">

var c = document.getElementById("my");
c.width = 960;
c.height = 540;
var ctx = c.getContext("2d");
var lineInitColor = "#0f0";
var clineWidth = 2
// 绘制方法
var boxGesture = setGesture(c); //得到一个对象
ctx.lineWidth = clineWidth;

function setGesture(el) {
    var obj = {}; //定义一个对象
    var istouch = false;
    var start = [];
    var One_hd = [];
    var can_move = false;
    el.addEventListener("touchstart", function(e) {
        ctx.strokeStyle = lineInitColor;
        startX = e.changedTouches[0].clientX - c.offsetLeft;
        startY = e.changedTouches[0].clientY - c.offsetTop;
        console.log(startX + "---start--" + startY); //鼠标按下
        return false;
    }, false);
    el.addEventListener("touchmove", function(e) {
        movingX = e.changedTouches[0].clientX - c.offsetLeft;
        movingY = e.changedTouches[0].clientY - c.offsetTop;

        console.log(movingX + "---moving--" + movingY);
    }, false);
    el.addEventListener("touchend", function(e) {
        endX = e.changedTouches[0].clientX - c.offsetLeft;
        endY = e.changedTouches[0].clientY - c.offsetTop;
        console.log(endX + "---end--" + endY);
        drawLineBroken(ctx, startX, startY, endX, endY, lineInitColor);
        return false;
    }, false);
    return obj;
};

//虚线
function drawLineBroken(ctx, fromX, fromY, toX, toY, color) {
    var arrow1_x, arrow1_y, arrow2_x, arrow2_y; //定义箭头开叉的尾部两个点的坐标
    var customAngle = 30; //假设夹角设定为30°
    var arrowLangth = 20; //箭头长度为20
    if (fromX == toX && fromY == toY) {
        // 开始和结束在同一点
    } else {
        var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI; //拿到夹角,目前为180°
    }
    var angle1 = angle + customAngle; //箭头上方的线与中间直线的角度
    var angle2 = angle - customAngle; //箭头下方的线与中间直线的角度
    //JS中sin和cos的参数都为弧度,不要直接把角度传进去
    var X1 = arrowLangth * Math.cos(angle1 * Math.PI / 180); //得到上方开叉的尾部到中间直线的X轴的长度
    var Y1 = arrowLangth * Math.sin(angle1 * Math.PI / 180); //得到上方开叉的尾部到中间直线Y轴(切线)的长度
    var X2 = arrowLangth * Math.cos(angle2 * Math.PI / 180); //得到下方开叉的尾部到中间直线的X轴的长度
    var Y2 = arrowLangth * Math.sin(angle2 * Math.PI / 180); //得到下方开叉的尾部到中间直线Y轴(切线)的长度
    console.log(X1 + "||" + X2);
    arrow1_x = toX + X1; //上方开叉的尾部点的x坐标
    arrow1_y = toY + Y1; //上方开叉的尾部点的y坐标
    arrow2_x = toX + X2; //下方开叉的尾部点的x坐标
    arrow2_y = toY + Y2; //下方开叉的尾部点的y坐标
    //虚线(中间那条长线)
    ctx.beginPath();
    ctx.setLineDash([15, 5]); //虚线
    ctx.moveTo(fromX, fromY); //起始点
    ctx.lineTo(toX, toY); //结束点
    ctx.strokeStyle = color; //虚线颜色
    ctx.stroke();
    //画上边箭头线
    ctx.beginPath();
    ctx.setLineDash([]);
    ctx.moveTo(arrow1_x, arrow1_y); //上箭头坐标
    ctx.lineTo(toX, toY);
    ctx.lineTo(arrow2_x, arrow2_y); //下箭头坐标
    ctx.strokeStyle = color;
    ctx.stroke();
}
</script>
</html>

效果

尽情的瞎画吧兄台们
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于 canvas 的图片编辑是一种使用 HTML5 技术的图形编辑工具,它可以在网页上绘制、修改和编辑图片。其中包括添加箭头和文字的功能。 首先,我们可以使用 canvas 绘制一个图像,通过 JavaScript 代码将其加载到网页上。然后,通过 canvas绘制 API,我们可以在图像上绘制箭头绘制箭头的步骤如下: 1. 确定箭头的起始点和结束点的坐标。 可以使用鼠标事件获取用户在图像上点击的位置,作为箭头的起始点。还可以使用 JavaScript 计算和设置箭头的结束点坐标。 2. 绘制箭头的线段。 使用 canvas 的线段绘制 API,从起始点绘制一条线段到结束点。 3. 绘制箭头箭头头部。 箭头的头部可以通过绘制一个三角形来实现。根据箭头线段的角度和长度,使用路径绘制 API 绘制一个三角形,并填充为箭头的颜色。 除了绘制箭头,我们还可以在 canvas 上添加文字。这可以通过以下步骤实现: 1. 确定文字的起始点坐标。 同样,可以通过鼠标事件JavaScript 确定文字的位置。 2. 设置文字样式。 使用 canvas 的字体和文本样式 API,可以设置文字的字体、大小、颜色等样式。 3. 绘制文字。 使用 canvas 的文本绘制 API,在指定的位置绘制文字。 总的来说,基于 canvas 的图片编辑可以让用户在网页上绘制箭头并添加文字。这个功能可以应用于图片标注、图形设计等各种场景,为用户提供了更多的编辑和创造空间。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值