Use some icons
This commit is contained in:
@@ -11,9 +11,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"gif.js": "^0.2.0",
|
||||
"unplugin-icons": "^0.18.5",
|
||||
"vue": "^3.3.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/octicon": "^1.1.52",
|
||||
"@types/gif.js": "^0.2.5",
|
||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||
"@vitejs/plugin-vue": "^5.0.3",
|
||||
|
@@ -1,6 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import * as GIF from 'gif.js';
|
||||
import { downloadBlob } from '../download.ts';
|
||||
import IconPlus from '~icons/octicon/feed-plus-16';
|
||||
import IconPlay from '~icons/octicon/play-16';
|
||||
|
||||
defineEmits<{
|
||||
selected: [image: HTMLImageElement]
|
||||
@@ -31,12 +34,7 @@ function onAnimateClick(): void {
|
||||
});
|
||||
images.value.forEach((img) => gif.addFrame(img, { delay: 200 }));
|
||||
gif.on('finished', (blob: Blob) => {
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = 'animation.gif';
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
downloadBlob(blob, 'animation.gif')
|
||||
});
|
||||
gif.render();
|
||||
}
|
||||
@@ -49,12 +47,16 @@ defineExpose({
|
||||
<template>
|
||||
<div class="file-column">
|
||||
<input id="file-upload" type="file" @change="onFileChange">
|
||||
<label for="file-upload" class="button">Add</label>
|
||||
<label for="file-upload" class="button">
|
||||
Add
|
||||
<icon-plus />
|
||||
</label>
|
||||
<div v-for="(img, idx) in images" :key="idx" class="image-file">
|
||||
<img :src="img.src" width="64" height="64" alt="" draggable="true" @click="$emit('selected', img)" @dragstart="onDragStart($event, idx)" />
|
||||
</div>
|
||||
<button v-if="images.length" @click="onAnimateClick">
|
||||
Animate
|
||||
<icon-play />
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -4,6 +4,8 @@ import { blackAndWhite, grayScale } from '../processing/gray-scale.ts';
|
||||
import ImageCollection from './ImageCollection.vue';
|
||||
import { mergeImages } from '../processing/merge.ts';
|
||||
import { drawOffscreen } from '../processing/offscreen.ts';
|
||||
import { download } from '../download.ts';
|
||||
import IconDownload from '~icons/octicon/download-16';
|
||||
|
||||
const canvas = ref<HTMLCanvasElement | null>(null);
|
||||
const collection = ref<typeof ImageCollection>();
|
||||
@@ -102,6 +104,10 @@ function onDrop(event: DragEvent) {
|
||||
function onDragLeave() {
|
||||
overlay.value = null;
|
||||
}
|
||||
|
||||
function downloadImage() {
|
||||
download(canvas.value!.toDataURL('image/png'), 'image.png');
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -115,6 +121,9 @@ function onDragLeave() {
|
||||
<button @click="grayScaleApply">
|
||||
Gray-scale
|
||||
</button>
|
||||
<button @click="downloadImage">
|
||||
Download <icon-download />
|
||||
</button>
|
||||
</div>
|
||||
<div class="inner">
|
||||
<input v-model="currentHeight" type="range" min="5" max="200" value="100" orient="vertical" @change="onChangeSlideHeight">
|
||||
|
13
src/download.ts
Normal file
13
src/download.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export function download(value: string, filename: string): void {
|
||||
const a = document.createElement('a');
|
||||
a.href = value;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
a.remove();
|
||||
}
|
||||
|
||||
export function downloadBlob(blob: Blob, filename: string): void {
|
||||
const url = URL.createObjectURL(blob);
|
||||
download(url, filename);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
@@ -79,7 +79,7 @@ button:focus-visible,
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
button, .button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
@@ -108,3 +108,7 @@ button:focus-visible,
|
||||
height: 50%;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"types": ["vite/client", "unplugin-icons/types/vue"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import Icons from 'unplugin-icons/vite'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
plugins: [vue(), Icons({ compiler: 'vue3' })],
|
||||
})
|
||||
|
Reference in New Issue
Block a user