1

I have a leafelt map app where first I initialize and add a tile layer like so:

<body>
    <div id="map"></div>
    <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
    <script>
        // Initialize the Leaflet map
        var map = L.map('map').setView([51.505, -0.09], 13);
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; OpenStreetMap contributors'
        }).addTo(map);
    </script>
    <script type="module" src="/main.js"></script>
</body>

You can see I call an external JS file directly after using a script tag of type module and calling a main.js file as src. In that script, which uses three three.js libraries to create an object that ends up under the map vector tile layer, I can it. Main.js looks like this:

import * as THREE from 'three';

// Initialize the Three.js scene
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

var renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById('map').appendChild(renderer.domElement);

// Add a simple box to the Three.js scene
var geometry = new THREE.BoxGeometry();
var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);

camera.position.z = 5;

// Animate the Three.js scene
function animate() {
    requestAnimationFrame(animate);

    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    renderer.render(scene, camera);
}
animate();

// Synchronize Three.js with Leaflet
map.on('move', function() {
    var center = map.getCenter();
    var scale = Math.pow(2, map.getZoom());
    
    camera.position.x = center.lng * scale;
    camera.position.y = center.lat * scale;
    camera.position.z = 500 / scale;  // Adjust this value for better visualization

    camera.updateProjectionMatrix();
});

map.on('zoom', function() {
    var scale = Math.pow(2, map.getZoom());
    
    camera.position.z = 500 / scale;  // Adjust this value for better visualization

    camera.updateProjectionMatrix();
});

But, the objects I create and add to the map in the external main.js always go underneath my tile layer.

Is there a way to get them to be on the map?

0

1 Answer 1

1

All Leaflet div elements that contain different parts of map are positioned absolutely and each has its own z-index value to control vertical placement.

You are adding created canvas element created by three.js after all the Leaflet elements. Since it's not positioned absolute, it's shown below map.

All you have to do is to set canvas element placement as absolute and then set some high z-index value.

Relevant part of the code could then look something like this:

var renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);

renderer.domElement.style.position = 'absolute';
renderer.domElement.style.top = '0';
renderer.domElement.style.left = '0';
renderer.domElement.style.zIndex = '1000';

document.getElementById('map').appendChild(renderer.domElement);

That's the result:

enter image description here

1
  • Thanks so much, TomazicM, as that was indeed the issue.
    – geo derek
    Commented Jun 20 at 19:58

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.