I'm trying to create an svg inside a leaflet control but I think my css/html knowledge is failing me: the browser inspector reports the size of the svg as 0x0. I can hack it by setting the svg position property to absolute, and the inspector reports the height/width I set, but the circle I render inside the svg still has size 0x0.
http://jsfiddle.net/n8L9ojej/4/
// Create the map
var map = L.map('map').setView([39.5, -0.5], 5);
// Set up the OSM layer
L.tileLayer(
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{maxZoom: 18}).addTo(map);
// add a marker in the given location
L.marker([36.83711,-2.464459]).addTo(map);
var control = L.control();
control.onAdd = function(map){
this.div = L.DomUtil.create("div"); this.div.setAttribute("style","height:100px;width:100px;background:white");
return this.div;
};
control.addTo(map);
svg = L.DomUtil.create("svg","test",control.div);
svg.setAttribute("style","height:90px;width:90px;");
d3.select(".test").append("circle")
.style("stroke", "gray")
.style("fill", "white")
.attr("r", 50)
.attr("cx", 50)
.attr("cy", 50);
The controller is on the upper right.
According to the leaflet documentation L.DomUtil.create always returns an HTMLElement.
SVG elements are of type SVGElement, so it seems that L.DomUtil.create cannot create these. What leaflet actually does is create an html element with the tag name svg.
You may find that learning more about namespaces is useful.
d3 is equally comfortable working with SVG and html elements but the browser will only render elements if they are created in the right namespace so an SVG element with the tag name p will not function as an html paragraph and equally an html element with the tag name line will not function as an SVG line.
There are elements that have the same tag name but different functionality which is why namespaces are necessary e.g. the SVG a element and the html a element.
Related
I am using D3 js to append an HTML block to an SVG using foreignObject.
Once appended I am selecting the element by id and changing the x,y attribute to move
d3.select("#" + id) .transition() .ease(d3.easeLinear) .duration(1000) .attr("x", "100") .attr("y", "220")
The transtion happens as expected but it leaves a trail of lines some times, Issue couldnt be reproduced consistantly
foreignObject is the only way to group HTML elements and append it to an SVG.
Tried to change the duration, transition time, CPU throttling, adding the block in window.requestAnimationFrame -It is not helping
I've included a zoom functionality similar to the one explained at this website:
http://www.flashandmath.com/howtos/zoom/
This works perfectly on my background image(a map, that is), but I want to keep the symbols on my map the same size while zooming in.
I probably could work this out by changing all the children's size when calling the zoom-function, but I am hoping there is some kind of easy code adapt in my children class to make the size of the instances unchangable. Is there?
Thanks!
One crude way, so you don't have to calculate the symbols scale, would be to remove the symbols from the mapDisplayObject so they're no longer a child and instead put symbol placeholders. Then match each symbol's x and y to each place holder, using localToGlobal...
If your children are not scaled or skewed or rotated you can iterate all of them and set transformation matrix to 1/parentScale. Something like:
for each (var child:DisplayObject in parent) {
var matrix:Matrix = child.transform.matrix;
matrix.a = 1/parentScale;
matrix.d = 1/parentScale;
child.transform.matrix = marix;
}
I am currently attempting to make a button which is in the shape of a trapezoid.
I found a method of creating the shape which involved CSS making borders and such.
The CSS method worked in the way that it made the shape, but I ran into an issue where the whole element is contained in a rectangle, so when you click in the white spaces outside of the trapezoid it will still register as a click in the element.
In short, I am trying to make the HTML element to be the shape, of a trapezoid, not just the visible shape itself. Thus when a user clicks any area around the button that is outside the visible Trapezoid, but may be within the actual boundaries of a button rectangle, it should ignore the click. Thanks.
Edit:
It was asked that I show an example of what I mean.
http://jsfiddle.net/MichaelMitchell/aR72g/9/
In this link, there is the red trapezoid, but you can see the background color is also green, and when you were to click the green it still activates an onclick. In other word, I only want the red to be able to trigger the onclick.
You cannot have other clickable areas than rectangles in HTML if you are not willing to do the trickery involving map attribute and image (see docs), but even then your image will always wrapped in rectangle bounding box (so you can only pretend to have different shape by using images with transparency and said map).
You can work around this by giving it an onmousemove event that determines whether or not that coordinate is actually inside the trapezoid and adds/removes the onclick event accordingly. Something like this:
<figure id ="trapezoid" onmousemove="trapezoidMouseMove(event)">
<p>Button</p>
</figure>
<script>
function trapezoidClick(e)
{
//Whatever you need it to do
alert("inside");
}
function trapezoidMouseMove(e)
{
//Fill in the angle of your trapezoid
angle = Math.PI / 4;
insideLeft = e.offsetX > Math.tan(angle) * e.offsetY;
insideRight = e.offsetX < e.toElement.offsetWidth - Math.tan(angle) * e.offsetY;
if (insideLeft && insideRight)
{
e.toElement.style.cursor = "pointer";
e.toElement.onclick = trapezoidClick;
}else{
e.toElement.style.cursor = "default";
e.toElement.onclick = null;
}
}
</script>
Is there a way to change the style of the white squares that are used as vertex handles by default when a polyline is set to editable:true?
I can see that changing the stroke of the polyline affects those handle squares, but I'd like to either change the shape of handle (e.g. to a circle), or substitute an image.
The only way I've managed to found is a direct manipulation of DOM elements corresponding to those markers. For instance, they may be selected using
$('div').filter(function() {
return $(this).css('width') == '11px';
})
Probably, more reliable approach is a DOM tree traverse starting from $('.gm-style') element.
I'm having my first experience in developing html5 applications. My issue is to make room plan. In the top of the page I have elements to drag to the bottom map area (they are copied). In the map area I can move elements, but not copy.
I've built drag'n'drop with help of image elements. But now I want to use canvas for updating numbers on images. I want to use canvas text functions for updating images.
The problem is when I copy canvas element from the top, html inserts well, but it is not drawn in some reasons.
Please, watch code here http://jsfiddle.net/InsideZ/MuGnv/2/. Code was written for Google Chrome.
EDIT:
I made a few small tweaks here: http://jsfiddle.net/MuGnv/5/
Note the changes made to the drawImg function:
function drawImg(src, targetClass) {
$(targetClass).each(function() {
var ctx = $(this).get(0).getContext('2d');
var img = new Image();
img.src = src;
img.onload = function() {
ctx.drawImage(img, 0, 0);
};
});
}
Anytime a drop event is handled, the images are drawn again. This was the missing component as the image was only being drawn once.