ghettovoice / vuelayers

Web map Vue components with the power of OpenLayers
https://vuelayers.github.io/
MIT License
680 stars 227 forks source link

ol-ext feature animation #363

Closed RaminMT closed 3 years ago

RaminMT commented 3 years ago

Hi, I tried to use ol-ext library to animate a feature, I set everything up but it's not work, it says animation is playing but I can't see anything on map This is my code:

        <vl-map
          ref="map"
          :load-tiles-while-animating="true"
          :load-tiles-while-interacting="true"
          :data-projection="'EPSG:4326'">

          <vl-view :enableRotation="false" :center="center" :zoom="zoom" :max-zoom="maxZoom"></vl-view>

          <vl-layer-tile>
            <vl-source-osm></vl-source-osm>
          </vl-layer-tile>

          <vl-layer-vector ref="featuresLayer">
            <vl-source-vector :features.sync="myFeatures"></vl-source-vector>
          </vl-layer-vector>

        </vl-map>

and the js:

<script>
import { Feature } from 'ol'
import { Point, LineString } from 'ol/geom'
import { Icon, Style, Fill, Stroke, RegularShape } from 'ol/style'
import featureAnimationPath from 'ol-ext/featureanimation/Path'
import _ from 'lodash'

export default {
  data() {
    return {
      center: [0, 0],
      zoom: 5.5,
      maxZoom: 19,
      myFeatures: []
    }
  },
  methods: {
    animate() {
      // feature with id=0 is a line string feature
      let coordinates = this.myFeatures.find(x => x.id === 0).geometry.coordinates
      let featurePoint = new Point(coordinates[0])
      let feature = new Feature(featurePoint)

      feature.setStyle(new Style({
        image: new RegularShape({
          radius: 14,
          points: 3,
          fill: new Fill({
            color: '#00f'
          }),
          stroke: new Stroke({
            color: '#fff',
            width: 2
          })
        }),
        stroke: new Stroke({
          color: [0, 0, 255],
          width: 2
        }),
        fill: new Fill({
          color: [0, 0, 255, 0.3]
        })
      }))

      //you may ask why I creating line string again, using the already created one won't work
      let lineString = new Feature({
        geometry: new LineString(coordinates)
      })

      let animation = new featureAnimationPath({
        path: lineString,
        rotate: true,
        duration: 10 * 1000,
      })

      // let result = this.$refs.featuresLayer.$olObject.animateFeature(feature, animation)
      let result = this.$refs.featuresLayer.$layer.animateFeature(feature, animation)
      console.log(result.isPlaying()) //returns true but nothing happens or at least I can't see
    }
  }
}
</script>

The style I set on animating feature is what they used on ol-ext example, a triangle. It's seems we can't use images, curious why?!

ghettovoice commented 3 years ago

Your example not working because you re-create new path feature (linestring) that is not bound to the vector layer on which you run animateFeature. Actually there is no need to re-create it at all, you should use features from the vector source. Check this updated demo https://jsfiddle.net/ghettovoice/jf41enh8/.

As for using image icons, I force icon load with icon.load(). It seems that without it ol-ext animation don't know icon resolution and can't render it correctly.

RaminMT commented 3 years ago

Wow! Why it didn't came to my mind?! Actually here in this line: let coordinates = this.myFeatures.find(x => x.id === 0).geometry.coordinates The feature it finds is the line string I'm showing on the map but as I commented It didn't work that way the actual code was like this:

let lineString = this.myFeatures.find(x => x.id === 0)
.
.
.
let animation = new featureAnimationPath({
        path: lineString,
        rotate: true,
        duration: 10 * 1000,
      })

And about the icon.load() thanks! It works!!

Thank you for your efforts dear, your library and replies really helped & saved me

ghettovoice commented 3 years ago

Actually here in this line: let coordinates = this.myFeatures.find(x => x.id === 0).geometry.coordinates The feature it finds is the line string I'm showing on the map but as I commented It didn't work that way the actual code was like this:

Because this.myFeatures is just a serialized representation of OpenLayers features, not the actual ol/Feature instances that was created inside vector source

RaminMT commented 3 years ago

Genius! You're right, I got that wrong

RaminMT commented 3 years ago

And another question, Is it possible to do seeking in the animation?

ghettovoice commented 3 years ago

I don't know. But I found that call vectorLayer.animateFeature(feature, fanim, useFilter) returns an object with animation control methods. So I think you can stop current animation (this will drop current animating marker) and re-call animation method with a marker on another coordinate along a linestring

https://viglino.github.io/ol-ext/doc/doc-pages/ol.layer.Base.html

RaminMT commented 3 years ago

Thank you, I've been away for a while I had some investigations and the way is using another lib named ol-games, that supports pause & resume actions