0

My component is a modal which displays an <img> with some tags on top. I get the image dimensions using const size = this.$refs.media.getBoundingClientRect(). However, the height and width is 0, so the tags become placed wrong.

So it seems the image hasn't loaded yet? If I delay getting the height+width with setTimeout, I do get the width and height. But it seems like a not too reliable workaround.

I have "v-cloak" on the modal, but that doesn't work.

I can get the html element with this.$refs.media, but it doesn't mean that the image is loaded, apparently. So, is there a way to check if the image is loaded? Is there some way to delay the component until the image is loaded?

One more thing: if I add a "width" and "height" in inline style on the img, then those values are available directly. But I don't want to set the size that way because it ruins the responsiveness.

The code doesn't say much more, but it is basically:

<modal>
    <vue-draggable-resizable                    // <-- each tag
        v-for="( tag, index ) in tags" 
       :x="convertX(tag.position.x)" 
       :y="convertY(tag.position.y)"
       (other parameters)

convertX (x) { 
     const size = this.$refs.media.getBoundingClientRect()
     return x * (size.width - 100)                     // <--- 0 width

async mounted () {

    this.renderTags(this.media.tags)          // <-- needs img width and height

Updated, solution

As the below answer says, I can use the onload event. I also came across the "@load" event, which I tried and it worked. I can't find it in the documentation though(?) (I searched for @load and v-on:load). Using "onload" directly on the image element didn't work though, so @load seems to be the way.

If I have a data property:

data () {
    return {
       imgLoaded: false

I can set it to true with a method using @load on the image:

<img 
    @load="whenImgLoaded" 


 <template v-if="imgLoaded = true">           
       <vue-draggable-resizable     
            :x="convertX(tag.position.x)" 
            :y="convertY(tag.position.y)"
             (other parameters)

methods: {
    whenImgLoaded(){
         this.imgLoaded = true;
         this.renderTags(this.media.tags)
   }

1 Answer 1

1

You could load the image first via javascript, and after it's loaded run the renderTags method.

E.g., do something like this:

async mounted() {
    let image = new Image();
    image.onload = function () {
        this.renderTags(this.media.tags)   
    };
    image.src = 'https://some-image.png'
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, the "onload" was what I needed. While googling I came across the "@load" event which I tried and it worked. So I can mark your answer as accepted since it's the same principle.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.