Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reactivity of opacity in Layers.OlTileLayer broken in v11 #410

Closed
vincerubinetti opened this issue Feb 20, 2025 · 3 comments
Closed

Reactivity of opacity in Layers.OlTileLayer broken in v11 #410

vincerubinetti opened this issue Feb 20, 2025 · 3 comments
Labels
bug Something isn't working

Comments

@vincerubinetti
Copy link

vincerubinetti commented Feb 20, 2025

Describe the bug

Put this into the current playground:

<template>
  {{ opacity }}
  <Map.OlMap style="height: 400px">
    <Map.OlView
      :center="center"
      :rotation="rotation"
      :zoom="zoom"
      projection="EPSG:4326"
    />

    <Layers.OlTileLayer :opacity="opacity">
      <Sources.OlSourceOsm />
    </Layers.OlTileLayer>
  </Map.OlMap>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { Layers, Map, Sources } from "vue3-openlayers";

const center = ref([40, 40]);
const zoom = ref(3);
const rotation = ref(0);
const opacity = ref(1);

setInterval(() => (opacity.value = Math.random()), 1000);
</script>

And it works, the tile layer opacity changes at random. I couldn't figure out why it wasn't working locally for me, then I noticed the Playground is still on v10. If you upgrade it to v11, the opacity is no longer reactive, it just stays whatever its initial value was.

P.S. The playground should really be updated, v11 has been out for several months.

Affected version(s)


I believe this warning I get in the console is related:

[Vue warn] toRefs() expects a reactive object but received a plain one.
setup	@	vue3-openlayers.js?v=5488eae0:76669

var _sfc_main$1b = defineComponent({
  __name: "OlTileLayer",
  props: mergeDefaults({
    className: {},
    opacity: {},
    visible: { type: Boolean },
    extent: {},
    zIndex: {},
    minResolution: {},
    maxResolution: {},
    minZoom: {},
    maxZoom: {},
    preload: {},
    source: {},
    map: {},
    useInterimTilesOnError: { type: Boolean },
    properties: {},
    cacheSize: {},
    openInLayerSwitcher: { type: Boolean },
    title: {},
    name: {},
    allwaysOnTop: { type: Boolean },
    baseLayer: { type: Boolean }
  }, useDefaults$1({
    preload: 1
  })),
  emits: ["sourceready", "change", "error", "propertychange", "change:extent", "change:maxResolution", "change:maxZoom", "change:minResolution", "change:minZoom", "change:opacity", "change:source", "change:visible", "change:zIndex", "postrender", "prerender", "change:useInterimTilesOnError", "change:preload"],
  setup(__props, { expose: __expose }) {
    const props = __props;
    const { layer } = useLayer(Tile_default4, toRefs({ ...props }), [ // <----------------------------
      "change:useInterimTilesOnError",
      "change:preload"
    ]);
@vincerubinetti vincerubinetti added the bug Something isn't working label Feb 20, 2025
@vincerubinetti
Copy link
Author

vincerubinetti commented Feb 21, 2025

Not sure if this is related, but I'm also having a reactivity bug with the following:

<template>

<!-- other stuff -->

<Layers.OlVectorLayer>
  <Sources.OlSourceVector :features="features">
    <Map.OlFeature
      v-for="(feature, key) in features"
      :key="key"
      :properties="feature.getProperties()"
    >
      <Styles.OlStyle :key="JSON.stringify(scale.steps)">
        <Styles.OlStyleStroke color="black" />
        <Styles.OlStyleFill
          :color="scale.getColor(feature.get('id'))"
        />
      </Styles.OlStyle>
    </Map.OlFeature>
  </Sources.OlSourceVector>
</Layers.OlVectorLayer>

<!-- other stuff -->

</template>

where features is of type ComputedRef<Feature<Geometry>[]> and scale is of type ComputedRef<{ steps: string[], getColor: (id: string) => string; }>

Note the :key="JSON.stringify(scale.steps)" I had to add to make the reactivity work.

For context: steps is a list of discrete hex colors, and getColor is a function that maps a feature id to one of those colors based on a value associated with the feature. The user is able to select a color gradient, so these can change reactively.

Pretty sure this is a bug in the library because if I change the gradient color, the map doesn't re-draw. But then if I drag/pan them map, it does update to the correct colors.

@vincerubinetti
Copy link
Author

vincerubinetti commented Feb 22, 2025

Another reactivity (or something) bug. Trying to do a very simple thing: change the fill of a feature when the user hovers it, but exclude a layer of text labels that hover over each feature (otherwise I get a bad flickering back and forth of the color when hovering across a label). Adding the layers filter, it just removes the fill all-together on hover, unless I add the extremely hacky :key="Math.random()" to force the style component to re-render every render.

<template>
  <Interactions.OlInteractionSelect
    :condition="pointerMove"
    :layers="(layer) => layer.get('name') !== 'labels'"
  >
    <Styles.OlStyle :key="Math.random()">
      <Styles.OlStyleFill />
    </Styles.OlStyle>
  </Interactions.OlInteractionSelect>
</template>

Unfortunately all of these issues I and others are running into make me feel not confident in using this library in a production site. I need to be 100% sure the map will show the right thing e.g. when users change filter controls. So I'm probably going to need to switch to just using Open Layers directly.

Related:
#277 #120 #359

@Radioaktywnyja
Copy link

Radioaktywnyja commented Feb 22, 2025

Hi. I think the problem is in the 11.3.2 update. In my case the visible prop is broken. I have code like that (simplified)

<ol-map ref="map" class="map" :controls="[]">
        <ol-view ref="view" :center="mapCenter" :zoom="mapLayersStore.mapZoom" @change:resolution="onUpdateMapZoom" />
        <template v-for="(style, index) in mapLayersStore.mapStylesData" :key="style.name">
            <ol-tile-layer :visible="index === mapLayersStore.activeMapStyleIndex" :opacity="mapLayersStore.mapOpacity">
                <ol-source-xyz v-if="style.type === 'standard' && style.options.basicAuth" :url="style.url"
                    :attributions="style.attribution" :ref="style.name" :title="style.name"
                    :tileLoadFunction="(tile, src) => tileLoadFunction(tile, src, style.options.basicAuth)" />
                <ol-source-xyz v-if="style.type === 'standard'" :url="style.url" :attributions="style.attribution"
                    :ref="style.name" :title="style.name" />
                <ol-source-tile-wms v-if="style.type === 'wms'" :url="style.url" :attributions="style.attribution"
                    :ref="style.name" :title="style.name" :layers="style.options.layers" />
            </ol-tile-layer>
        </template>
    </ol-map>

It works on 11.3.1 but updated to 11.3.2 it breaks. Changing activeMapStyleIndex does not change the map layer. I laso have the same warning

[Vue warn] toRefs() expects a reactive object but received a plain one.

And i beleive that is caused by changes in OlTileLayer.vue file in 11.3.2 update

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants