Compare commits
3 commits
b584a539fe
...
de5d12c0fa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de5d12c0fa | ||
|
|
c084260688 | ||
|
|
9e02813d19 |
2 changed files with 57 additions and 5 deletions
13
src/App.vue
13
src/App.vue
|
|
@ -2,6 +2,7 @@
|
|||
import PagedJsWrapper from './components/PagedJsWrapper.vue';
|
||||
import EditorPanel from './components/editor/EditorPanel.vue';
|
||||
import ElementPopup from './components/ElementPopup.vue';
|
||||
import PreviewLoader from './components/PreviewLoader.vue';
|
||||
import { onMounted, ref, watch, computed, provide } from 'vue';
|
||||
import { useStylesheetStore } from './stores/stylesheet';
|
||||
import Coloris from '@melloware/coloris';
|
||||
|
|
@ -16,7 +17,7 @@ provide('activeTab', activeTab);
|
|||
|
||||
let savedScrollPercentage = 0;
|
||||
const currentFrameIndex = ref(1); // 1 or 2, which iframe is currently visible
|
||||
let isTransitioning = false;
|
||||
const isTransitioning = ref(false);
|
||||
|
||||
const activeFrame = computed(() => {
|
||||
return currentFrameIndex.value === 1
|
||||
|
|
@ -25,8 +26,8 @@ const activeFrame = computed(() => {
|
|||
});
|
||||
|
||||
const renderPreview = async (shouldReloadFromFile = false) => {
|
||||
if (isTransitioning) return;
|
||||
isTransitioning = true;
|
||||
if (isTransitioning.value) return;
|
||||
isTransitioning.value = true;
|
||||
|
||||
// Determine which iframe is currently visible and which to render to
|
||||
const visibleFrame =
|
||||
|
|
@ -35,7 +36,7 @@ const renderPreview = async (shouldReloadFromFile = false) => {
|
|||
currentFrameIndex.value === 1 ? previewFrame2.value : previewFrame1.value;
|
||||
|
||||
if (!hiddenFrame) {
|
||||
isTransitioning = false;
|
||||
isTransitioning.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -112,7 +113,7 @@ const renderPreview = async (shouldReloadFromFile = false) => {
|
|||
|
||||
// Swap current frame
|
||||
currentFrameIndex.value = currentFrameIndex.value === 1 ? 2 : 1;
|
||||
isTransitioning = false;
|
||||
isTransitioning.value = false;
|
||||
}, 200); // Match CSS transition duration
|
||||
}, 50); // Small delay to ensure scroll is set
|
||||
}, 200); // Wait for PagedJS
|
||||
|
|
@ -147,6 +148,8 @@ onMounted(() => renderPreview(true));
|
|||
:class="{ shifted: activeTab.length > 0 }"
|
||||
></iframe>
|
||||
|
||||
<PreviewLoader :isLoading="isTransitioning" :shifted="activeTab.length > 0" />
|
||||
|
||||
<ElementPopup ref="elementPopup" :iframeRef="activeFrame" />
|
||||
</template>
|
||||
|
||||
|
|
|
|||
49
src/components/PreviewLoader.vue
Normal file
49
src/components/PreviewLoader.vue
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<template>
|
||||
<div v-if="isLoading" class="preview-loader" :class="{ shifted }">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
shifted: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.preview-loader {
|
||||
position: fixed;
|
||||
top: 2rem;
|
||||
right: 2rem;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
transition: all 0.2s ease-in-out var(--curve);
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
border-top: 3px solid #000;
|
||||
border-right: 3px solid transparent;
|
||||
box-sizing: border-box;
|
||||
animation: rotation 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes rotation {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue