新增正方形和椭圆

This commit is contained in:
朱浩 2024-09-26 12:36:24 +08:00
parent 37ef481a35
commit 3fed8af69d
6 changed files with 92 additions and 0 deletions

View File

@ -5,8 +5,10 @@
<el-radio-group v-model="currentType" @change="onCurrentTypeChange"> <el-radio-group v-model="currentType" @change="onCurrentTypeChange">
<el-radio-button label="selection">选择</el-radio-button> <el-radio-button label="selection">选择</el-radio-button>
<el-radio-button label="rectangle">矩形</el-radio-button> <el-radio-button label="rectangle">矩形</el-radio-button>
<el-radio-button label="square">正方形</el-radio-button>
<el-radio-button label="diamond">菱形</el-radio-button> <el-radio-button label="diamond">菱形</el-radio-button>
<el-radio-button label="triangle">三角形</el-radio-button> <el-radio-button label="triangle">三角形</el-radio-button>
<el-radio-button label="elliptic">椭圆形</el-radio-button>
<el-radio-button label="circle">圆形</el-radio-button> <el-radio-button label="circle">圆形</el-radio-button>
<el-radio-button label="line">线段</el-radio-button> <el-radio-button label="line">线段</el-radio-button>
<el-radio-button label="arrow">箭头</el-radio-button> <el-radio-button label="arrow">箭头</el-radio-button>

View File

@ -1,5 +1,6 @@
import Rectangle from './elements/Rectangle' import Rectangle from './elements/Rectangle'
import Circle from './elements/Circle' import Circle from './elements/Circle'
import Elliptic from './elements/Elliptic'
import Diamond from './elements/Diamond' import Diamond from './elements/Diamond'
import Triangle from './elements/Triangle' import Triangle from './elements/Triangle'
import Freedraw from './elements/Freedraw' import Freedraw from './elements/Freedraw'
@ -167,6 +168,8 @@ export default class Elements {
return new Triangle(opts, this.app) return new Triangle(opts, this.app)
case 'circle': case 'circle':
return new Circle(opts, this.app) return new Circle(opts, this.app)
case 'elliptic':
return new Elliptic(opts, this.app)
case 'freedraw': case 'freedraw':
return new Freedraw(opts, this.app) return new Freedraw(opts, this.app)
case 'image': case 'image':
@ -258,6 +261,18 @@ export default class Elements {
this.activeElement.updateSize(offsetX, offsetY) 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) { creatingCircle(x, y, e) {
this.createElement({ this.createElement({
@ -269,6 +284,16 @@ export default class Elements {
this.activeElement.updateSize(radius, radius) 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) { creatingFreedraw(e, event) {
this.createElement({ this.createElement({

33
src/elements/Elliptic.js Normal file
View File

@ -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)
}
}

View File

@ -2,6 +2,7 @@ import Arrow from './Arrow'
import BaseElement from './BaseElement' import BaseElement from './BaseElement'
import BaseMultiPointElement from './BaseMultiPointElement' import BaseMultiPointElement from './BaseMultiPointElement'
import Circle from './Circle' import Circle from './Circle'
import Elliptic from './Elliptic'
import Diamond from './Diamond' import Diamond from './Diamond'
import DragElement from './DragElement' import DragElement from './DragElement'
import Freedraw from './Freedraw' import Freedraw from './Freedraw'
@ -17,6 +18,7 @@ export default {
BaseElement, BaseElement,
BaseMultiPointElement, BaseMultiPointElement,
Circle, Circle,
Elliptic,
Diamond, Diamond,
DragElement, DragElement,
Freedraw, Freedraw,

View File

@ -472,10 +472,19 @@ class TinyWhiteboard extends EventEmitter {
offsetY offsetY
) )
this.render.render() 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') { } else if (this.drawType === 'circle') {
// 绘制圆形模式 // 绘制圆形模式
this.elements.creatingCircle(mx, my, e) this.elements.creatingCircle(mx, my, e)
this.render.render() this.render.render()
} else if (this.drawType === 'elliptic') {
// 绘制圆形模式
this.elements.creatingElliptic(mx, my, offsetX, offsetY)
this.render.render()
} else if (this.drawType === 'freedraw') { } else if (this.drawType === 'freedraw') {
// 自由画笔模式 // 自由画笔模式
this.elements.creatingFreedraw(e, event) this.elements.creatingFreedraw(e, event)

View File

@ -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) => { export const drawDiamond = (ctx, x, y, width, height, fill = false) => {
drawWrap( 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) => { export const drawLine = (ctx, points) => {
drawWrap(ctx, () => { drawWrap(ctx, () => {