From a8c6552bf814b70abe5b8185c5543ba1c0d0092c Mon Sep 17 00:00:00 2001 From: redhoodsu Date: Sat, 17 Feb 2024 18:12:57 +0800 Subject: [PATCH] feat(painter): fit and fill screen --- src/painter/tools/Hand.ts | 20 ++++++- src/painter/tools/Zoom.ts | 106 ++++++++++++++++++++++++++------------ 2 files changed, 93 insertions(+), 33 deletions(-) diff --git a/src/painter/tools/Hand.ts b/src/painter/tools/Hand.ts index 0267a91..abadc48 100644 --- a/src/painter/tools/Hand.ts +++ b/src/painter/tools/Hand.ts @@ -43,7 +43,7 @@ export default class Hand extends Tool { protected renderToolbar() { super.renderToolbar() - const { toolbar } = this + const { toolbar, painter } = this toolbar.appendButton( '100%', () => { @@ -52,6 +52,24 @@ export default class Hand extends Tool { }, 'hover' ) + toolbar.appendButton( + 'Fit Screen', + () => { + const zoom = painter.getTool('zoom') as Zoom + zoom.fitScreen() + this.centerCanvas() + }, + 'hover' + ) + toolbar.appendButton( + 'Fill Screen', + () => { + const zoom = painter.getTool('zoom') as Zoom + zoom.fillScreen() + this.centerCanvas() + }, + 'hover' + ) } private bindEvent() { const { painter } = this diff --git a/src/painter/tools/Zoom.ts b/src/painter/tools/Zoom.ts index 10ebcaf..6a727a2 100644 --- a/src/painter/tools/Zoom.ts +++ b/src/painter/tools/Zoom.ts @@ -1,5 +1,6 @@ import Tool from './Tool' import Painter from '../index' +import Hand from './Hand' import Tween from 'licia/Tween' import $ from 'licia/$' import h from 'licia/h' @@ -58,12 +59,12 @@ export default class Zoom extends Tool { zoom(ratio: number, pivot?: IPivot) { ratio = ratio < 0 ? 1 / (1 - ratio) : 1 + ratio const offset = this.$canvas.offset() - this.zoomTo((offset.width * ratio) / this.canvas.width, pivot) + this.zoomTo((offset.width * ratio) / this.canvas.width, true, pivot) } getRatio() { return this.ratio } - zoomTo(ratio: number, pivot?: IPivot) { + zoomTo(ratio: number, animation = true, pivot?: IPivot) { if (this.isZooming) { return } @@ -104,39 +105,50 @@ export default class Zoom extends Tool { const newScrollTop = scrollTop + deltaMarginTop + deltaHeight * ((pivot.y - top) / height) - const tween = new Tween({ - scrollLeft, - scrollTop, - width, - height, - }) + if (animation) { + const tween = new Tween({ + scrollLeft, + scrollTop, + width, + height, + }) - tween - .on('update', (target) => { - $canvas.css({ - width: target.width, - height: target.height, + tween + .on('update', (target) => { + $canvas.css({ + width: target.width, + height: target.height, + }) + viewport.scrollLeft = target.scrollLeft + viewport.scrollTop = target.scrollTop + this.emit('change') + }) + .on('end', () => { + this.isZooming = false }) - viewport.scrollLeft = target.scrollLeft - viewport.scrollTop = target.scrollTop - this.emit('change') - }) - .on('end', () => { - this.isZooming = false - }) - tween - .to( - { - scrollLeft: newScrollLeft, - scrollTop: newScrollTop, - width: newWidth, - height: newHeight, - }, - 300, - 'linear' - ) - .play() + tween + .to( + { + scrollLeft: newScrollLeft, + scrollTop: newScrollTop, + width: newWidth, + height: newHeight, + }, + 300, + 'linear' + ) + .play() + } else { + $canvas.css({ + width: newWidth, + height: newHeight, + }) + viewport.scrollLeft = newScrollLeft + viewport.scrollTop = newScrollTop + this.emit('change') + this.isZooming = false + } } setOption(name: string, val: any, renderToolbar?: boolean) { super.setOption(name, val, renderToolbar) @@ -147,6 +159,18 @@ export default class Zoom extends Tool { $icon.addClass(c(`icon-zoom-${val}`)) } } + fitScreen() { + const { canvas, viewport } = this + const sx = viewport.clientWidth / canvas.width + const sy = viewport.clientHeight / canvas.height + this.zoomTo(Math.min(sx, sy), false) + } + fillScreen() { + const { canvas, viewport } = this + const sx = viewport.clientWidth / canvas.width + const sy = viewport.clientHeight / canvas.height + this.zoomTo(Math.max(sx, sy), false) + } protected renderToolbar() { super.renderToolbar() @@ -177,6 +201,24 @@ export default class Zoom extends Tool { }, 'hover' ) + toolbar.appendButton( + 'Fit Screen', + () => { + this.fitScreen() + const hand = painter.getTool('hand') as Hand + hand.centerCanvas() + }, + 'hover' + ) + toolbar.appendButton( + 'Fill Screen', + () => { + this.fillScreen() + const hand = painter.getTool('hand') as Hand + hand.centerCanvas() + }, + 'hover' + ) } private bindEvent() { this.$viewport.on('wheel', this.onWheel)