SVG uneven stroke-width - css

The fiddle below shows an SVG map with CSS hover animations.
https://jsfiddle.net/persianturtle/akkjcmo1/
svg .state:hover , .state.active {
cursor: pointer;
stroke-width: 4;
stroke-alignment: inner;
stroke: #000;
z-index: 100;
}
It doesn't seem that the stroke-alignment: inner; property is being applied. It seems that different states on the map have different strokes depending on which state the border is 'owned' by. Is there a way to have a unified stroke width for all hovered states?
To see the problem clearly, hover over California and then Utah. California has a nice unified stroke-width. Utah does not.

Take a look at this:
I made the stroke width 15 just to show that it's a matter of what element gets printed first. in SVG, you kind of can't set a z-index to the elements because their priority is set by the order in which they appear in the code. You'd need some JavaScript (I think) to re-order the elements. A good starting point is this question: SVG re-ordering z-index (Raphael optional).
Also, as pointed out in the comments, stroke-alignment is still a working draft and might simply not be working.

So, I ran into this with a polygon, exactly the stroke behavior you described and stroke-alignment: inner; not being acknowledged.
So, because the stroke-alignment is being ignored, the part of the stroke on the very edge of the artboard get clipped.
I have a greatly simplified version of what you're doing and I'm calculating my points dynamically, but the work around was to set my polygon/path a couple of pixels inside, so for example point 0,0 becomes 2,2.
Then all the points and their outside/center aligned strokes fit inside the artboard and don't get clipped.

Related

Cystoscape, trying to display images instead of nodes

I'm trying to display images instead of nodes using Cytoscape.js to create a network diagram, but I haven't had any success yet. I started with the Images and breadthfirst example (https://gist.github.com/maxkfranz/aedff159b0df05ccfaa5), but there are a couple key things I would like to change.
For starters, I'd like to display an image only instead of a node. The above example displays a circle node with an image inside it. Is there any way to make the node completely transparent, and just let the image show through? I just want to see my vector icon images. When I delete all style properties for my node selector except width and height, I still see a circle constraining my image. I just want to see my image.
Next, I'd like to use something on the element data to decide what image to use instead of the #nodeId mechanism in the example above.
.selector('#order-db')
.css({
'background-image': 'https://farm8.staticflickr.com/7272/7633179468_3e19e45a0c_b.jpg'
})
Using a unique selector for each id is not very scalable or easy to modify. I'd prefer a declarative approach where a property on the data element determines which image to display. I tried using the "classes" property on an element, and I added a "shape-database" value to it. Here is how the class is defined...
.shape-database {
width: 95px;
height: 95px;
/*background: url('images/network-icons.jpg') 0px -95px;*/
background: url('images/database-5-med.png');
}
I then tested that the "shape-database" class was working by adding a simple div to the page, and the class is working properly on a normal div. The cyto node I added the classes property to does not display the background image. It's as if the class was not applied to the node, or else the node is blocking the image somehow. This is with the exact same code I was using above, with all the node selector css properties removed except width and height, and the #order-db css selector removed. I just see a grey circle for the node.
When the classes property on the element didn't work, I even tried the following to no avail...
cy.$('#order-db').addClass('shape-database');
Any thoughts on what I'm doing wrong? A link to an example displaying just images instead of nodes would help as well.
Displaying an image instead of a node:
The key here was in hiding the node background and border completely, so that the background image alone shows through. The key to accomplishing that is through "background-opacity" and "border-opacity" (or "border-width") on the style objects. I added an image property (value is an img src) to the data object for each element that I wanted to swap out with an image, as well as the following style.
{
selector: 'node[image]',
style: {
'background-image': 'data(image)', // specify some image
'background-opacity': 0, // do not show the bg colour
'border-width': 0, // no border that would increase node size
'background-clip': 'none' // let image go beyond node shape (also better performance)
}
}
This also satisfied my requirement to use the element data to designate which elements are to be replaced with images and which images to use, instead of hard-coding a unique style and image for each element id.
I never got the classes data property to have any effect whatsoever on the background-image of a node. Perhaps there's a bug there.
Hopefully, this will help someone in the future because it was not obvious to me that background-opacity etc. made the entire node invisible. From the documentation, it sounded like it affected the node's background. Knowing that I was altering the background image for the node caused me quite a bit of confusion around nodes and backgrounds. I'm still quite fuzzy on all the layers and how they interact, but the above works and is better in my opinion than the image example given on the cytoscape site.

How to invert a css clip-path or animate hard-stops in SVG radial gradients

It seems that generally a css clip-path is used to hide beginning at the edges of an element. I can use something like this:
clip-path:circle(70% at center);
and get something like this:
Is there a way I can invert that? I want my result to be something like this:
I want to clip the center of the image, not the edges. It's an SVG, so I tried something like this pen, animating a radial gradient: http://codepen.io/ethanclevenger91/pen/myMYwQ
But that didn't work like expected. There's the animated one and then one with what I assume the final step of the animation cycle should look like, but it doesn't. Any light on either of these would be appreciated.
You can use a still use a clipPath if you use it in its url form i.e. as svg markup. Draw the path outer rectangle clockwise and the inner ellipse (using two or more elliptical arcs) anticlockwise, drawing everything as a single path together with clip-rule="evenodd"
Alternatively you could use a <mask>. This is a simpler, but slower solution. Draw a white ellipse within the mask area and that part of the mask will be opaque.
So here's what ended up happening:
Since the background I was trying to match was a solid color, I gave the circles a stroke double their radius (since stroke is applied centered on the edge of the object) and then applied a clip-path the size of the object. Then I animated the stroke to 0. Will update with a link to the application when it's live.

How do I get rid of PNG invisible borders?

I'm new to web programming, recently I've been asked to make some home pages for someone.
Unfortunately I've run into some problem, the homepage will be on a touch screen for touch input, I've got reports like buttons most of the time doesn't work when clicked on, one of my suspects is invisible borders caused by PNGs.
TL;DR - http://puu.sh/6HQez.jpg The corner of the red button is being blocked by the invisible border of the purple button, are there any ways to fix that?
EDIT: No I'm not asking for how to remove the dotted line, I made them visible to show you.
It seems like what you are referring to is not an 'invisible border' but an 'invisible background'.
Your PNG files are rectangular shaped when it comes to event handling, even if some parts are transparent.
If you need to disable some elements from being clicked, you can go about it few ways:
Disable pointer-events with CSS to make sure that a specific
element does not caputre clicks.
#mypurplediv {pointer-events: none;}
Use Z-index to decide the hierarchy of your elements:
#mypurplediv {z-index: 0;}
#myrediv {z-index: 1;}
EDIT:
Per your comments, it seems that you need to retain the abiity to click on ALL elements.
As I mentioned above , your current PNGs are actually rectangles with some parts being transparents.
So you have these options:
1) Use SVG which are vector based shapes (that will by default not have invisible backgrounds). Good tutorial here.
2) Use image mapping and area to create your shapes and give them href. This is a good tutorial about image mapping.
example - <area shape="poly" coords="74,0,113,29,98,72,52,72,38,27" href="index.htm">
3) Use 3rd party javascript/jQuery libraries such as ImageMapster.
Hope this helps!
That dotted border is called focus outline. You can turn it off by applying CSS to the image.
img { outline: none; }

