feat: 双折线线条

This commit is contained in:
zxc 2024-07-23 23:40:43 +08:00
parent 6739bbff6f
commit 08769d2bbd
8 changed files with 21 additions and 3 deletions

View File

@ -120,6 +120,7 @@ npm run dev
- Shape format painter
- Edit text (supports rich text, similar to text elements rich text editing)
#### Lines
- Straight lines, polylines, curves
- Color
- Width
- Style

View File

@ -106,6 +106,7 @@ npm run dev
- 形状格式刷
- 编辑文字(支持富文本,与文字元素的富文本编辑功能近似)
#### 线条
- 直线、基础折线/曲线
- 颜色
- 宽度
- 样式

View File

@ -6,6 +6,7 @@ export interface LinePoolItem {
style: 'solid' | 'dashed'
points: [LinePoint, LinePoint]
isBroken?: boolean
isBroken2?: boolean
isCurve?: boolean
isCubic?: boolean
}
@ -30,6 +31,7 @@ export const LINE_LIST: PresetLine[] = [
type: '折线、曲线',
children: [
{ path: 'M 0 0 L 0 20 L 20 20', style: 'solid', points: ['', 'arrow'], isBroken: true },
{ path: 'M 0 0 L 10 0 L 10 20 L 20 20', style: 'solid', points: ['', 'arrow'], isBroken2: true },
{ path: 'M 0 0 Q 0 20 20 20', style: 'solid', points: ['', 'arrow'], isCurve: true },
{ path: 'M 0 0 C 20 0 0 20 20 20', style: 'solid', points: ['', 'arrow'], isCubic: true },
],

View File

@ -265,6 +265,7 @@ export default () => {
width: 2,
}
if (data.isBroken) newElement.broken = [(start[0] + end[0]) / 2, (start[1] + end[1]) / 2]
if (data.isBroken2) newElement.broken2 = [(start[0] + end[0]) / 2, (start[1] + end[1]) / 2]
if (data.isCurve) newElement.curve = [(start[0] + end[0]) / 2, (start[1] + end[1]) / 2]
if (data.isCubic) newElement.cubic = [[(start[0] + end[0]) / 2, (start[1] + end[1]) / 2], [(start[0] + end[0]) / 2, (start[1] + end[1]) / 2]]
createElement(newElement)

View File

@ -361,6 +361,8 @@ export type LinePoint = '' | 'arrow' | 'dot'
*
* broken?: 折线控制点位置[x, y]
*
* broken2?: 双折线控制点位置[x, y]
*
* curve?: 二次曲线控制点位置[x, y]
*
* cubic?: 三次曲线控制点位置[[x1, y1], [x2, y2]]
@ -374,6 +376,7 @@ export interface PPTLineElement extends Omit<PPTBaseElement, 'height' | 'rotate'
points: [LinePoint, LinePoint]
shadow?: PPTElementShadow
broken?: [number, number]
broken2?: [number, number]
curve?: [number, number]
cubic?: [[number, number], [number, number]]
}

View File

@ -214,6 +214,11 @@ export const getLineElementPath = (element: PPTLineElement) => {
const mid = element.broken.join(',')
return `M${start} L${mid} L${end}`
}
else if (element.broken2) {
const { minX, maxX, minY, maxY } = getElementRange(element)
if (maxX - minX >= maxY - minY) return `M${start} L${element.broken2[0]},${element.start[1]} L${element.broken2[0]},${element.end[1]} ${end}`
return `M${start} L${element.start[0]},${element.broken2[1]} L${element.end[0]},${element.broken2[1]} ${end}`
}
else if (element.curve) {
const mid = element.curve.join(',')
return `M${start} Q${mid} ${end}`

View File

@ -77,8 +77,8 @@ const resizeHandlers = computed(() => {
},
]
if (props.elementInfo.curve || props.elementInfo.broken) {
const ctrlHandler = (props.elementInfo.curve || props.elementInfo.broken) as [number, number]
if (props.elementInfo.curve || props.elementInfo.broken || props.elementInfo.broken2) {
const ctrlHandler = (props.elementInfo.curve || props.elementInfo.broken || props.elementInfo.broken2) as [number, number]
handlers.push({
handler: OperateLineHandlers.C,

View File

@ -79,7 +79,7 @@ export default (elementList: Ref<PPTElement[]>) => {
let endX = element.left + element.end[0]
let endY = element.top + element.end[1]
const mid = element.broken || element.curve || [0, 0]
const mid = element.broken || element.broken2 || element.curve || [0, 0]
let midX = element.left + mid[0]
let midY = element.top + mid[1]
@ -192,10 +192,15 @@ export default (elementList: Ref<PPTElement[]>) => {
if (element.curve) newEl.curve = [(start[0] + end[0]) / 2, (start[1] + end[1]) / 2]
if (element.cubic) newEl.cubic = [[(start[0] + end[0]) / 2, (start[1] + end[1]) / 2], [(start[0] + end[0]) / 2, (start[1] + end[1]) / 2]]
}
if (element.broken2) newEl.broken2 = [(start[0] + end[0]) / 2, (start[1] + end[1]) / 2]
}
else if (command === OperateLineHandlers.C) {
if (element.broken) newEl.broken = [midX - minX, midY - minY]
if (element.curve) newEl.curve = [midX - minX, midY - minY]
if (element.broken2) {
if (maxX - minX >= maxY - minY) newEl.broken2 = [midX - minX, newEl.broken2![1]]
else newEl.broken2 = [newEl.broken2![0], midY - minY]
}
}
else {
if (element.cubic) newEl.cubic = [[c1X - minX, c1Y - minY], [c2X - minX, c2Y - minY]]