On desktop onmouseover it changes color to green and then I click it changes to red but in mobile devices both event goes at the same time. Is it possible to make on tap changes to green color then on 2nd tap it goes to red color?
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="600" version="1.1" style="display:inline">
<g>
<rect id="rect1" x="160" y="10"
width="60" height="60" fill="blue"
onmouseout="evt.target.setAttribute('fill','blue');"
onclick="evt.target.setAttribute('fill','red');"
onmouseover="evt.target.setAttribute('fill','green');"/>
</g>
</svg>
fiddel
thanks!
The right behavior on touch devices usability-wise would be to color the rect green when the touch starts, if the user drags the finger off the rect then it would go back to blue. If the user releases at the same target it would change the color to red. This behavior could be replicated with CSS (removing your onmouseout and onmouseover handlers):
rect {
fill: blue;
}
rect:active {
fill: green
}
Now, if you really want it to behave in the way you describe (first tap is green, second tap is red) then you'd have to keep the state somewhere (in the DOM?) which complicates things, from the top of my mind I'd try...
ontouchend="evt.target.getAttribute('data-clicked') === "true" ? evt.target.setAttributed('fill', 'red') : evt.target.setAttribute('data-clicked', 'true')";
The problem with this is that you can start the touch at a different point and end the touch at the rect element.
Related
I have a small SVG canvas in my application which houses a button to click. Upon clicking that button, the small circle does some flashy work and opens up to an appropriate sized bubble to fit all the data. This data is just a list of data with custom bullets off to the left; some of this text is clickable (bound to click events) and causes other functions to be fired off. My problem is that the SVG canvas never changes in size. It's really only big enough to contain the original circle that the user clicks on. The rest of SVG elements that make up this control flow outside the bounds of the SVG canvas, but is all viewable due to the SVG having its overflow set to visible. Everything works fine in all browsers, but things change when I open up the application in an iPad or on a Mac (regardless of browser). It seems the overflow pieces of my SVG are completely invisible to the browser. Any click event that fires fine on the overflowed SVG elements on Window's browsers are completely invisible on OSX/iOS browsers (it seems like any click actually falls through to whatever is behind the overflowed SVG). At first I thought it was an issue with the click binding, but after searching and playing around with it, I think OSX/iOS just doesn't handle overflowed SVG very well.
To explain in its simplest form what's going on in my application, I have a very simple JSFiddle here: https://jsfiddle.net/yno8daka/
HTML:
<svg style="overflow: visible !important" class="canvas" width='70px' height='70px' xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<circle id="circle1" stroke="black" fill="black" stroke-width="1" cx="10" cy="10" r="10"></circle>
<circle id="circle2" stroke="black" fill="black" stroke-width="1" cx="110" cy="110" r="10"></circle>
</svg>
Javascript:
$('#circle1').click(function() {
alert('yeah');
})
$('#circle2').click(function() {
alert('yeah2');
})
Circle1 is in the bounds of the SVG canvas, while circle2 is not. On Windows browsers, you will be able to click on both circles without any issue. On OSX/iOS browsers, the click event will fire for circle1, but not for circle2.
Does anyone know how to get this to work?
When an Excel cell referencing other cells is selected, the referenced cells are systematically highlighted with different colours. I would like to imitate and reproduce this effect in JavaScript and CSS.
For instance, in the beginning the background colour of Cell A1 is gray:
Once we double click on Cell C2, its referenced cells are highlighted:
We only learn the background colours (and ignore the border colours). A3 now is in purple; A2 is in purple on top of red; A1 is in purple on top of red on top of blue on top of gray.
Does anyone know how this colour effect is called (eg, overlay, hover)? Is there a notion of opacity there? Given the colour code of purple and red (and maybe an opacity number), is there an easy way in JavaScript and CSS to produce the colour of A3?
The only thing I can think of is by using svg and rectangles, dynamically generating them and assigning them colors based on numbers of cells selected (I suppose Excel assigns random colors?!). You can achieve the overlay effect by using mix-blend-mode (see snippet below, pay attention to the colors defined and the colors displayed).
.multiply {
background: white;
}
.multiply rect {
mix-blend-mode: multiply;
}
<svg class="multiply" width="400" height="500">
<rect fill="cyan" width="150" height="20" x="0" y="0" />
<rect fill="yellow" width="100" height="40" x="50" y="0" />
<rect fill="magenta" width="50" height="60" x="100" y="0" />
</svg>
Another way you can do it (this is more Javascript oriented) is to compute the RGB value of the colors you want to combine and then by using the R, G and B values create the overlayed color, see link
I'm working with animated SVGs / Snap.svg for the first time, so please forgive my lack of knowledge on this subject.
I made a series of 3 animated SVG "frames" (400x300px), each nested within a larger SVG (1200x300px) to contain them all. A div element with a clip style property hides the other two "frames" when they're not ready to be shown.
Using Snap.svg, each frame is supposed to "slide" into view using translate after a certain amount of time, and within each frame are some animated elements.
Long story short: the animation looks perfect in Firefox, but it looks awful in Chrome/Webkit. In Chrome, it looks like each of the frames are just being stacked on top of each other instead of side-by-side.
In addition, two of the elements (the cow circle joules and the graph circle graph) are rendering in the upper-left corner instead of using their translate property to position them in the center-right area.
You can see the animation in Plunker. Please try it out in both browsers to see what I mean.
http://plnkr.co/UhTy83
Firefox GIF screen capture:
Chrome GIF screen capture:
Thanks Ian in the comments to my question! Swapping out the <svg> tags for <g> (group) tags fixed this problem. It's interesting to me that Firefox allows you to transform <svg> elements but Webkit does not.
Before:
<svg class="slides" width="1200" height="300">
<svg class="slide1" width="400" height="300"></svg>
<svg class="slide2" width="400" height="300"></svg>
<svg class="slide3" width="400" height="300"></svg>
</svg>
After:
<svg class="slides" width="1200" height="300">
<g class="slide1"></g>
<g class="slide2"></g>
<g class="slide3"></g>
</svg>
I need to have an area for which I would set mouse over event. How can I do that in JavaScript?
This area should be
easy to define
invisible (i need the background to be visible).
To make an svg shape(polygon,rect,circle,path) invisible, the fill attribute is set to "none". And to make it still respond to events you include pointer-events="visible". Then you include a mouseover event within the shape. Note:
evt is the svg event object call. The function itself can also apply outside of the element(target) to which it is attached. For example, the function could draw a circle anywhere in the svg root.
e.g.
<svg id="mySVG" width="400" height="400">
<rect id="myRect" x="0" y="0" width="100%" height="100%" pointer-events="visible" fill="none" onmouseover="myEvent(evt)" />
</svg>
<script>
function myEvent(evt)
{
var target=evt.target
target.setAttribute("fill","red")
}
</script>
I'm having a little trouble working out if this is even possible with D3 let alone how to do it.
I have a rect elements that I have attached 3 event handlers to ("click", "Mouseover", "mouseout"). This is all working great the only trouble is that I also add a text element to the the same <g> that is placed on top of the rect element. like this:
<g>
<rect x="204" y="204" width="204" height="204" style="fill: yellow; pointer-events: all; fill-opacity: 0.402592;" stroke="none" stroke-width="0" stroke-dasharray="15,15,15">
<text class="word" x="306" y="306" text-anchor="middle" fill="black" style="fill-opacity: 1.00648;">Text Element</text>
</g>
The problem I'm seeing is that the mouseout event is fired when the mouse is still over the rect but the text element is immediately below the mouse and basically "inbetween" the mouse and the rect below the text.
Is there any way to make the text "invisible" to the mouse?
I guess if we were talking WinForms/WPF the analgulous feature I'm looking for in D3 is something along the lines of IsHitTestable=false.
Typical isn't it ... just as I ask the question the solution presents itself.
In order to hide stacked elements from mouse events add this style declaration:
.style("pointer-events", "none")