0

I'm attempting to use react-leaflet and ImageOverlay with CSS animation to create the appearance of clouds floating over the base image.

At the default zoom level, all is good. The animation works, and I can pan around and it looks great. However, when I zoom in, then drag, then zoom back out, the animation seems to reset at a new location. Specifically, it moves the opposite distance that I panned. So if I pan 100 pixels down then zoom out, the clouds will be 100 pixels higher.

I attempted to hide the layer at all except one specific zoom level (-2), and the overlay hides fine on the zoom, but doesn't return to its original location when it re-appears.

Here is a 3-second video of the symptom. Notice where the clouds are initially, after zooming and panning and zooming back out, the clouds are no longer there, they are higher. Link: https://www.youtube.com/watch?v=R1pipizyQ4Y

Here is the React/js code:

import styles from '../map/map.test.styles.module.css';
import 'leaflet/dist/leaflet.css';
import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css';
import 'leaflet-defaulticon-compatibility';

import { ImageOverlay, MapContainer } from 'react-leaflet';
import L from 'leaflet';

const map = { image: '/Trakan_Map.jpeg', height: 4608, width: 6144 };

const CloudsOverlay = () => {
  return (
    <ImageOverlay
      zIndex={-1}
      url="/assets/test-clouds.png"
      opacity={0.4}
      bounds={[
        [0, 0],
        [map.height, map.width],
      ]}
      attribution="(v0.5.1)"
      className={styles.clouds}
    />
  );
};

const TrakanOverlay = () => {
  return (
    <ImageOverlay
      zIndex={-1}
      url={map.image}
      opacity={0.4}
      bounds={[
        [0, 0],
        [map.height, map.width],
      ]}
      attribution="(v0.5.1)"
    />
  );
};

export default function Map() {
  return (
    <MapContainer
      center={[375, 500]}
      zoom={-1}
      maxZoom={2}
      minZoom={-2}
      zoomDelta={0.5}
      zoomSnap={0.5}
      wheelPxPerZoomLevel={60}
      scrollWheelZoom={true}
      maxBounds={[
        [0, 0],
        [map.height, map.width],
      ]}
      maxBoundsViscosity={0.97}
      crs={L.CRS.Simple}
      zoomControl={false}
      className={styles.leafletContainer}
    >
      <TrakanOverlay />
      <CloudsOverlay />
    </MapContainer>
  );
}

Here is the CSS code:

.clouds {
  background-color: blue;
  opacity: 1;
  animation: slideLeft 1s linear infinite;
}

@keyframes slideLeft {
  0% {
    transform: translateX(0px);
  }
  100% {
    transform: translateX(100px);
  }
}

.leafletContainer {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}

0