02-Canvas-fabric.BaseBrush绘图工具

fabric.BaseBrush,你可以实现各种绘图工具,例如自由绘图、直线、矩形、圆形等。

  • 内置了一些基于 fabric.BaseBrush 的画笔工具,例如:
    fabric.PencilBrush:自由绘图工具。
    fabric.CircleBrush:圆形绘图工具。
    fabric.SprayBrush:喷枪工具。
    fabric.PatternBrush:图案画笔工具。
  • 自定义的绘图工具,可以通过扩展fabric.BaseBrush 来实现。
    fabric.BaseBrush 提供了一些核心方法,用于实现绘图工具的逻辑:
    initialize(canvas, options):初始化画笔工具。
    onMouseDown(pointer):鼠标按下时触发。
    onMouseMove(pointer):鼠标移动时触发。
    onMouseUp():鼠标释放时触发。
    createPath(pathData):创建路径对象(用于自由绘图工具)。
    setBrushStyles():设置画笔样式(颜色、宽度等)。
  • 自定义画笔工具-通过以下属性自定义画笔工具的样式:
    color:画笔颜色。
    width:画笔宽度。
    opacity:画笔透明度。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Fabric.js 自定义画笔工具</title><script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.2.4/fabric.min.js"></script>
</head><body><canvas id="canvas" width="1920" height="1080" style="border: 1px solid #000;"></canvas><script>// 通过继承 fabric.BaseBrush 实现一个自定义的自由绘图工具// 自定义画笔工具-自由绘图工具可以通过记录鼠标移动的路径来实现。const CustomBrush = fabric.util.createClass(fabric.BaseBrush, {initialize: function (canvas, options) {this.callSuper('initialize', canvas, options);this.points = []; // 存储绘图点},// 鼠标按下时触发onMouseDown: function (pointer) {this.points = [pointer]; // 记录起始点this.setBrushStyles(); // 设置画笔样式},// 鼠标移动时触发onMouseMove: function (pointer) {this.points.push(pointer); // 记录移动点this._render(); // 渲染路径},// 鼠标释放时触发onMouseUp: function () {if (this.points.length > 1) {const path = this.createPath(this.points); // 创建路径对象this.canvas.add(path); // 将路径添加到画布}this.points = []; // 清空点},// 创建路径对象createPath: function (points) {const pathData = points.map((point, index) => {return (index === 0 ? 'M' : 'L') + point.x + ' ' + point.y;}).join(' ');return new fabric.Path(pathData, {stroke: this.color,strokeWidth: this.width,fill: null,selectable: false});},// 渲染路径_render: function () {const ctx = this.canvas.getContext('2d');ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);ctx.beginPath();this.points.forEach((point, index) => {if (index === 0) {ctx.moveTo(point.x, point.y);} else {ctx.lineTo(point.x, point.y);}});ctx.strokeStyle = this.color;ctx.lineWidth = this.width;ctx.stroke();}});// 1.直线工具通过记录起点和终点来绘制直线。// const LineBrush = fabric.util.createClass(fabric.BaseBrush, {//     initialize: function (canvas, options) {//         this.callSuper('initialize', canvas, options);//         this.startPoint = null;//     },//     onMouseDown: function (pointer) {//         this.startPoint = pointer;//         this.setBrushStyles();//     },//     onMouseMove: function (pointer) {//         if (!this.startPoint) return;//         this._render(pointer);//     },//     onMouseUp: function () {//         if (this.startPoint) {//             const line = new fabric.Line([//                 this.startPoint.x, this.startPoint.y,//                 this.endPoint.x, this.endPoint.y//             ], {//                 stroke: this.color,//                 strokeWidth: this.width,//                 selectable: false//             });//             this.canvas.add(line);//         }//         this.startPoint = null;//     },//     _render: function (pointer) {//         const ctx = this.canvas.getContext('2d');//         ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);//         ctx.beginPath();//         ctx.moveTo(this.startPoint.x, this.startPoint.y);//         ctx.lineTo(pointer.x, pointer.y);//         ctx.strokeStyle = this.color;//         ctx.lineWidth = this.width;//         ctx.stroke();//         this.endPoint = pointer;//     }// });// 2.矩形工具通过记录起点和终点来绘制矩形。// const RectBrush = fabric.util.createClass(fabric.BaseBrush, {//     initialize: function (canvas, options) {//         this.callSuper('initialize', canvas, options);//         this.startPoint = null;//     },//     onMouseDown: function (pointer) {//         this.startPoint = pointer;//         this.setBrushStyles();//     },//     onMouseMove: function (pointer) {//         if (!this.startPoint) return;//         this._render(pointer);//     },//     onMouseUp: function () {//         if (this.startPoint) {//             const rect = new fabric.Rect({//                 left: this.startPoint.x,//                 top: this.startPoint.y,//                 width: this.endPoint.x - this.startPoint.x,//                 height: this.endPoint.y - this.startPoint.y,//                 stroke: this.color,//                 strokeWidth: this.width,//                 fill: null,//                 selectable: false//             });//             this.canvas.add(rect);//         }//         this.startPoint = null;//     },//     _render: function (pointer) {//         const ctx = this.canvas.getContext('2d');//         ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);//         ctx.strokeStyle = this.color;//         ctx.lineWidth = this.width;//         ctx.strokeRect(//             this.startPoint.x,//             this.startPoint.y,//             pointer.x - this.startPoint.x,//             pointer.y - this.startPoint.y//         );//         this.endPoint = pointer;//     }// });// 3.圆形工具// const CircleBrush = fabric.util.createClass(fabric.BaseBrush, {//     initialize: function (canvas, options) {//         this.callSuper('initialize', canvas, options);//         this.startPoint = null;//     },//     onMouseDown: function (pointer) {//         this.startPoint = pointer;//         this.setBrushStyles();//     },//     onMouseMove: function (pointer) {//         if (!this.startPoint) return;//         this._render(pointer);//     },//     onMouseUp: function () {//         if (this.startPoint) {//             const radius = Math.sqrt(//                 Math.pow(this.endPoint.x - this.startPoint.x, 2) +//                 Math.pow(this.endPoint.y - this.startPoint.y, 2)//             );//             const circle = new fabric.Circle({//                 left: this.startPoint.x,//                 top: this.startPoint.y,//                 radius: radius,//                 stroke: this.color,//                 strokeWidth: this.width,//                 fill: null,//                 selectable: false//             });//             this.canvas.add(circle);//         }//         this.startPoint = null;//     },//     _render: function (pointer) {//         const ctx = this.canvas.getContext('2d');//         ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);//         ctx.beginPath();//         const radius = Math.sqrt(//             Math.pow(pointer.x - this.startPoint.x, 2) +//             Math.pow(pointer.y - this.startPoint.y, 2)//         );//         ctx.arc(this.startPoint.x, this.startPoint.y, radius, 0, Math.PI * 2);//         ctx.strokeStyle = this.color;//         ctx.lineWidth = this.width;//         ctx.stroke();//         this.endPoint = pointer;//     }// });// 初始化画布const canvas = new fabric.Canvas('canvas');// 使用自定义画笔工具// const customBrush = new CustomBrush(canvas);// canvas.freeDrawingBrush = customBrush; // 设置为当前画笔工具// canvas.freeDrawingBrush.color = 'blue'; // 设置画笔颜色// canvas.freeDrawingBrush.width = 5; // 设置画笔宽度// canvas.isDrawingMode = true; // 启用绘图模式// 一、使用fabric.PencilBrush自定义画笔工具const customBrush = new CustomBrush(canvas);canvas.freeDrawingBrush = new fabric.PencilBrush(canvas);canvas.freeDrawingBrush.color = 'blue'; // 设置画笔颜色canvas.freeDrawingBrush.width = 2; // 设置画笔宽度canvas.isDrawingMode = true; // 启用绘图模式// 二、使用 fabric.CircleBrush(圆形绘图工具)// canvas.freeDrawingBrush = new fabric.CircleBrush(canvas);// canvas.freeDrawingBrush.color = 'red'; // 设置画笔颜色// canvas.freeDrawingBrush.width = 10; // 设置画笔宽度// canvas.isDrawingMode = true; // 启用绘图模式// 1.使用直线工具// const customBrush = new LineBrush(canvas);// canvas.freeDrawingBrush = new fabric.PencilBrush(canvas);// canvas.freeDrawingBrush.color = 'red'; // 设置画笔颜色// canvas.freeDrawingBrush.width = 3; // 设置画笔宽度// canvas.isDrawingMode = true; // 启用绘图模式// 2.矩形工具// const customBrush = new RectBrush(canvas);// canvas.freeDrawingBrush = new fabric.PencilBrush(canvas);// canvas.freeDrawingBrush.color = 'green'; // 设置画笔颜色// canvas.freeDrawingBrush.width = 2; // 设置画笔宽度// canvas.isDrawingMode = true; // 启用绘图模式// 3.圆形工具// canvas.freeDrawingBrush = new CircleBrush(canvas);// canvas.freeDrawingBrush = new fabric.PencilBrush(canvas);// canvas.freeDrawingBrush.color = 'green'; // 设置画笔颜色// canvas.freeDrawingBrush.width = 2; // 设置画笔宽度// canvas.isDrawingMode = true; // 启用绘图模式</script>
</body></html>

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

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

