4

Vue.use(VueGoogleMaps, {
  load: {
    key: ''
  },
});

new Vue({
  el: '#root',
  computed:{
    icon(){
        if (this.resized)
            return {
            url:"https://i.ibb.co/bdykLz4/test.png",
            size: { width: 100, height: 100, f: "px", b: "px" },
            scaledSize: { width: 50, height: 50, f: "px", b: "px" }
                
            }
        else
            return {
            url:"https://i.ibb.co/bdykLz4/test.png"
            }
      
    }
  },
  data: {
    resized:true,
    startLocation: {
      lat: 38.7126659,
      lng: -9.3051496
    },
    coordinates: {
      0: {
        full_name: 'Point 1',
      lat: 38.7226659,
      lng: -9.3151496
      },
      1: {
        full_name: 'Point 2',
      lat: 38.7136659,
      lng: -9.3061496
      }
    },
  },
  methods: {
    getPosition: function(marker) {
      return {
        lat: parseFloat(marker.lat),
        lng: parseFloat(marker.lng)
      }
    },
  }
});
<script src="https://xkjyeah.github.io/vue-google-maps/vue-google-maps.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<body>
  <div id="root">
    <gmap-map ref="mymap" :center="startLocation" :zoom="14" style="width: 100%; height: 500px">

      <gmap-marker v-for="(item, key) in coordinates" :key="key" :position="getPosition(item)" :icon="icon"/>

    </gmap-map>
    Resized: <input type="checkbox" id="checkbox" v-model="resized" >
  </div>

</body>

I am trying to use custom markers with vue2-google-maps, and found a strange behaviour.

If I use a png image for example 100x100 pixels and set the properties to resize it to 50x50 pixels, when I start to zoom out, the marker start to move away from the coordinates.

If I did not use the resize property, there is no problem.

I have searched a lot about this issue and can´t find anything.

I had prepared a JSFiddle, just uncheck the checkbox and everything is ok during the zoom out, but if you let the checkbox marked and start to zoom out, you will see that the mark goes to the ocean, when it should be on Portugal.

The difference on the object passed to the icon property is:

when checked:

{
   url:"https://i.ibb.co/bdykLz4/test.png",
   size: { width: 100, height: 100, f: "px", b: "px" },
   scaledSize: { width: 50, height: 50, f: "px", b: "px" }
}

when unchecked:

{
   url:"https://i.ibb.co/bdykLz4/test.png",
}

Here is the fiddle: https://jsfiddle.net/5dw83v7g/3/

UPDATE: If I keep "size" and "scaledSize" the same, the problem disapears

best regards,

TIA

1 Answers1

2

Vue.use(VueGoogleMaps, {
  load: {
    key: 'YOUR_API_KEY'
  },
});

new Vue({
  el: '#root',
 computed:{
    icon(){
        if (this.resized)
            return {
            url:"https://i.ibb.co/bdykLz4/test.png",
            size: { width: 100, height: 100, f: "px", b: "px" },
            scaledSize: { width: 50, height: 50, f: "px", b: "px" }
                
            }
        else
            return {
            url:"https://i.ibb.co/bdykLz4/test.png"
            }
      
    }
    },
  data: {
    startLocation: {
      lat: 10.3157,
      lng: 123.8854
    },
    coordinates: {
      0: {
        full_name: 'Erich  Kunze',
        lat: '10.31',
        lng: '123.89'
      },
      1: {
        full_name: 'Delmer Olson',
        lat: '10.32',
        lng: '123.89'
      }
    },
    infoPosition: null,
    infoContent: null,
    infoOpened: false,
    infoCurrentKey: null,
    infoOptions: {
      pixelOffset: {
        width: 0,
        height: -35
      }
    },
  },
  methods: {
    getPosition: function(marker) {
      return {
        lat: parseFloat(marker.lat),
        lng: parseFloat(marker.lng)
      }
    },
    toggleInfo: function(marker, key) {
      this.infoPosition = this.getPosition(marker);
      this.infoContent = marker.full_name;
      if (this.infoCurrentKey == key) {
        this.infoOpened = !this.infoOpened;
      } else {
        this.infoOpened = true;
        this.infoCurrentKey = key;
      }
    }
  }
});
<script src="https://xkjyeah.github.io/vue-google-maps/vue-google-maps.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<body>
  <div id="root">
    <gmap-map ref="mymap" :center="startLocation" :zoom="14" style="width: 100%; height: 500px">

      <gmap-marker v-for="(item, key) in coordinates" :key="key" :position="getPosition(item)" :icon="icon"/>

    </gmap-map>
    Resized: <input type="checkbox" id="checkbox" v-model="resized" >
  </div>

</body>

You have to change your code like this:

Vue.use(VueGoogleMaps, {
  load: {
    key: 'YOUR_API_KEY'
  },
});

new Vue({
  el: '#root',
 computed:{
    icon(){
        if (this.resized)
            return {
            url:"https://i.ibb.co/bdykLz4/test.png",
            size: { width: 100, height: 100, f: "px", b: "px" },
            scaledSize: { width: 50, height: 50, f: "px", b: "px" }
                
            }
        else
            return {
            url:"https://i.ibb.co/bdykLz4/test.png"
            }
      
    }
    },
  data: {
    startLocation: {
      lat: 10.3157,
      lng: 123.8854
    },
    coordinates: {
      0: {
        full_name: 'Erich  Kunze',
        lat: '10.31',
        lng: '123.89'
      },
      1: {
        full_name: 'Delmer Olson',
        lat: '10.32',
        lng: '123.89'
      }
    },
    infoPosition: null,
    infoContent: null,
    infoOpened: false,
    infoCurrentKey: null,
    infoOptions: {
      pixelOffset: {
        width: 0,
        height: -35
      }
    },
  },
  methods: {
    getPosition: function(marker) {
      return {
        lat: parseFloat(marker.lat),
        lng: parseFloat(marker.lng)
      }
    },
    toggleInfo: function(marker, key) {
      this.infoPosition = this.getPosition(marker);
      this.infoContent = marker.full_name;
      if (this.infoCurrentKey == key) {
        this.infoOpened = !this.infoOpened;
      } else {
        this.infoOpened = true;
        this.infoCurrentKey = key;
      }
    }
  }
});

and use thisin your body:

<body>
  <div id="root">
    <gmap-map ref="mymap" :center="startLocation" :zoom="14" style="width: 100%; height: 300px">

      <gmap-info-window :options="infoOptions" :position="infoPosition" :opened="infoOpened" @closeclick="infoOpened=false">
        {{infoContent}}
      </gmap-info-window>

      <gmap-marker v-for="(item, key) in coordinates" :key="key" :position="getPosition(item)" :icon="icon"/>

    </gmap-map>
  </div>

</body>

I used this code here.

Vue.use(VueGoogleMaps, {
  load: {
    key: 'YOUR_API_KEY'
  },
});

new Vue({
  el: '#root',
 computed:{
    icon(){
        if (this.resized)
            return {
            url:"https://i.ibb.co/bdykLz4/test.png",
            size: { width: 100, height: 100, f: "px", b: "px" },
            scaledSize: { width: 50, height: 50, f: "px", b: "px" }
                
            }
        else
            return {
            url:"https://i.ibb.co/bdykLz4/test.png"
            }
      
    }
    },
  data: {
    startLocation: {
      lat: 10.3157,
      lng: 123.8854
    },
    coordinates: {
      0: {
        full_name: 'Erich  Kunze',
        lat: '10.31',
        lng: '123.89'
      },
      1: {
        full_name: 'Delmer Olson',
        lat: '10.32',
        lng: '123.89'
      }
    },
    infoPosition: null,
    infoContent: null,
    infoOpened: false,
    infoCurrentKey: null,
    infoOptions: {
      pixelOffset: {
        width: 0,
        height: -35
      }
    },
  },
  methods: {
    getPosition: function(marker) {
      return {
        lat: parseFloat(marker.lat),
        lng: parseFloat(marker.lng)
      }
    },
    toggleInfo: function(marker, key) {
      this.infoPosition = this.getPosition(marker);
      this.infoContent = marker.full_name;
      if (this.infoCurrentKey == key) {
        this.infoOpened = !this.infoOpened;
      } else {
        this.infoOpened = true;
        this.infoCurrentKey = key;
      }
    }
  }
});
<script src="https://xkjyeah.github.io/vue-google-maps/vue-google-maps.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<body>
  <div id="root">
    <gmap-map ref="mymap" :center="startLocation" :zoom="14" style="width: 100%; height: 500px">

      <gmap-marker v-for="(item, key) in coordinates" :key="key" :position="getPosition(item)" :icon="icon"/>

    </gmap-map>
    Resized: <input type="checkbox" id="checkbox" v-model="resized" >
  </div>

</body>

Please rate me if it was helpful. Thanks a lot.

jabamataro
  • 1,154
  • 7
  • 13
Arash Yazdani
  • 302
  • 2
  • 12
  • Hi @Arash, thank you very much for your time and efforts... The code does not use the resize properties of the icon, this is the key of the problem, so it does not reproduce the problem to solve it... – Alexandre Benson Smith Jul 27 '20 at 15:19
  • I changed that and got a run check it please – Arash Yazdani Jul 27 '20 at 17:33
  • thank you for your time again ! I am very new to stack overflow, first question posted, so pardon me for my ignorance... How I could duplicate your stack snippet to make some changes an tests ? I think the getIcon function are returning always the version with just the URL and not the resize properties. – Alexandre Benson Smith Jul 27 '20 at 21:56
  • No I don't think. If you want to be sure, test it in a debugger program. – Arash Yazdani Jul 29 '20 at 07:31
  • Hi @Arash , thank you very much for your time and support... In fact it´s always sending the just the url without the resize properties, check here: https://jsfiddle.net/fqjz8m05/6/ To simplify, I just created another one that always return the object for the icon that has the misplacement problem, you can check here: https://jsfiddle.net/5p6km48z/ – Alexandre Benson Smith Jul 30 '20 at 16:23
  • Please don't share API keys publicly and make sure you restrict them as per: https://developers.google.com/maps/api-key-best-practices#restrict_apikey – jabamataro Jul 31 '20 at 05:36