Webkit CSS Transitioning Rotation Not Spinning

I'm having difficulty rotating an item a full 360 degrees in webkit using CSS transitions.
I've created a JS Fiddle to show what I'm trying to do: http://jsfiddle.net/russelluresti/PnTk8/2/
The transition should happen in 2 steps. First, the item should just rotate along the Y axis for a 1/2 turn. Then, once that transition is complete, it should rotate the opposite direction a full turn and scale down to 1/2 the original size. The problem I'm having is that the second transition is only scaling and not rotating, even though rotate values of rotateY(-360deg) and rotateY(0deg) should cause a full rotation.
This is just a proof-of-concept, so I'm only targeting webkit at the moment. However, I'd like to stick with transitions, and not keyframe animations. Any ideas?
In my knowledge, rotate from rotateY(-180deg) to rotateY(-360deg) would be as the same state as rotateY(0). Let's put it this way: imagine you flip a piece of paper twice in the same direction, would be totally the same state as the very beginning. As a result, the browser take it for 'no changes at all', therefore no transition upon the rotation.
another example would make this even clearer:
given deg. set to your case, rotateY(-90deg) => rotateY(-300deg) => rotateY(60deg) would work just the same, the second transition won't start. Becuz relative to the original state: rotateY(0), rotateY(-300deg) is just at the same state as rotateY(60deg).

IE gradient filter doesn't respond to click event

I want to have a transparent background-color and I use gradient filter as a fallback of RGBA in IE. The code is like this:
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#bfffffff,endColorstr=#bfffffff);
I also want to trigger an event when the user clicks the background, but it seems like the click event doesn't get triggered after I set the filter. Everything is ok without the filter.
So is it another IE bug? How can I solve the problem?
This is probably related to the IE bug that makes links with transparent background no longer clickable: I came across it today. I had a link with a transparent background and display set to block: the main area of the link wasn't clickable, but a 10px border I set on it was. It seems IE also has problems with filters.
This kind of bug is discussed here and here. The first guy's solution is to give a fake background image to the element before setting the filter. The second guy's is to give the element a background colour and set the opacity to 1%, which will make it practically invisible in IE. Hopefully you'll be able to get round it using one of these.
This is not the deal.
Internet explorer creates the filters on a separate layer which is placed above your element and since the new graphic layer is not part of the element - which you have the click event on - there will be no event bubbling.
Recently I made a label element with a nice gradient filter for IE. Only the text can be clicked. If I analyze the label layers from the side with and without the gradient layer, then you will understand the problem.
without gradient filter:
------------------
text layer
------------------
background layer
------------------
with gradient filter:
------------------
text layer
------------------
gradient layer
------------------
background layer
------------------
By the way, that is the reason, why you cannot put a border radius on a gradient filter too. Try it. Create an element, and style it with border radius and give it a gradient filter and run it in IE 9. No matter how you try to force the gradient to stay inside the round borders - with for example overflow:hidden -, it will never obey. Its like a separate element which is positioned absolute and right above your element to cover it up and right under the text.

Resources