diff --git a/packages/core/src/ruler.ts b/packages/core/src/ruler.ts index 600320b..8aefd96 100644 --- a/packages/core/src/ruler.ts +++ b/packages/core/src/ruler.ts @@ -2,7 +2,7 @@ import { getClosestTimesVal, nearestPixelVal } from '@suika/common'; import { HALF_PI } from './constant'; import { type SuikaEditor } from './editor'; -import { rotateInCanvas } from './utils'; +import { mergeIntervals, rotateInCanvas } from './utils'; const getStepByZoom = (zoom: number) => { /** @@ -55,6 +55,8 @@ class Ruler { ctx.fillRect(0, 0, viewportWidth, setting.get('rulerWidth')); ctx.fillRect(0, 0, setting.get('rulerWidth'), viewportHeight); + this.drawSelectArea(); + this.drawXRuler(); this.drawYRuler(); @@ -79,6 +81,40 @@ class Ruler { ctx.restore(); } + private drawSelectArea() { + const setting = this.editor.setting; + const ctx = this.editor.ctx; + const zoom = this.editor.zoomManager.getZoom(); + const viewport = this.editor.viewportManager.getViewport(); + + const bboxes = this.editor.selectedElements + .getItems({ + excludeLocked: true, + }) + .map((item) => item.getBbox()); + + ctx.fillStyle = setting.get('rulerSelectedBgColor'); + for (const [minX, maxX] of mergeIntervals( + bboxes.map(({ minX, maxX }) => [minX, maxX]), + )) { + ctx.fillRect( + (minX - viewport.x) * zoom, + 0, + (maxX - minX) * zoom, + setting.get('rulerWidth'), + ); + } + for (const [minY, maxY] of mergeIntervals( + bboxes.map(({ minY, maxY }) => [minY, maxY]), + )) { + ctx.fillRect( + 0, + (minY - viewport.y) * zoom, + setting.get('rulerWidth'), + (maxY - minY) * zoom, + ); + } + } private drawXRuler() { // 绘制刻度线和刻度值 // 计算 x 轴起点和终点范围 diff --git a/packages/core/src/setting.ts b/packages/core/src/setting.ts index 8e261e6..ab7e741 100644 --- a/packages/core/src/setting.ts +++ b/packages/core/src/setting.ts @@ -97,6 +97,7 @@ export class Setting { rulerBgColor: '#fff', rulerStroke: '#e6e6e6', rulerMarkStroke: '#c1c1c1', + rulerSelectedBgColor: '#e6f5ff', rulerWidth: 20, // 宽度 rulerMarkSize: 4, // 刻度高度 diff --git a/packages/core/src/utils/geo.ts b/packages/core/src/utils/geo.ts index b1e4f14..bfa4884 100644 --- a/packages/core/src/utils/geo.ts +++ b/packages/core/src/utils/geo.ts @@ -70,3 +70,17 @@ export const adjustSizeToKeepPolarSnap = (rect: IRect): IRect => { } return rect; }; + +export const mergeIntervals = (intervals: [number, number][]) => { + intervals.sort(([a], [b]) => a - b); + const result: [number, number][] = []; + for (const [prev, next] of intervals) { + const cur = result.at(-1); + if (cur && cur[1] >= prev) { + cur[1] = Math.max(next, cur[1]); + } else { + result.push([prev, next]); + } + } + return result; +};