load / save scene wip

main
km0 2 years ago
parent 17a0dc410b
commit 0288e8de0d

@ -13,8 +13,15 @@
<input v-model="title" placeholder="Title"> <input v-model="title" placeholder="Title">
<button @click="add">Add Scene</button> <button @click="add">Add Scene</button>
</div> </div>
<SceneEntry v-for="scene in scenes" :title="scene"/> <div class="load-scene">
<label >Load scene</label>
<input type="file" multiple @change="load">
</div>
<SceneEntry v-for="scene in scenes" :title="scene.title" :series="scene.series"/>
</main> </main>
</template> </template>
@ -27,10 +34,32 @@ import {ref} from 'vue'
const scenes = ref([]) const scenes = ref([])
const title = ref('') const title = ref('')
const add = () => { const add = () => {
scenes.value.push(title.value) scenes.value.push({
title: title.value,
series: []
})
title.value = "" title.value = ""
} }
const load = (e) => {
let files = e.target.files
new Promise.all(files.forEach(async (file) =>{
const reader = new FileReader()
reader.readAsText(file)
reader.onloadend = (e) => {
if (e.target.readyState == FileReader.DONE) {
try {
let scene = JSON.parse(reader.result)
scenes.value.push(scene)
} catch (e) {
console.log(e)
}
}
}
})
)
}
</script> </script>
<style> <style>

@ -1,7 +1,7 @@
<template> <template>
<div class="add-shot"> <div class="add-shot">
<FileLoader class="cover" @upload="getImg" @filename="setTitle" :key="key"></FileLoader> <FileLoader class="cover" @upload="getImg" @file="setFile" :key="key"></FileLoader>
<div class="meta"> <div class="meta" v-if="file">
<input v-model="title" placeholder="Title"> <input v-model="title" placeholder="Title">
<textarea v-model="description" placeholder="Description"></textarea> <textarea v-model="description" placeholder="Description"></textarea>
<button class="insert" @click="add">Add</button> <button class="insert" @click="add">Add</button>
@ -12,6 +12,8 @@
import FileLoader from '../components/FileLoader.vue' import FileLoader from '../components/FileLoader.vue'
import {ref} from 'vue' import {ref} from 'vue'
const file = ref(null)
const title = ref('') const title = ref('')
const description = ref('') const description = ref('')
const img = ref('') const img = ref('')
@ -22,13 +24,17 @@
const getImg = (e) => img.value = e const getImg = (e) => img.value = e
const setTitle = e => title.value = e const setFile = e => {
file.value = e
}
const add = () => { const add = () => {
emits('add', { emits('add', {
title: title.value, title: title.value,
description: description.value, description: description.value,
img: img.value} img: img.value,
file: file.value
}
) )
reset() reset()
} }
@ -38,7 +44,6 @@
description.value = "" description.value = ""
img.value = "" img.value = ""
key.value += 1 key.value += 1
} }
</script> </script>

@ -15,18 +15,17 @@
<script setup> <script setup>
import {ref, computed} from 'vue' import {ref, computed} from 'vue'
const emit = defineEmits(['upload', 'filename']) const emit = defineEmits(['upload', 'file'])
const dropFile = ref([])
const file = ref([])
const fileType = ref("") const fileType = ref("")
const thumb = ref(null) const thumb = ref(null)
const loading = ref(false) const loading = ref(false)
const dragFile = (e) => { const dragFile = (e) => {
file.value = e.dataTransfer.files[0] dropFile.value = e.dataTransfer.files[0]
createPreview(file.value) createPreview(dropFile.value)
} }
const container = computed(()=>{ const container = computed(()=>{
@ -39,9 +38,6 @@
loading.value = true loading.value = true
const fileName = file.name
emit('filename', fileName)
// get file type // get file type
fileType.value = file.type.toLowerCase().substr(0, file.type.indexOf("/")) fileType.value = file.type.toLowerCase().substr(0, file.type.indexOf("/"))
@ -55,6 +51,8 @@
fileToRead = await videoSnapshot(filePath) fileToRead = await videoSnapshot(filePath)
filePath = (window.URL || window.webkitURL).createObjectURL(fileToRead) filePath = (window.URL || window.webkitURL).createObjectURL(fileToRead)
} }
emit('file', fileToRead)
const reader = new FileReader() const reader = new FileReader()
reader.readAsDataURL(fileToRead) reader.readAsDataURL(fileToRead)
@ -65,6 +63,7 @@
} }
} }
// TODO: scale image to thumb size
const imageSnapshot = (url) => { const imageSnapshot = (url) => {
thumb.value.src = url thumb.value.src = url
emit('upload', url) emit('upload', url)
@ -80,12 +79,12 @@
const snapshot = async () => { const snapshot = async () => {
let canvas = document.createElement('canvas') let canvas = document.createElement('canvas')
canvas.width = 1280 canvas.width = 640
canvas.height = 720 canvas.height = 360
let ctx = canvas.getContext('2d') let ctx = canvas.getContext('2d')
ctx.drawImage(video, 0, 0, canvas.width, canvas.height) ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
thumb.value.src = canvas.toDataURL('image/png') thumb.value.src = canvas.toDataURL('image/jpeg')
loading.value = false loading.value = false
video.removeEventListener('canplay', snapshot) video.removeEventListener('canplay', snapshot)
let file = await dataUrlToFile(thumb.value.src, 'snapshot') let file = await dataUrlToFile(thumb.value.src, 'snapshot')
@ -101,7 +100,7 @@
// in order not to have super long src urls for snapshot in the DOM // in order not to have super long src urls for snapshot in the DOM
const res = await fetch(dataUrl); const res = await fetch(dataUrl);
const blob = await res.blob(); const blob = await res.blob();
return new File([blob], fileName, { type: 'image/png' }); return new File([blob], fileName, { type: 'image/jpeg' });
} }
</script> </script>

@ -33,6 +33,10 @@
</template> </template>
</draggable> </draggable>
<button @click="serialize">Export scene</button>
</section> </section>
@ -46,9 +50,13 @@ import ShotEntry from '../components/ShotEntry.vue'
import {ref, computed} from 'vue' import {ref, computed} from 'vue'
const props = defineProps(['title']) const props = defineProps({
title: String,
series: Array
})
const shots = ref(props.series || [])
const shots = ref([])
const drag = ref(false) const drag = ref(false)
const dragOptions = computed(()=> { const dragOptions = computed(()=> {
@ -68,8 +76,40 @@ const remove = (index) => {
shots.value.splice(index, 1) shots.value.splice(index, 1)
} }
const serialize = async () => {
let series = await Promise.all(shots.value.map(async (shot) => {
let img = await blobToBase64(shot.file)
return {
title: shot.title,
description: shot.description,
img: img
}
}))
download(
JSON.stringify({title: props.title, series}),
`${props.title}.json`,
'text/plain'
)
}
const blobToBase64 = (blob) => {
return new Promise((resolve, _) => {
const reader = new FileReader()
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(blob)
})
}
function download(content, fileName, contentType) {
var a = document.createElement("a");
var file = new Blob([content], {type: contentType});
a.href = URL.createObjectURL(file);
a.download = fileName;
a.click();
}
</script> </script>

Loading…
Cancel
Save