相关文章

C++算法学习2:二分算法精讲

一、实数二分法回顾 1.1问题背景 在1~2的范围内找到一个x&#xff0c;使得式子5x2 -9x 1 的绝对值<10-9&#xff08;即无限接近0&#xff09; 要求&#xff1a;x精确到小数点后9位。 换句话说也就是求&#xff1a;就是求方程 5x2- 9x 1 0 在1~2内的近似解 1.2怎么找到…

手写一个简易版的tomcat

Tomcat 是一个广泛使用的开源 Servlet 容器&#xff0c;用于运行 Java Web 应用程序。深入理解 Tomcat 的工作原理对于 Java 开发者来说是非常有价值的。本文将带领大家手动实现一个简易版的 Tomcat&#xff0c;通过这个过程&#xff0c;我们可以更清晰地了解 Tomcat 是如何处理…

object.assign和扩展运算法是深拷贝还是浅拷贝,两者区别

object.assign和扩展运算法是深拷贝还是浅拷贝&#xff0c;两者区别 1. 浅拷贝的本质2. Object.assign 和扩展运算符的区别‌3. 具体场景对比‌合并多个对象‌‌复制数组‌‌处理默认值‌ ‌4. 如何实现深拷贝&#xff1f;JSON.parse(JSON.stringify(obj))‌‌递归深拷贝函数第…

X-CLIP和X-FLORENCE论文解读

1.研究背景 尽管已有研究探索了如何将语言-图像模型迁移到其他下游任务&#xff08;如点云理解和密集预测&#xff09;&#xff0c;但视频识别领域的迁移和适应性研究还不够充分。例如&#xff0c;ActionCLIP提出了一种“预训练、提示和微调”的框架用于动作识别&#xff0c;但…

微信小程序刷题逻辑实现:技术揭秘与实践分享

页面展示&#xff1a; 概述 在当今数字化学习的浪潮中&#xff0c;微信小程序以其便捷性和实用性&#xff0c;成为了众多学习者刷题备考的得力工具。今天&#xff0c;我们就来深入剖析一个微信小程序刷题功能的实现逻辑&#xff0c;从代码层面揭开其神秘面纱。 小程序界面布局…

Android UI 组件系列(二):Button 进阶用法

引言 在上一篇博客中&#xff0c;我们介绍了 Button 的基本用法和常见属性&#xff0c;掌握了 Button 的基础知识。然而&#xff0c;在实际开发中&#xff0c;Button 远不止于简单的点击功能&#xff0c;它还可以支持不同的变体、丰富的自定义样式&#xff0c;以及更灵活的状态…

【云馨AI-大模型】RAGFlow功能预览:Dify接入外部知识库RAGFlow指南

介绍 Dify介绍 开源的 LLM 应用开发平台。提供从 Agent 构建到 AI workflow 编排、RAG 检索、模型管理等能力&#xff0c;轻松构建和运营生成式 AI 原生应用。比 LangChain 更易用。官网&#xff1a;https://dify.ai/zh RAGFlow介绍 RAGFlow 是一款基于深度文档理解构建的…

Redis超高并发分key实现

Redis扛并发的能力是非常强的&#xff0c;所以高并发场景下经常会使用Redis&#xff0c;但是Redis单分片的写入瓶颈在2w左右&#xff0c;读瓶颈在10w左右&#xff0c;如果在超高并发下即使是集群部署Redis&#xff0c;单分片的Redis也是有可能扛不住的&#xff0c;如下图所示&a…

缓存使用的具体场景有哪些?缓存的一致性问题如何解决?缓存使用常见问题有哪些?

缓存使用场景、一致性及常见问题解析 一、缓存的核心使用场景 1. 高频读、低频写场景 典型场景&#xff1a;商品详情页、新闻资讯、用户基本信息。特点&#xff1a;数据更新频率低&#xff0c;但访问量极高。策略&#xff1a; Cache-Aside&#xff08;旁路缓存&#xff09;&a…

