@gradio/image 0.13.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/Image.stories.svelte +21 -0
- package/Index.svelte +2 -0
- package/package.json +8 -8
- package/shared/ImagePreview.svelte +87 -25
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# @gradio/image
|
2
2
|
|
3
|
+
## 0.14.0
|
4
|
+
|
5
|
+
### Features
|
6
|
+
|
7
|
+
- [#8964](https://github.com/gradio-app/gradio/pull/8964) [`bf6bbd9`](https://github.com/gradio-app/gradio/commit/bf6bbd971acddbf78f03bea431ed7d1e0003ccf9) - Add min/max-imize button to gr.Image and gr.Gallery. Thanks @hannahblair!
|
8
|
+
|
9
|
+
### Dependency updates
|
10
|
+
|
11
|
+
- @gradio/atoms@0.7.9
|
12
|
+
- @gradio/statustracker@0.7.4
|
13
|
+
- @gradio/client@1.5.0
|
14
|
+
- @gradio/icons@0.7.0
|
15
|
+
- @gradio/upload@0.12.2
|
16
|
+
|
3
17
|
## 0.13.1
|
4
18
|
|
5
19
|
### Dependency updates
|
package/Image.stories.svelte
CHANGED
@@ -40,6 +40,27 @@
|
|
40
40
|
}}
|
41
41
|
/>
|
42
42
|
|
43
|
+
<Story
|
44
|
+
name="static with label and download button"
|
45
|
+
args={{
|
46
|
+
value: {
|
47
|
+
path: "https://gradio-builds.s3.amazonaws.com/demo-files/ghepardo-primo-piano.jpg",
|
48
|
+
url: "https://gradio-builds.s3.amazonaws.com/demo-files/ghepardo-primo-piano.jpg",
|
49
|
+
orig_name: "cheetah.jpg"
|
50
|
+
},
|
51
|
+
show_label: true,
|
52
|
+
show_download_button: true
|
53
|
+
}}
|
54
|
+
play={async ({ canvasElement }) => {
|
55
|
+
const canvas = within(canvasElement);
|
56
|
+
|
57
|
+
const expand_btn = canvas.getByRole("button", {
|
58
|
+
name: "View in full screen"
|
59
|
+
});
|
60
|
+
await userEvent.click(expand_btn);
|
61
|
+
}}
|
62
|
+
/>
|
63
|
+
|
43
64
|
<Story
|
44
65
|
name="static with no label or download button"
|
45
66
|
args={{
|
package/Index.svelte
CHANGED
@@ -51,6 +51,7 @@
|
|
51
51
|
export let streaming: boolean;
|
52
52
|
export let pending: boolean;
|
53
53
|
export let mirror_webcam: boolean;
|
54
|
+
export let show_fullscreen_button: boolean;
|
54
55
|
|
55
56
|
export let gradio: Gradio<{
|
56
57
|
input: never;
|
@@ -114,6 +115,7 @@
|
|
114
115
|
selectable={_selectable}
|
115
116
|
{show_share_button}
|
116
117
|
i18n={gradio.i18n}
|
118
|
+
{show_fullscreen_button}
|
117
119
|
/>
|
118
120
|
</Block>
|
119
121
|
{:else}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@gradio/image",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.14.0",
|
4
4
|
"description": "Gradio UI packages",
|
5
5
|
"type": "module",
|
6
6
|
"author": "",
|
@@ -10,13 +10,13 @@
|
|
10
10
|
"cropperjs": "^1.5.12",
|
11
11
|
"lazy-brush": "^1.0.1",
|
12
12
|
"resize-observer-polyfill": "^1.5.1",
|
13
|
-
"@gradio/atoms": "^0.7.
|
14
|
-
"@gradio/icons": "^0.
|
15
|
-
"@gradio/statustracker": "^0.7.
|
16
|
-
"@gradio/
|
17
|
-
"@gradio/
|
18
|
-
"@gradio/
|
19
|
-
"@gradio/
|
13
|
+
"@gradio/atoms": "^0.7.9",
|
14
|
+
"@gradio/icons": "^0.7.0",
|
15
|
+
"@gradio/statustracker": "^0.7.4",
|
16
|
+
"@gradio/client": "^1.5.0",
|
17
|
+
"@gradio/upload": "^0.12.2",
|
18
|
+
"@gradio/utils": "^0.5.2",
|
19
|
+
"@gradio/wasm": "^0.12.0"
|
20
20
|
},
|
21
21
|
"devDependencies": {
|
22
22
|
"@gradio/preview": "^0.10.2"
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<script lang="ts">
|
2
|
-
import { createEventDispatcher } from "svelte";
|
2
|
+
import { createEventDispatcher, onMount } from "svelte";
|
3
3
|
import type { SelectData } from "@gradio/utils";
|
4
4
|
import { uploadToHuggingFace } from "@gradio/utils";
|
5
5
|
import { BlockLabel, Empty, IconButton, ShareButton } from "@gradio/atoms";
|
@@ -7,6 +7,7 @@
|
|
7
7
|
import { get_coordinates_of_clicked_image } from "./utils";
|
8
8
|
import Image from "./Image.svelte";
|
9
9
|
import { DownloadLink } from "@gradio/wasm/svelte";
|
10
|
+
import { Maximize, Minimize } from "@gradio/icons";
|
10
11
|
|
11
12
|
import { Image as ImageIcon } from "@gradio/icons";
|
12
13
|
import { type FileData } from "@gradio/client";
|
@@ -19,6 +20,7 @@
|
|
19
20
|
export let selectable = false;
|
20
21
|
export let show_share_button = false;
|
21
22
|
export let i18n: I18nFormatter;
|
23
|
+
export let show_fullscreen_button = true;
|
22
24
|
|
23
25
|
const dispatch = createEventDispatcher<{
|
24
26
|
change: string;
|
@@ -31,6 +33,24 @@
|
|
31
33
|
dispatch("select", { index: coordinates, value: null });
|
32
34
|
}
|
33
35
|
};
|
36
|
+
|
37
|
+
let is_full_screen = false;
|
38
|
+
let image_container: HTMLElement;
|
39
|
+
|
40
|
+
onMount(() => {
|
41
|
+
document.addEventListener("fullscreenchange", () => {
|
42
|
+
is_full_screen = !!document.fullscreenElement;
|
43
|
+
});
|
44
|
+
});
|
45
|
+
|
46
|
+
const toggle_full_screen = async (): Promise<void> => {
|
47
|
+
if (!is_full_screen) {
|
48
|
+
await image_container.requestFullscreen();
|
49
|
+
} else {
|
50
|
+
await document.exitFullscreen();
|
51
|
+
is_full_screen = !is_full_screen;
|
52
|
+
}
|
53
|
+
};
|
34
54
|
</script>
|
35
55
|
|
36
56
|
<BlockLabel
|
@@ -41,36 +61,55 @@
|
|
41
61
|
{#if value === null || !value.url}
|
42
62
|
<Empty unpadded_box={true} size="large"><ImageIcon /></Empty>
|
43
63
|
{:else}
|
44
|
-
<div class="
|
45
|
-
|
46
|
-
|
47
|
-
<IconButton
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
<div class="image-container" bind:this={image_container}>
|
65
|
+
<div class="icon-buttons">
|
66
|
+
{#if !is_full_screen && show_fullscreen_button}
|
67
|
+
<IconButton
|
68
|
+
Icon={Maximize}
|
69
|
+
label={is_full_screen ? "Exit full screen" : "View in full screen"}
|
70
|
+
on:click={toggle_full_screen}
|
71
|
+
/>
|
72
|
+
{/if}
|
73
|
+
|
74
|
+
{#if is_full_screen && show_fullscreen_button}
|
75
|
+
<IconButton
|
76
|
+
Icon={Minimize}
|
77
|
+
label={is_full_screen ? "Exit full screen" : "View in full screen"}
|
78
|
+
on:click={toggle_full_screen}
|
79
|
+
/>
|
80
|
+
{/if}
|
81
|
+
|
82
|
+
{#if show_download_button}
|
83
|
+
<DownloadLink href={value.url} download={value.orig_name || "image"}>
|
84
|
+
<IconButton Icon={Download} label={i18n("common.download")} />
|
85
|
+
</DownloadLink>
|
86
|
+
{/if}
|
87
|
+
{#if show_share_button}
|
88
|
+
<ShareButton
|
89
|
+
{i18n}
|
90
|
+
on:share
|
91
|
+
on:error
|
92
|
+
formatter={async (value) => {
|
93
|
+
if (!value) return "";
|
94
|
+
let url = await uploadToHuggingFace(value, "url");
|
95
|
+
return `<img src="${url}" />`;
|
96
|
+
}}
|
97
|
+
{value}
|
98
|
+
/>
|
99
|
+
{/if}
|
67
100
|
</div>
|
68
|
-
|
101
|
+
<button on:click={handle_click}>
|
102
|
+
<div class:selectable>
|
103
|
+
<Image src={value.url} alt="" loading="lazy" on:load />
|
104
|
+
</div>
|
105
|
+
</button>
|
106
|
+
</div>
|
69
107
|
{/if}
|
70
108
|
|
71
109
|
<style>
|
72
110
|
.image-container {
|
73
111
|
height: 100%;
|
112
|
+
position: relative;
|
74
113
|
}
|
75
114
|
.image-container :global(img),
|
76
115
|
button {
|
@@ -79,6 +118,10 @@
|
|
79
118
|
object-fit: contain;
|
80
119
|
display: block;
|
81
120
|
border-radius: var(--radius-lg);
|
121
|
+
|
122
|
+
display: flex;
|
123
|
+
align-items: center;
|
124
|
+
justify-content: center;
|
82
125
|
}
|
83
126
|
|
84
127
|
.selectable {
|
@@ -91,5 +134,24 @@
|
|
91
134
|
top: 6px;
|
92
135
|
right: 6px;
|
93
136
|
gap: var(--size-1);
|
137
|
+
z-index: 1;
|
138
|
+
}
|
139
|
+
|
140
|
+
:global(.fullscreen-controls svg) {
|
141
|
+
position: relative;
|
142
|
+
top: 0px;
|
143
|
+
}
|
144
|
+
|
145
|
+
:global(.image-container:fullscreen) {
|
146
|
+
background-color: black;
|
147
|
+
display: flex;
|
148
|
+
justify-content: center;
|
149
|
+
align-items: center;
|
150
|
+
}
|
151
|
+
|
152
|
+
:global(.image-container:fullscreen img) {
|
153
|
+
max-width: 90vw;
|
154
|
+
max-height: 90vh;
|
155
|
+
object-fit: contain;
|
94
156
|
}
|
95
157
|
</style>
|