0

I am trying to add a transition of 2 png into an png in the background, and be able to switch between different scenarios ( like living-room, dining-room etc). Once I click the element that select which area of the house I am choosing, the images gets fetched but because it takes some time to load, the transition doesn't happen and they just appear on top of the image on the background without transition smoothly from the side. I need a way to load the all the images once the route gets rendered, or maybe if you could give me another solution for the problem I'm happy to hear it.

This is the template

<template>
    <div>
        <div v-for="item in painting" :key="item.id" class="showroom">
            <div class="setting">
                <h1>{{ item.name }}</h1>
                <h3>Choose a room:</h3>
                <div v-for=" (room, idx) in rooms" :key="idx" id="roomSelection">
                    <img id="roomSelector" :src="room.roomview" @click="showRoom(room)">
                    <p>{{ room.name }}</p>
                    <br>
                </div>
                <p>Choose a wall color:  <span id="colorPicker" :style="{backgroundColor: color}"><input type="color" id="base" v-model="color"></span></p>
                <router-link to="/painting"><i class="fas fa-arrow-left"></i></router-link>
            </div>
            <div  class="display">
                <div :style="{backgroundColor: color}" class="wall">
                    <img :src="item.img">
                </div>
                <div class="forniture">
                    <transition name="slideIn">
                    <div v-for=" room in roomToShow" :key="room" class="setForniture">
                        <img  class="left" :id="room.space1" :src="room.forniture1">
                        <img  class="left" :id="room.space2" :src="room.forniture2">
                    </div>
                    </transition>
                </div>
            </div>
        </div>
    </div>
</template>

This is the script

<script>
import { mapGetters } from 'vuex'
import sofa from '../assets/sofa.png'
import lamp from '../assets/lamp.png'
import table from '../assets/table.png'
import cabinet from '../assets/cabinet.png'
import chair from '../assets/chair.png'
import sidetable from '../assets/sidetable.png'
import livingroom from '../assets/livingroom.png'
import diningroom from '../assets/diningroom.png'
import lounge from '../assets/lounge.png'

export default {
    data(){
        return{
            color: '#243E36',
            rooms: [
                { name: "lounge", space1: 'lounge1', space2: 'lounge2', forniture1: chair, forniture2:sidetable, roomview: lounge},
                { name: "livingroom" , space1: 'livingroom1', space2: 'livingroom2',  forniture1:sofa, forniture2:lamp, roomview: livingroom },
                { name: "diningroom" , space1: 'diningroom1', space2: 'diningroom2', forniture1: table, forniture2: cabinet, roomview: diningroom }
            ],
            roomToShow: [],
        }
    },
    computed: {
        ...mapGetters([
            'showPainting',
            'forSale',
            'painting'
        ]),

    },
    methods: {
        showRoom(room) {
            setTimeout( () => {
                this.roomToShow.shift();
                this.roomToShow.push(room);   
            }, 100)   
        }
    }
</script>

1 Answers1

0

The easiest way to solve this issue is to just hide the images with CSS but nevertheless load all from the beginning (render the elements). You can do that by dynamically adding a class to the currently visible image with :class="".

A more complex solution, which gives you also a callback for when the images are loaded, is to create a new Image() for all images and react to onload/onerror. Like this, you can load all the images in the beginning with JS abd without changing the HTML. Here is an example for this use case: How to create a JavaScript callback for knowing when an image is loaded?

ssc-hrep3
  • 15,024
  • 7
  • 48
  • 87