From 3fed8af69d329cf705032f4b3da790a3ed92e7b0 Mon Sep 17 00:00:00 2001 From: zhuhao <979263092@qq.com> Date: Thu, 26 Sep 2024 12:36:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=AD=A3=E6=96=B9=E5=BD=A2?= =?UTF-8?q?=E5=92=8C=E6=A4=AD=E5=9C=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/App.vue | 2 ++ src/Elements.js | 25 +++++++++++++++++++++++++ src/elements/Elliptic.js | 33 +++++++++++++++++++++++++++++++++ src/elements/index.js | 2 ++ src/index.js | 9 +++++++++ src/utils/draw.js | 21 +++++++++++++++++++++ 6 files changed, 92 insertions(+) create mode 100644 src/elements/Elliptic.js diff --git a/app/src/App.vue b/app/src/App.vue index e5fade4..1fcec4d 100644 --- a/app/src/App.vue +++ b/app/src/App.vue @@ -5,8 +5,10 @@ 选择 矩形 + 正方形 菱形 三角形 + 椭圆形 圆形 线段 箭头 diff --git a/src/Elements.js b/src/Elements.js index dba01a8..25af7d5 100644 --- a/src/Elements.js +++ b/src/Elements.js @@ -1,5 +1,6 @@ import Rectangle from './elements/Rectangle' import Circle from './elements/Circle' +import Elliptic from './elements/Elliptic' import Diamond from './elements/Diamond' import Triangle from './elements/Triangle' import Freedraw from './elements/Freedraw' @@ -167,6 +168,8 @@ export default class Elements { return new Triangle(opts, this.app) case 'circle': return new Circle(opts, this.app) + case 'elliptic': + return new Elliptic(opts, this.app) case 'freedraw': return new Freedraw(opts, this.app) case 'image': @@ -258,6 +261,18 @@ export default class Elements { this.activeElement.updateSize(offsetX, offsetY) } + // 正在创建正方形元素 + creatingSquare(x, y, offsetX, offsetY) { + this.createElement({ + type: 'rectangle', + x: x, + y: y, + width: offsetX, + height: offsetY + }) + this.activeElement.updateSize(offsetX, offsetY) + } + // 正在创建圆形元素 creatingCircle(x, y, e) { this.createElement({ @@ -269,6 +284,16 @@ export default class Elements { this.activeElement.updateSize(radius, radius) } + // 正在创建椭圆形元素 + creatingElliptic(x, y, offsetX, offsetY) { + this.createElement({ + type: 'elliptic', + x: x, + y: y + }) + this.activeElement.updateSize(offsetX, offsetY) + } + // 正在创建自由画笔元素 creatingFreedraw(e, event) { this.createElement({ diff --git a/src/elements/Elliptic.js b/src/elements/Elliptic.js new file mode 100644 index 0000000..46fca16 --- /dev/null +++ b/src/elements/Elliptic.js @@ -0,0 +1,33 @@ +import BaseElement from './BaseElement' +import { drawElliptic } from '../utils/draw' +import DragElement from './DragElement' +import { transformPointOnElement } from '../utils' +import { getCircleRadius, checkIsAtCircleEdge } from '../utils/checkHit' + +// 正圆元素类 +export default class Circle extends BaseElement { + constructor(...args) { + super(...args) + // 拖拽元素实例 + this.dragElement = new DragElement(this, this.app, { + lockRatio: true + }) + } + + // 渲染到画布 + render() { + let { width, height } = this + this.warpRender(({ halfWidth, halfHeight }) => { + // 画布中心点修改了,所以元素的坐标也要相应修改 + drawElliptic(this.app.ctx, 0, 0, width, height, true) + }) + // 激活时显示拖拽框 + this.renderDragElement() + } + + // 检测是否被击中 + isHit(x, y) { + let rp = transformPointOnElement(x, y, this) + return checkIsAtCircleEdge(this, rp) + } +} diff --git a/src/elements/index.js b/src/elements/index.js index 85f2883..f1f6359 100644 --- a/src/elements/index.js +++ b/src/elements/index.js @@ -2,6 +2,7 @@ import Arrow from './Arrow' import BaseElement from './BaseElement' import BaseMultiPointElement from './BaseMultiPointElement' import Circle from './Circle' +import Elliptic from './Elliptic' import Diamond from './Diamond' import DragElement from './DragElement' import Freedraw from './Freedraw' @@ -17,6 +18,7 @@ export default { BaseElement, BaseMultiPointElement, Circle, + Elliptic, Diamond, DragElement, Freedraw, diff --git a/src/index.js b/src/index.js index a4e5290..5debefc 100644 --- a/src/index.js +++ b/src/index.js @@ -472,10 +472,19 @@ class TinyWhiteboard extends EventEmitter { offsetY ) this.render.render() + } else if (this.drawType === 'square') { + let wid = Math.min(Math.abs(offsetX), Math.abs(offsetY)) + // 正方形元素绘制模式 + this.elements.creatingSquare(mx, my, wid, wid) + this.render.render() } else if (this.drawType === 'circle') { // 绘制圆形模式 this.elements.creatingCircle(mx, my, e) this.render.render() + } else if (this.drawType === 'elliptic') { + // 绘制圆形模式 + this.elements.creatingElliptic(mx, my, offsetX, offsetY) + this.render.render() } else if (this.drawType === 'freedraw') { // 自由画笔模式 this.elements.creatingFreedraw(e, event) diff --git a/src/utils/draw.js b/src/utils/draw.js index b91ebd8..5929afb 100644 --- a/src/utils/draw.js +++ b/src/utils/draw.js @@ -22,6 +22,16 @@ export const drawRect = (ctx, x, y, width, height, fill = false) => { }) } +export const drawSquare = (ctx, x, y, width, height, fill = false) => { + drawWrap(ctx, () => { + let wid = Math.min(Math.abs(width), Math.abs(height)) + ctx.rect(x, y, wid, wid) + if (fill) { + ctx.fillRect(x, y, wid, wid) + } + }) +} + // 绘制菱形 export const drawDiamond = (ctx, x, y, width, height, fill = false) => { drawWrap( @@ -62,6 +72,17 @@ export const drawCircle = (ctx, x, y, r, fill = false) => { ) } +// 绘制圆形 +export const drawElliptic = (ctx, x, y, rX, rY, fill = false) => { + drawWrap( + ctx, + () => { + ctx.ellipse(x, y, rX, rY, 0,0, 2 * Math.PI) + }, + fill + ) +} + // 绘制折线 export const drawLine = (ctx, points) => { drawWrap(ctx, () => {