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
Related
My question is about cells rotation - i'm trying to render scheme, with rotated groups of cells
First i tried to set rotation using style, and i found that selection rectangle renders incorrectly - without any angle
Then i found in source code vertexHandler rotate - this solution worked better, but it requires to render all elements, and only then - rotate them. Whole scheme with 100+ elements blinks every rerender
How to rotate selection rectangle, to render elements without blinking?
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.
I'm trying to rotate an SVG circle (a group of three 120deg arcs actually), and running into problems where the edges of the arcs are being cut off (at least in Firefox)
http://jsfiddle.net/RedDevil/u9u9rbbw/
var circle;
var root = Snap('#arcs');
circle = root.select('.circle');
Snap.animate(0, 360, function(v) {
return circle.transform("r" + v);
}, 2000);
Here is a render of the static rotated circle to highlight the problem
http://jsfiddle.net/RedDevil/gvbtr2Ly/
circle = root.select('.circle');
circle.transform("r" + 40);
I've inspected every parent of the arcs, and none of them seem to be cutting the arcs off. I can't seem to pinpoint what could be causing the cuts... I thought it could be the viewBox, but adjusting the values doesn't help sadly... I've known SVG in many forms over the past, but am new to using it with HTML...
You've probably already figured it out by now, but just incase someone else comes across this issue...
The issue does relate to the viewBox, but also the objects within that viewBox. Basically you need to provide some padding within your viewBox to allow for the rotation. So, if your object is 400 x 400 and your viewBox is 400 x 400 any minor discrepancy will appear to be cut off (ie, out of the viewBox) therefore you should allow some padding. So your object would be 400 x 400 and positioned center and your viewBox could be 420 x 420.
Hopefully that makes sense.
Is it possible to only trigger a div's mouseover when the cursor is over an opaque part of the div's background image? Perhaps via Javascript?
All I can find with Google are old IE PNG fixes.
This looks like a similar question to this one: Hit detection on non-transparent pixel
I suppose this could also be done for background image by getting the attribute with jQuery:
$('#myDiv').css('background-image');
I haven't personally done this, but it seems like a viable solution. This will only work for modern browsers, but you should be able to make it back-compatible with excanvas.
It is possible, just not very easily. You'll have to use a lot of Javascript.
You'd want to attach to your <div>'s onmousemove event, which returns the X,Y coordinates of the cursor. Your event handler function would then test to see if the cursor is in the correct place in order to trigger an alternative onmouseover event.
Implementing the "is the cursor over an opaque pixel or not?" test can be done two ways: the first is to create a simple mathematical expression (say if the opaque parts of the image make neat rectangles, circles or polygons). The more difficult (and less browser-supported) way is to load the background image into a Canvas object and then get the current pixel value's opacity figure and take it from there, like so:
var pixel = canvas.getImageData(x, y, 1, 1).data;
var alpha = pixel[3]; // assuming RGBA
if( alpha > threshold ) onMouseOver(); // raise the event
Another alternative is to create an entirely transparent div (or some other element) positioned and sized so that it only covers the opaque part of the div below, then just test the mouseover of that element's box.
It's a bit of tweaking but why don't you add a class to your opaque div, and use JavaScript to check for it?
In jQuery:
$('div').mouseover(function(){
if ($(this).is('.opaque')) {
//Some actions
}
});
Usless Background Info
Hello, all. This is my first post here, but I often come here for help.
I am an amateur web designer and have been in web designing for almost a year now.
The Problem
My question is about CSS3 transforms. I have a small, circular element in the center of my page that transforms successfully when I hover over it. I have a larger circular element that is, by z-index, underneath it. The larger circle also has CSS3 transforms coded in the CSS, but will not transform, or even triggerd when hovered over. Both circles are overlaid, with the smallest on top, to create concentric circles.
My Attempted Solution
One word: Z-index. I have tried putting the larger circle on top, which works fine. The problem with this is that the smaller circle no longer triggers...
The Result I Want
I would like for the circles to remain in their 'concentric' positions and for the larger circle on the outside to transform by :hover. Is it possible to have an 'alternate trigger'? e.g.: in JavaScript, I can trigger an animation by hovering over any element that I specify. Is this possible to do in CSS? Can I hover element (I), and change properties for element (II)? If I cannot do this, how would I go about triggering animations for both circles, by hovering over only one? I am trying to stay with pure CSS/HTML, but I will accept JavaScript answers.
Last Notes
I hope I have provided ample info for a decent answer... Here is a screenshot: http://i.stack.imgur.com/WPj62.png
The circle with the infinity sign is the smaller circle element. The larger circle with the faint border around the screen is the other element.
EDIT:
Something's still not right, please take a look at the full code posted here: http://cssdesk.com/eJ8BH
If I understand your question, it sounds like when you hover over the small circle, you want both the large and small circle to transform, correct?
The easiest way is likely to use javascript for this. If you are using jQuery, it's even easier:
$('.littleCircle')
.hover(function(){
$(this).addClass('myTransformationClass');
$('.biggerCircle').addClass('myTransformationClass');
})
UPDATE: Some further examples based on follow-up feedback.
Here's what I'd do. First, give all 4 related elements a class so you can grab them via jQuery. For the example I use .rolloverSet
// grab all 4 elements and cache them
$rolloverSet = $('.rolloverSet');
// grab the one element that needs to have two classes
$otherElement = $rolloverSet.find('.otherElement');
$rolloverSet
.hover(function(){ // we'll add a hover event to each element in the group
$(this).addClass('myTransformationClass');
$otherElement.addClass('myOtherTransformationClass');
})
.blur(function(){ // remove the classes on mousout
$(this).removeClass('myTransformationClass');
$otherElement.removeClass('myOtherTransformationClass');
})
You do not need jQuery for this. You need to apply :hover on the parent element of the concentric circles and then apply the animation to its immediate children like this: http://jsfiddle.net/nimbu/taqr4/
Things I changed:
Updated to use shorter transitions, animations property
Added moz, o, unprefixed properties
Removed -webkit- from border-radius
Gathered common properties of concentric circles to prevent repetition
Fixed incorrect background-color (#00000000)