Image width/height for gallery component, don't save ImageCache props
This commit is contained in:
71
src/lib/components/gradio/image/StaticImage.svelte
Normal file
71
src/lib/components/gradio/image/StaticImage.svelte
Normal file
@@ -0,0 +1,71 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import type { SelectData } from "@gradio/utils";
|
||||
import { BlockLabel, Empty, IconButton } from "@gradio/atoms";
|
||||
import { Download } from "@gradio/icons";
|
||||
import { get_coordinates_of_clicked_image } from "./utils";
|
||||
|
||||
import { Image } from "@gradio/icons";
|
||||
|
||||
export let value: null | string;
|
||||
export let label: string | undefined = undefined;
|
||||
export let show_label: boolean;
|
||||
export let selectable: boolean = false;
|
||||
export let imageWidth: number = 1;
|
||||
export let imageHeight: number = 1;
|
||||
let imageElem: HTMLImageElement | null = null;
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
change: string;
|
||||
select: SelectData;
|
||||
}>();
|
||||
|
||||
$: value && dispatch("change", value);
|
||||
|
||||
$: if (value == null || !imageElem) {
|
||||
imageWidth = 1;
|
||||
imageHeight = 1;
|
||||
}
|
||||
|
||||
const handle_click = (evt: MouseEvent) => {
|
||||
let coordinates = get_coordinates_of_clicked_image(evt);
|
||||
if (coordinates) {
|
||||
dispatch("select", { index: coordinates, value: null });
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<BlockLabel {show_label} Icon={Image} label={label || "Image"} />
|
||||
{#if value === null}
|
||||
<Empty size="large" unpadded_box={true}><Image /></Empty>
|
||||
{:else}
|
||||
<div class="download">
|
||||
<a
|
||||
href={value}
|
||||
target={window.__is_colab__ ? "_blank" : null}
|
||||
download={"image"}
|
||||
>
|
||||
<IconButton Icon={Download} label="Download" />
|
||||
</a>
|
||||
</div>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<img src={value} alt="" class:selectable on:click={handle_click} bind:naturalWidth={imageWidth} bind:naturalHeight={imageHeight} />
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
img {
|
||||
width: var(--size-full);
|
||||
height: var(--size-full);
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.selectable {
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.download {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 6px;
|
||||
}
|
||||
</style>
|
||||
1
src/lib/components/gradio/image/index.ts
Normal file
1
src/lib/components/gradio/image/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as StaticImage } from "./StaticImage.svelte"
|
||||
26
src/lib/components/gradio/image/utils.ts
Normal file
26
src/lib/components/gradio/image/utils.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
export const get_coordinates_of_clicked_image = (
|
||||
evt: MouseEvent
|
||||
): [number, number] | null => {
|
||||
let image = evt.currentTarget as HTMLImageElement;
|
||||
|
||||
const imageRect = image.getBoundingClientRect();
|
||||
const xScale = image.naturalWidth / imageRect.width;
|
||||
const yScale = image.naturalHeight / imageRect.height;
|
||||
if (xScale > yScale) {
|
||||
const displayed_width = imageRect.width;
|
||||
const displayed_height = image.naturalHeight / xScale;
|
||||
const y_offset = (imageRect.height - displayed_height) / 2;
|
||||
var x = Math.round((evt.clientX - imageRect.left) * xScale);
|
||||
var y = Math.round((evt.clientY - imageRect.top - y_offset) * xScale);
|
||||
} else {
|
||||
const displayed_width = image.naturalWidth / yScale;
|
||||
const displayed_height = imageRect.height;
|
||||
const x_offset = (imageRect.width - displayed_width) / 2;
|
||||
var x = Math.round((evt.clientX - imageRect.left - x_offset) * yScale);
|
||||
var y = Math.round((evt.clientY - imageRect.top) * yScale);
|
||||
}
|
||||
if (x < 0 || x >= image.naturalWidth || y < 0 || y >= image.naturalHeight) {
|
||||
return null;
|
||||
}
|
||||
return [x, y];
|
||||
};
|
||||
Reference in New Issue
Block a user