-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Feature Request: SVG symbols (via addImage) #5529
Comments
Also I'd like to note that the docs say I get this error: |
@krabbypattified did you try https://www.mapbox.com/mapbox-gl-js/api/#marker The following tutorial works also with SVG: |
@pathmapper yes I have tried Markers. I need to animate it so I even jerry-rigged an animation mechanism for it. The problem is that on mobile it gets slow and the markers lag behind the rest of the map. Basically all I’m trying to accomplish is this demo: |
You need to rasterize your SVG so it can be used as an icon-image. You can do this by rendering the SVG into a canvas: Then you should be able to get the image data from the canvas 2d context:
|
Passing an |
Thanks @jfirebaugh! There was something srewy with my version (i was using a fork). import mySVG from 'foo.svg'
let img = new Image(20,20)
img.onload = ()=>map.addImage('bus', img)
img.src = mySVG |
@krabbypattified how do you add the image to the layer?
And the layers don't show. Here is my code:
|
Ive come across the behavior as described by @gabrielmoncea (especially in chrome) and think ive figured out whats going on. The issue is that
|
#6231 may be related |
Had a similar issue on Firefox v65. Turns out Firefox currently requires both a Perhaps a little bit overkill, but Mapbox-gl could attempt to resolve this internally by type-checking the src of a passed HTMLImageElement and updating with width & height attributes where appropriate. Or warning when the resultant image data is fully transparent, e.g. const isTransparent = (data /* canvasImageData */) => {
const len = data.length / 4; // insert fancy accuracy factor here
for(let i = 0; i < len; i += 1) {
// insert fancy inside-out iterator here
if (data[(i * 4) + 3]) { // check opacity is larger than zero
return false;
break;
}
}
return true;
};
if (isTransparent(imgData)) console.warn('Your symbol is invisible!'); |
I modified @bdirito's excellent solution to remove the dependency on rxjs, and it's working well for me. The first method generates the ImageData from an external path, and the second generates the string for an inline image src.
I'm using |
SOLVED:- This is the best solution I have found - thanks so much for sharing the outcome of your journey! In my instance, I needed to load "many" svgs, so simply created a map of them and ran this snippet in a loop:- // CustomIcons.js
import CustSVG from './CustSVG';
import CustBlueSVG from './CustBlueSVG';
const CustomIcons = [
{
src: CustSVG,
name: 'custom-svg'
},
{
src: CustBlueSVG,
name: 'custom-blue-svg'
}
];
export default CustomIcons; Then I import these, and use them within the useEffect hook of my Component: // MapComponent.js
import CustomIcons from './CustomIcons';
function MapComponent() {
// ...
useEffect( () => {
map.on('load', function () {
CustomIcons.forEach(icon => {
const customIcon = new Image(24, 24);
customIcon.onload = () => map.addImage(icon.name, customIcon)
customIcon.src = icon.src;
});
// ... the rest of your map code that uses the SVGs
});
}, []);
} Thanks again, super helpful! |
Thanks in advance. |
Motivation
Use with Webpack (for modern workflows)
This isn't a great solution:
Can we use svg symbols? #1577
And this isn't either (yuck, callbacks).
mapbox-gl-js version: v0.41.0
The text was updated successfully, but these errors were encountered: