added fit to page button for canvas
This commit is contained in:
parent
fcfa06f691
commit
5227c0acea
@ -1,35 +1,45 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {
|
import {
|
||||||
ZoomInOutline,
|
ZoomInOutline,
|
||||||
ZoomOutOutline,
|
ZoomOutOutline,
|
||||||
RefreshOutline,
|
RefreshOutline,
|
||||||
} from "flowbite-svelte-icons";
|
MinimizeOutline
|
||||||
|
} from 'flowbite-svelte-icons';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
scale,
|
scale,
|
||||||
onZoomIn,
|
onZoomIn,
|
||||||
onZoomOut,
|
onZoomOut,
|
||||||
resetZoom,
|
resetZoom,
|
||||||
}: {
|
fit,
|
||||||
scale: number;
|
showFit
|
||||||
onZoomIn: () => void;
|
}: {
|
||||||
onZoomOut: () => void;
|
scale: number;
|
||||||
resetZoom: () => void;
|
onZoomIn: () => void;
|
||||||
} = $props();
|
onZoomOut: () => void;
|
||||||
|
resetZoom: () => void;
|
||||||
|
fit: () => void;
|
||||||
|
showFit: boolean;
|
||||||
|
} = $props();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<span class="zoom-level">{(scale * 100).toFixed(0)}%</span>
|
<span class="zoom-level">{(scale * 100).toFixed(0)}%</span>
|
||||||
<button class="control-button" onclick={onZoomIn}>
|
{#if showFit}
|
||||||
<ZoomInOutline />
|
<button class="control-button" onclick={fit}>
|
||||||
</button>
|
<MinimizeOutline />
|
||||||
<button class="control-button" onclick={onZoomOut}>
|
</button>
|
||||||
<ZoomOutOutline />
|
{/if}
|
||||||
</button>
|
<button class="control-button" onclick={onZoomIn}>
|
||||||
<button class="control-button" onclick={resetZoom}>
|
<ZoomInOutline />
|
||||||
<RefreshOutline />
|
</button>
|
||||||
</button>
|
<button class="control-button" onclick={onZoomOut}>
|
||||||
|
<ZoomOutOutline />
|
||||||
|
</button>
|
||||||
|
<button class="control-button" onclick={resetZoom}>
|
||||||
|
<RefreshOutline />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import ZoomControls from '../components/ZoomControls.svelte';
|
import ZoomControls from '../components/ZoomControls.svelte';
|
||||||
import { onMount } from 'svelte';
|
|
||||||
|
|
||||||
type ZoomableProps = {
|
type ZoomableProps = {
|
||||||
minZoom?: number;
|
minZoom?: number;
|
||||||
@ -12,7 +11,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
let {
|
let {
|
||||||
minZoom = 0.5,
|
minZoom = 0.1,
|
||||||
maxZoom = 10,
|
maxZoom = 10,
|
||||||
zoomStep = 0.1,
|
zoomStep = 0.1,
|
||||||
imgUrl,
|
imgUrl,
|
||||||
@ -21,6 +20,8 @@
|
|||||||
}: ZoomableProps = $props();
|
}: ZoomableProps = $props();
|
||||||
|
|
||||||
let currentImgUrl = $state(imgUrl);
|
let currentImgUrl = $state(imgUrl);
|
||||||
|
let image: HTMLImageElement | undefined = $state(undefined);
|
||||||
|
let container = $state<HTMLDivElement>();
|
||||||
|
|
||||||
type ViewState = {
|
type ViewState = {
|
||||||
x: number;
|
x: number;
|
||||||
@ -35,7 +36,6 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// DOM refs
|
// DOM refs
|
||||||
let container = $state<HTMLElement>();
|
|
||||||
|
|
||||||
// Drag state
|
// Drag state
|
||||||
type DragState = {
|
type DragState = {
|
||||||
@ -94,6 +94,20 @@
|
|||||||
dragState = undefined;
|
dragState = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fitCanvasToPage() {
|
||||||
|
if (!canvas || !container) return;
|
||||||
|
const w = canvas.width;
|
||||||
|
const h = canvas.height;
|
||||||
|
const targetWidth = container.offsetWidth;
|
||||||
|
const targetHeight = container.offsetHeight;
|
||||||
|
|
||||||
|
const wScale = targetWidth / w;
|
||||||
|
const hScale = targetHeight / h;
|
||||||
|
viewState.scale = Math.min(maxZoom, Math.max(minZoom, Math.min(wScale, hScale)));
|
||||||
|
viewState.x = 0;
|
||||||
|
viewState.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
function resetZoom() {
|
function resetZoom() {
|
||||||
viewState.scale = 1;
|
viewState.scale = 1;
|
||||||
if (container) {
|
if (container) {
|
||||||
@ -122,9 +136,11 @@
|
|||||||
<div class="relative w-full h-full">
|
<div class="relative w-full h-full">
|
||||||
<ZoomControls
|
<ZoomControls
|
||||||
scale={viewState.scale}
|
scale={viewState.scale}
|
||||||
onZoomIn={() => (viewState.scale = Math.min(viewState.scale + zoomStep, maxZoom))}
|
onZoomIn={() => (viewState.scale = Math.min(viewState.scale + (zoomStep * viewState.scale), maxZoom))}
|
||||||
onZoomOut={() => (viewState.scale = Math.max(viewState.scale - zoomStep, minZoom))}
|
onZoomOut={() => (viewState.scale = Math.max(viewState.scale - (zoomStep * viewState.scale), minZoom))}
|
||||||
{resetZoom}
|
{resetZoom}
|
||||||
|
fit={fitCanvasToPage}
|
||||||
|
showFit={!image}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="container"
|
class="container"
|
||||||
@ -140,6 +156,7 @@
|
|||||||
{#if imgUrl}
|
{#if imgUrl}
|
||||||
<img
|
<img
|
||||||
class="zoomimage"
|
class="zoomimage"
|
||||||
|
bind:this={image}
|
||||||
alt="rendered-page"
|
alt="rendered-page"
|
||||||
src={currentImgUrl}
|
src={currentImgUrl}
|
||||||
style:transform="translate({viewState.x}px, {viewState.y}px) scale({viewState.scale})"
|
style:transform="translate({viewState.x}px, {viewState.y}px) scale({viewState.scale})"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user