mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 10:08:34 +00:00
feat: improve middleware scroller
This commit is contained in:
parent
4781931eb1
commit
eef66ff7c4
1 changed files with 68 additions and 70 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import type { Point, BoardViewerFrameSnapshot, ViewScaleInfo, ViewSizeInfo, ViewContext2D, ElementSize } from '@idraw/types';
|
||||
import type { Point, PointSize, BoardViewerFrameSnapshot, ViewScaleInfo, ViewSizeInfo, ViewContext2D, ElementSize } from '@idraw/types';
|
||||
import { getViewScaleInfoFromSnapshot, getViewSizeInfoFromSnapshot } from '@idraw/util';
|
||||
import { keyActivePoint, keyActiveThumbType, keyPrevPoint, keyXThumbRect, keyYThumbRect } from './config';
|
||||
|
||||
const minScrollerWidth = 12;
|
||||
const scrollerLineWidth = 16;
|
||||
|
|
@ -14,40 +15,6 @@ const scrollConfig = {
|
|||
showBackground: true
|
||||
};
|
||||
|
||||
function isPointAtScrollbarY(helperContext: ViewContext2D, p: Point, viewSizeInfo: ViewSizeInfo): boolean {
|
||||
const { width, height } = viewSizeInfo;
|
||||
const ctx = helperContext;
|
||||
ctx.beginPath();
|
||||
ctx.rect(width - scrollConfig.width, 0, scrollConfig.width, height);
|
||||
ctx.closePath();
|
||||
if (ctx.isPointInPath(p.x, p.y)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isPointAtScrollbarX(helperContext: ViewContext2D, p: Point, viewSizeInfo: ViewSizeInfo): boolean {
|
||||
const { width, height } = viewSizeInfo;
|
||||
const ctx = helperContext;
|
||||
ctx.beginPath();
|
||||
ctx.rect(0, height - scrollConfig.width, width - scrollConfig.width, scrollConfig.width);
|
||||
ctx.closePath();
|
||||
if (ctx.isPointInPath(p.x, p.y)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isPointInScrollbar(helperContext: ViewContext2D, p: Point, viewSizeInfo: ViewSizeInfo): ScrollbarThumbType | null {
|
||||
let thumbType: ScrollbarThumbType | null = null;
|
||||
if (isPointAtScrollbarX(helperContext, p, viewSizeInfo)) {
|
||||
thumbType = 'X';
|
||||
} else if (isPointAtScrollbarY(helperContext, p, viewSizeInfo)) {
|
||||
thumbType = 'Y';
|
||||
}
|
||||
return thumbType;
|
||||
}
|
||||
|
||||
function isPointAtRect(helperContext: ViewContext2D, p: Point, rect: ElementSize): boolean {
|
||||
const ctx = helperContext;
|
||||
const { x, y, w, h } = rect;
|
||||
|
|
@ -78,6 +45,25 @@ export function isPointInScrollThumb(
|
|||
return thumbType;
|
||||
}
|
||||
|
||||
interface ScrollInfo {
|
||||
activePoint: Point | null;
|
||||
prevPoint: Point | null;
|
||||
activeThumbType: ScrollbarThumbType | null;
|
||||
xThumbRect: ElementSize | null;
|
||||
yThumbRect: ElementSize | null;
|
||||
}
|
||||
function getScrollInfoFromSnapshot(snapshot: BoardViewerFrameSnapshot): ScrollInfo {
|
||||
const { sharedStore } = snapshot;
|
||||
const info: ScrollInfo = {
|
||||
activePoint: sharedStore[keyActivePoint] || null,
|
||||
prevPoint: sharedStore[keyPrevPoint] || null,
|
||||
activeThumbType: sharedStore[keyActiveThumbType] || null,
|
||||
xThumbRect: sharedStore[keyXThumbRect] || null,
|
||||
yThumbRect: sharedStore[keyYThumbRect] || null
|
||||
};
|
||||
return info;
|
||||
}
|
||||
|
||||
function calcScrollerInfo(viewScaleInfo: ViewScaleInfo, viewSizeInfo: ViewSizeInfo) {
|
||||
const { width, height } = viewSizeInfo;
|
||||
const { offsetTop, offsetBottom, offsetLeft, offsetRight } = viewScaleInfo;
|
||||
|
|
@ -196,48 +182,59 @@ function drawScrollerThumb(
|
|||
ctx.stroke();
|
||||
}
|
||||
|
||||
function drawScrollerInfo(helperContext: ViewContext2D, opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }) {
|
||||
function drawScrollerInfo(helperContext: ViewContext2D, opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo; scrollInfo: ScrollInfo }) {
|
||||
const ctx = helperContext;
|
||||
const { viewScaleInfo, viewSizeInfo } = opts;
|
||||
const { viewScaleInfo, viewSizeInfo, scrollInfo } = opts;
|
||||
const { activeThumbType, prevPoint, activePoint } = scrollInfo;
|
||||
const { width, height } = viewSizeInfo;
|
||||
const wrapper = calcScrollerInfo(viewScaleInfo, viewSizeInfo);
|
||||
const { xThumbRect, yThumbRect } = wrapper;
|
||||
if (wrapper.xSize > 0) {
|
||||
if (scrollConfig.showBackground === true) {
|
||||
ctx.globalAlpha = scrollerAlpha;
|
||||
ctx.fillStyle = wrapper.color;
|
||||
// x-line
|
||||
ctx.fillRect(0, height - wrapper.lineSize, width, wrapper.lineSize);
|
||||
}
|
||||
let xThumbRect: ElementSize = { ...wrapper.xThumbRect };
|
||||
let yThumbRect: ElementSize = { ...wrapper.yThumbRect };
|
||||
|
||||
// ctx.globalAlpha = 1;
|
||||
// x-slider
|
||||
drawScrollerThumb(ctx, {
|
||||
axis: 'X',
|
||||
...xThumbRect,
|
||||
r: wrapper.lineSize / 2,
|
||||
color: wrapper.color
|
||||
});
|
||||
if (activeThumbType && prevPoint && activePoint) {
|
||||
if (activeThumbType === 'X' && scrollInfo.xThumbRect) {
|
||||
xThumbRect = { ...scrollInfo.xThumbRect };
|
||||
xThumbRect.x = xThumbRect.x + (activePoint.x - prevPoint.x);
|
||||
} else if (activeThumbType === 'Y' && scrollInfo.yThumbRect) {
|
||||
yThumbRect = { ...scrollInfo.yThumbRect };
|
||||
yThumbRect.y = yThumbRect.y + (activePoint.y - prevPoint.y);
|
||||
}
|
||||
}
|
||||
|
||||
if (wrapper.ySize > 0) {
|
||||
if (scrollConfig.showBackground === true) {
|
||||
ctx.globalAlpha = scrollerAlpha;
|
||||
ctx.fillStyle = wrapper.color;
|
||||
// y-line
|
||||
ctx.fillRect(width - wrapper.lineSize, 0, wrapper.lineSize, height);
|
||||
}
|
||||
|
||||
// ctx.globalAlpha = 1;
|
||||
// y-slider
|
||||
drawScrollerThumb(ctx, {
|
||||
axis: 'Y',
|
||||
...yThumbRect,
|
||||
r: wrapper.lineSize / 2,
|
||||
color: wrapper.color
|
||||
});
|
||||
// x-bar
|
||||
if (scrollConfig.showBackground === true) {
|
||||
ctx.globalAlpha = scrollerAlpha;
|
||||
ctx.fillStyle = wrapper.color;
|
||||
// x-line
|
||||
ctx.fillRect(0, height - wrapper.lineSize, width, wrapper.lineSize);
|
||||
}
|
||||
|
||||
// ctx.globalAlpha = 1;
|
||||
// x-thumb
|
||||
drawScrollerThumb(ctx, {
|
||||
axis: 'X',
|
||||
...xThumbRect,
|
||||
r: wrapper.lineSize / 2,
|
||||
color: wrapper.color
|
||||
});
|
||||
|
||||
// y-bar
|
||||
if (scrollConfig.showBackground === true) {
|
||||
ctx.globalAlpha = scrollerAlpha;
|
||||
ctx.fillStyle = wrapper.color;
|
||||
// y-line
|
||||
ctx.fillRect(width - wrapper.lineSize, 0, wrapper.lineSize, height);
|
||||
}
|
||||
|
||||
// ctx.globalAlpha = 1;
|
||||
// y-thumb
|
||||
drawScrollerThumb(ctx, {
|
||||
axis: 'Y',
|
||||
...yThumbRect,
|
||||
r: wrapper.lineSize / 2,
|
||||
color: wrapper.color
|
||||
});
|
||||
|
||||
ctx.globalAlpha = 1;
|
||||
return {
|
||||
xThumbRect,
|
||||
|
|
@ -249,6 +246,7 @@ export function drawScroller(ctx: ViewContext2D, opts: { snapshot: BoardViewerFr
|
|||
const { snapshot } = opts;
|
||||
const viewSizeInfo = getViewSizeInfoFromSnapshot(snapshot);
|
||||
const viewScaleInfo = getViewScaleInfoFromSnapshot(snapshot);
|
||||
const { xThumbRect, yThumbRect } = drawScrollerInfo(ctx, { viewSizeInfo, viewScaleInfo });
|
||||
const scrollInfo = getScrollInfoFromSnapshot(snapshot);
|
||||
const { xThumbRect, yThumbRect } = drawScrollerInfo(ctx, { viewSizeInfo, viewScaleInfo, scrollInfo });
|
||||
return { xThumbRect, yThumbRect };
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue