canvas画箭头线

箭头线

vue+uni-app+canvas 画带箭头可拖动的线段

<template><div><canvas ref="canvas" class="canvas" width="600px" height="400px" @mousedown="startDrawing" @mousemove="draw" @mouseup="stopDrawing"></canvas></div>
</template><script>
export default {data() {return {drawing: false,context: null,startX: 0,startY: 0,endX: 0,endY: 0};},mounted() {this.initializeCanvas();},methods: {initializeCanvas() {this.context = this.$refs.canvas.getContext('2d');this.context.strokeStyle = 'red';this.context.lineWidth = 2;this.context.strokeRect(300, 150, 10, 100);},startDrawing(event) {this.drawing = true;let rect = this.$refs.canvas.getBoundingClientRect()this.startX = event.clientX - rect.left;this.startY = event.clientY - rect.top;},draw(event) {if (!this.drawing) return;let rect = this.$refs.canvas.getBoundingClientRect()this.endX = event.clientX - rect.left;this.endY = event.clientY - rect.top;this.clearCanvas();this.drawLineArrow(this.context, this.startX, this.startY, this.endX, this.endY);},stopDrawing() {this.drawing = false;this.clearCanvas();this.startX = 0this.startY = 0this.endX = 0this.endY = 0},clearCanvas() {this.context.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height);},drawArrowLine(startX, startY, endX, endY) {this.context.beginPath();this.context.moveTo(startX, startY);this.context.lineTo(endX, endY);// 计算箭头的角度const angle = Math.atan2(endY - startY, endX - startX);// 绘制箭头部分const arrowSize = 10;this.context.lineTo(endX - arrowSize * Math.cos(angle - Math.PI / 6), endY - arrowSize * Math.sin(angle - Math.PI / 6));this.context.moveTo(endX, endY);this.context.lineTo(endX - arrowSize * Math.cos(angle + Math.PI / 6), endY - arrowSize * Math.sin(angle + Math.PI / 6));this.context.stroke();},/*** * @param {*canvas context 对象} ctx * @param {*起点横坐标} fromX * @param {*起点纵坐标} fromY * @param {*终点横坐标} toX * @param {*终点纵坐标} toY * 以下注释以终点在坐标第一象限内,且方向为右上方*/drawLineArrow(ctx, fromX, fromY, toX, toY) {var headlen = 0.2 * 1.41 * Math.sqrt((fromX - toX) * (fromX - toX) + (fromY - toY) * (fromY - toY));//箭头头部长度headlen = headlen > 40 ? 40 : headlen;//40是箭头头部最大值var theta = 30;//自定义箭头线与直线的夹角var arrowX, arrowY;//箭头线终点坐标// 计算各角度和对应的箭头终点坐标var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI;var angle1 = (angle + theta) * Math.PI / 180;var angle2 = (angle - theta) * Math.PI / 180;var topX = headlen * Math.cos(angle1);var topY = headlen * Math.sin(angle1);var botX = headlen * Math.cos(angle2);var botY = headlen * Math.sin(angle2);var toLeft = fromX > toX;var toUp = fromY > toY;//箭头最上点arrowX = toX + topX;arrowY = toY + topY;//箭头下拐点var arrowX1 = toX + botX;var arrowY1 = toY + botY;//箭头上拐点var arrowX2 = toUp ? arrowX + 0.25 * Math.abs(arrowX1 - arrowX) : arrowX - 0.25 * Math.abs(arrowX1 - arrowX);var arrowY2 = toLeft ? arrowY - 0.25 * Math.abs(arrowY1 - arrowY) : arrowY + 0.25 * Math.abs(arrowY1 - arrowY);//箭头最下点 var arrowX3 = toUp ? arrowX + 0.75 * Math.abs(arrowX1 - arrowX) : arrowX - 0.75 * Math.abs(arrowX1 - arrowX);var arrowY3 = toLeft ? arrowY - 0.75 * Math.abs(arrowY1 - arrowY) : arrowY + 0.75 * Math.abs(arrowY1 - arrowY);ctx.beginPath();//起点-起点,闭合ctx.moveTo(fromX, fromY);ctx.lineTo(arrowX2, arrowY2);ctx.lineTo(arrowX, arrowY);ctx.lineTo(toX, toY);ctx.lineTo(arrowX1, arrowY1);ctx.lineTo(arrowX3, arrowY3);ctx.lineTo(fromX, fromY);ctx.closePath();ctx.strokeStyle = "#FB8978";ctx.fillStyle = "rgba(255,197,179,0.3)";ctx.fill();ctx.stroke();}}
};
</script><style scoped>
/* 可以添加一些样式 */
.canvas {/* width: 800px;height: 500px; */background: #ccc;
}
</style>

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

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

相关文章

Centos手动安装PHP和配置mydqli模块

第一步&#xff1a;手动安装php和php-fpm sudo yum install php php-fpm 安装 sudo systemctl start php-fpm 启动 sudo systemctl enable php-fpm 开机启动 php -v php-fpm -v PHP 5.4.16 (cli) (built: Apr 1 2020 04:07:17) Copyright (c) 1997-2013 The PHP G…

【加密与解密】【09】GPG Client签名流程

什么是GPG客户端 GPG客户端是实现PGP加密协议的一套客户端程序&#xff0c;可用于加密或签名 下载GPG客户端 建议安装命令行工具&#xff0c;图形工具一般不具备完整功能 https://gnupg.org/download/index.html生成私钥 此时会要求你输入名称&#xff0c;邮箱&#xff0c…

Qt Q_ASSERT详解

Q_ASSERT详解 引言一、基本用法二、深入了解三、参考链接 引言 Q_ASSERT是 Qt 框架中的一个宏&#xff0c;用于在调试时检查某个条件是否为真。它是程序调试中的一个重要工具&#xff0c;有助于开发者在开发过程中及时发现并修复潜在的错误。 一、基本用法 只在使用 Qt 的 D…

干货:科技论文写作保姆级攻略

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。科技论文是报道自然科学研究或技术开发工作成果的论说文章。通常基于概念、判断、推理、证明或反驳等逻辑思维体系&#xff0c;使用实验调研或理论计算等研究手段&#xff0c;按照特定格式撰写完成。 科技论文可以粗略分为…

UiPath+Appium实现app自动化测试

一、环境准备工作 1.1 完成appium环境的搭建 参考&#xff1a;pythonappiumpytestallure模拟器(MuMu)自动化测试环境搭建_appium mumu模拟器-CSDN博客 1.2 完成uipath的安装 登录官网&#xff0c;完成注册与软件下载安装。 UiPath业务自动化平台&#xff1a;先进的RPA及自动…

vue组件深入介绍之插槽

了解插槽之前请先了解vue组件基础及注册 Vue2官网介绍 Vue3官网介绍 1、vue2插槽介绍 在2.6.0中&#xff0c;具名插槽和作用域插槽引入了一个新的统一语法&#xff08;v-slot指令&#xff09;。它将取代slot和slot-scope&#xff1b; Vue 实现了一套内容分发的 API&#xf…

AI 会淘汰程序员吗?

前言 前些日子看过一篇文章&#xff0c;说国外一位拥有 19 年编码经验、会 100% 手写代码的程序员被企业解雇了&#xff0c;因为他的竞争对手&#xff0c;一位仅有 4 年经验、却善于使用 Copilot、GPT-4 的后辈&#xff0c;生产力比他更高&#xff0c;成本比他更低&#xff0c…

【数据分享】《中国金融年鉴》1986-2020年PDF版

而今天要免费分享的数据就是1986-2020年间出版的《中国金融年鉴》并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 《中国金融年鉴》自1986年起&#xff0c;逐年记录着中国金融领域的发展历程、政策变化和市场动态。这部年鉴不仅是金融专业…

利用人工智能技术提升返利App的智能推荐功能

利用人工智能技术提升返利App的智能推荐功能 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 随着人工智能技术的迅猛发展&#xff0c;它已经渗透到了各行各业…

Halcon 基于分水岭的目标分割

一 分水岭 1 分水岭介绍 传统的分水岭分割方法&#xff0c;是一种基于拓扑理论的数学形态学的分割方法&#xff0c;其基本思想是把图像看作是地质学上的拓扑地貌&#xff0c;图像中每一像素的灰度值表示该点的海拔高度&#xff0c;每一个局部极小值及其周边区域称为集水盆地&…

企业私有模型和提示词工程初探

企业私有模型和提示词工程&#xff1a;提升AI应用的策略和方法 摘要 在当今竞争激烈的商业环境中&#xff0c;企业越来越依赖于人工智能&#xff08;AI&#xff09;技术来提高运营效率和创新能力。本文探讨了企业如何通过构建私有模型和应用提示词工程来优化AI系统。首先&…

ROS学习笔记(18):建图与定位(2)

0.前言 上文提到现在的我们已经进入到了SLAM领域的学习&#xff0c;会涉及到大量专业知识&#xff0c;作为一个自学的大三&#xff08;好吧也快大四了&#xff09;萌新并不能保证每次文章的专业性和准确性&#xff0c;所以&#xff0c;本人推荐大家能自己去查阅一些相关书籍和…

牛!手机、TV双端聚合,免费可同步!

哈喽&#xff0c;各位小伙伴们好&#xff0c;我是给大家带来各类黑科技与前沿资讯的小武。 有不少小伙伴闲时会选择观看游戏、户外、娱乐等各类的直播&#xff0c;而关注的主播可能驻留在不同直播平台&#xff0c;需要下载多个APP&#xff0c;且切换非常不方便。 所以今天给大…

缓存生命周期管理:探索Memcached的过期策略

缓存生命周期管理&#xff1a;探索Memcached的过期策略 在高效的缓存系统中&#xff0c;过期策略是确保数据时效性的关键。Memcached作为一个简单而强大的分布式内存缓存系统&#xff0c;提供了几种不同的缓存过期策略来满足不同的业务需求。本文将详细介绍Memcached的缓存过期…

OpenHarmony移植小型系统exynos4412(一)

新建芯片解决方案 1、新建目录 芯片解决方案的目录规则为:device/board/{芯片解决方案厂商}/{开发板}。以exynos的fs4412开发板为例,在代码根目录执行如下命令建立目录: mkdir -p device/exynos/fs4412 芯片解决方案目录树的规则如下: device/board └── company # 芯…

自定义动态数据源+事务控制

1&#xff1a;首先yml配置两个数据库的链接 spring:application:name: xxxxmain:banner-mode: OFFdatasource: # 默认数据源 datamarkdruid: # 关闭数据库的 web 访问stat-view-servlet:enabled: falseweb-stat-filter:enabled: falsefilt…

Linux系统之玩转SafeLine防火墙应用

Linux系统之玩转SafeLine防火墙应用 一、SafeLine介绍1.1SafeLine简介1.2 SafeLine功能1.3 SafeLine 的工作原理二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本四、部署SafeLine4.1 安…

算法训练营day67

题目1&#xff1a; #include <iostream> #include <vector> #include <string> #include <unordered_set> #include <unordered_map> #include <queue>using namespace std;int main() {string beginStr, endStr;int n;cin >> n;ci…

一篇文章搞懂弹性云服务器和轻量云服务器的区别

前言 在众多的云服务器类型中&#xff0c;弹性云服务器和轻量云服务器因其各自的特点和优势&#xff0c;受到了广大用户的青睐。那么&#xff0c;这两者之间到底有哪些区别呢&#xff1f;本文将为您详细解析。 弹性云服务器&#xff1a;灵活多变的计算资源池 弹性云服务器&…

谷粒商城-个人笔记(集群部署篇一)

前言 ​学习视频&#xff1a;​Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强​学习文档&#xff1a; 谷粒商城-个人笔记(基础篇一)谷粒商城-个人笔记(基础篇二)谷粒商城-个人笔记(基础篇三)谷粒商城-个人笔记(高级篇一)谷粒商城-个…