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