HTML5(Web前端开发笔记第一期)

p.s.这是萌新自己自学总结的笔记&#xff0c;如果想学习得更透彻的话还是请去看大佬的讲解 目录 三件套标签标题标签段落标签文本格式化标签图像标签超链接标签锚点链接默认链接地址 音频标签视频标签 HTML基本骨架综合案例->个人简介列表表格表单input标签单选框radio上传…

ubuntu22.04 关于挂在设备为nfts文件格式无法创建软连接的问题

最近遇到情况&#xff0c;解压工程报错&#xff0c;无法创建软连接 但是盘内还有130G空间&#xff0c;明显不是空间问题&#xff0c;查找之后发现是移动硬盘的文件格式是NTFS&#xff0c;在ubuntu上不好兼容&#xff0c;于是报错。 开贴记录解决方案。 1.确定文件格式 使用命…

深度解读DeepSeek部署使用安全(48页PPT)(文末有下载方式)

深度解读DeepSeek&#xff1a;部署、使用与安全 详细资料请看本解读文章的最后内容。 引言 DeepSeek作为一款先进的人工智能模型&#xff0c;其部署、使用与安全性是用户最为关注的三大核心问题。本文将从本地化部署、使用方法与技巧、以及安全性三个方面&#xff0c;对Deep…

RK3568 Android13 源码编译

提示&#xff1a;RK3568 Android13 源码编译 脚本&#xff0c;源码编译管理方式优化 文章目录 获取源码设置屏幕配置确认屏幕修改源码的设备树 修改线程数整体编译Android固件配置JDK java 环境 source javaenv.sh使能编译 build/envsetup.sh lunch topeet_rk3568-userdebug整体…

【CentOS】搭建Radius服务器

目录 背景简介&#xff1a;Radius是什么&#xff1f;Radius服务器验证原理搭建Radius服务器环境信息yum在线安装配置FreeRADIUS相关文件clients.conf文件users文件重启服务 验证 参考链接 背景 在项目中需要用到Radius服务器作为数据库代理用户的外部验证服务器&#xff0c;做…

ToB公司找客户专用|大数据获客系统

对于ToB公司而言&#xff0c;找到并吸引合适的潜在客户并非易事。传统的获客手段如参加行业展会、电话推销以及直接拜访等&#xff0c;虽然在过去取得了一定成效&#xff0c;但如今却暴露出诸多问题。首先&#xff0c;这些方法往往成本高昂&#xff0c;无论是时间还是金钱上的投…

Linux 文件权限类

目录 文件属性 从左到右的10个字符表示 rwx作用文件和目录的不同解释 图标&#xff1a; 案例实操 chmod 改变权限 基本语法 经验技巧 案例实操 拓展&#xff1a;可以通过一个命令查看用户列表 chown改变所有者 基本语法 选项说明 案例实操 chgrp 改变所属组 基…

DeepSeek技术解析:MoE架构实现与代码实战

以下是一篇结合DeepSeek技术解析与代码示例的技术文章&#xff0c;重点展示其核心算法实现与落地应用&#xff1a; DeepSeek技术解析&#xff1a;MoE架构实现与代码实战 作为中国AI领域的创新代表&#xff0c;DeepSeek在混合专家模型&#xff08;Mixture of Experts, MoE&…

vue3:八、登录界面实现-页面初始搭建、基础实现

一、初始工作 1、创建登录文件 在src/views中创建文件LoginView.vue文件 2、创建路由 在router/index.js中增加登录的信息 代码 import { createRouter, createWebHistory } from vue-router import HomeView from ../views/HomeView.vue const router createRouter({hist…

dify+mysql的诗词助手

目录 数据库表结构&#xff1a; 数据库查询的http服务搭建&#xff1a; 流程引擎搭建&#xff1a; 开始&#xff0c; HTTP查询数据库&#xff0c; LLM数据分析&#xff0c; 直接回复&#xff0c; 效果测试&#xff1a; 下载链接&#xff1a; 数据库表结构&#xff1a;…

jenkins 配置邮件问题整理

版本&#xff1a;Jenkins 2.492.1 插件&#xff1a; A.jenkins自带的&#xff0c; B.安装功能强大的插件 配置流程&#xff1a; 1. jenkins->系统配置->Jenkins Location 此处的”系统管理员邮件地址“&#xff0c;是配置之后发件人的email。 2.配置系统自带的邮件A…