RaphaelJS with rgba gradient fill - javascript

I am trying to create a gradient fill with RaphaelJS that uses rgba colors. In other words, I want both the start and end points to have a degree of transparency. For instance, 20% black to 0% black. How is this done?
This fiddle is how I expect that this would be accomplished but as you can see, the bottom black is completely opaque. http://jsfiddle.net/4aPj2/
r.circle(50,50,50).attr({fill:'90-rgba(0,0,0,0)-rgba(0,0,0,0.2)',opacity:0})

Ok,
previous answer is a red herring for anyone looking at this question. I just spent half a day digging around through the raphaeljs source code. It's not this simple. So Raphaeljs actually already has some built in support for this and anything you try to modify like above won't work as the built in support will override it later.
The support that Raphaeljs currently has allows you to set the transparency of the final color-stop using the opacity attribute and the fill-opacity, so for example this:
r.circle(50,50,50).attr({fill:'90-#000000-#0000ff',opacity:0})
would translate in the real world to a circle with 100% opacity in the first color stop(black) in the center and 0% opacity in the final stop(blue). Another example :
r.circle(50,50,50).attr({fill:'90-#000000-#ffffff',opacity:0.5})
would produce a real world circle with 100% opacity black in the center and 50% white opacity around the outer of the circle on the final stop.
There is no current way in Raphaeljs to support different opacities on both color stops but if you desperately needed to do this this source line you would need to modify would be here :
$(stops[stops.length - 1], {"stop-opacity": value});
It's located at 6265 in the current version of Raphaeljs (2.1.0).
I hope this helps someone avoid the hours of debugging RaphealJS source code I just spent....

There is a workaround, but that involves editing raphael.js
Locate the code block:
el.appendChild($("stop", {
offset: dots[i].offset ? dots[i].offset : i ? "100%" : "0%",
"stop-color": dots[i].color || "#fff"
}));
And replace it using:
el.appendChild($("stop", {
offset: dots[i].offset ? dots[i].offset : i ? "100%" : "0%",
"stop-color": dots[i].color || "#fff",
"stop-opacity": R.is(dots[i].opacity, "undefined") ? 1 : dots[i].opacity
}));
Update: Later figured out that I had accidentally missed a one-line change from my patch.
Next, locate the following line within the function R._parseDots
par[2] && (dot.offset = par[2] + "%");
and replace it with
dot.opacity = dot.color.opacity;
par[2] && (dot.offset = par[2] + "%");
With the above code, you can easily use something like myRect.attr("fill", "90-rgba(255,0,0,0.25)-rgba(0,255,0,0.75)-rgba(0,0,255,0.25)"); But note that the solution is for SVG output, VML does not support this. VML only supports a single opacity on gradient at 0% position and optionally a second opacity for the last opacity at 100% position. There would be a few more code changes for VML that I am not including here.
The code can be seen in action in the fiddle http://jsfiddle.net/shamasis/SYdJW/

Related

SVG Rotate Element While Animating svgjs

I'm using Javascript, Jquery, SVG, and SVG.js right now. I would like to rotate a circle about its origin while it's animating. The animation is doing the same thing, so I could use some sort of step function but I couldn't find anything. The problem is that with my current solution the animation is janky, it has to stop the animation, rotate the circle, and then start it again. Which in sequence has too much of a delay and causes a wiggling motion. Here's the setup code:
var draw = SVG('svg');
var innerCircle = draw.group().addClass("atom0g0").move(100,100);
innerCircle.circle(100).addClass("atom0p0").center(0, 0).attr({ fill: "white", stroke: "blue", "stroke-dasharray": "10" });
innerCircle.animate(6000).rotate(360, 0, 0).loop();
And the executing code right now, which I need to change to something is here:
var elms = $(".atom"+atom.atom_id.toString()+"g0");
for (var j=0; j < elms.length; j++) {
// this is the problem, too much of a delay, therefore causing a wiggle motion.
elms[j].instance.animate().stop();
elms[j].instance.rotate(step, 0, 0);
elms[j].instance.animate(6000).rotate(360, 0, 0).loop();
}
Here's the CodePen that I'm working on right now to make it: Current Version or Bugged Version
In short (if you just skipped to the end here) I need to rotate a circle without stopping the animation of the circle completely. I know that play(), pause() doesn't work because I can't call rotate() while the animations paused.
Accepted answer:
Try to wrap your element with one more element and animate them separately.
One of the solutions is to change this line:
elms[j].instance.rotate(Math.random()*360, 0, 0);
into that:
elms[j].instance.animate(1000).rotate(Math.random()*360, 0, 0);
This way rotation will be animated.
Codepen: https://codepen.io/soentio/pen/POVLYV
Other of the possible solutions i to utilise css for your transitions. By adding following line:
#svg > g {
transition: transform 1s ease-in-out;
}
you make sure that whenever a group (that is direct children of your svg root node) is rotated, it's gonna be animated smoothly.
CodePen: https://codepen.io/soentio/pen/gXqqNQ
Advantage of this approach is that whatever your rotation is, browser picks the shortest path.
Bonus:
I believe in superiority od css animations ( ;-) ) and inspired by your code made you a little codepen fiddle: https://codepen.io/soentio/pen/YEBgyj
Maybe your goals are to be achieved with css only?

How do I remove the vertex border in mxGraph?

I'm trying to get it so that a vertex will highlight a border on a mouse over, but have no border otherwise. I've tried using the strokewidth and stroke color to do this, but the border doesn't seem to obey me setting it to zero, there's always a 1px outline.
Looking at the source code I have I see:
var strokeWidth=Math.max(1,this.strokewidth*this.scale);
So should I override this and remove the Math.max call so the 1px minimum isn't enforced?
Google Chrome ignores the value 0 for stroke-widths (uses 1). Try using
strokeColor=none
The API specification is worth reading when facing such problems.

Changing opacity on Mouseover

The ultimate goal of my project is to make my image of circle chart interactive on mouseovers. I want the pieces of the circle to change opacity to .5 (from 1) when the user hovers them. I have an image of the chart but I'm not sure how to make areas of one single image change opacity on hover. I have tried several things:
I image mapped the chart with each piece in its own map, but I wasn't sure how to change opacity of an area of one single image (css)(if its even possible)
My second approach was that i sliced the chart up into individual pieces and made their opacity .5 and saved them all separately. Then, I image mapped the single image of the chart and tried to load the individual piece on hover (css)
My final approach was saving each piece of the chart as individual images and when the image is hovered, change the opacity to .5 with css. This works perfectly except i am not sure how to position the pieces to form a perfect circle in dreamweaver.
Any direction or advise is greatly appreciated. I am willing to learn javascript or jquery to help get this done.
Thank you
EDIT Image of the chart is now attached
http://i.stack.imgur.com/KwIfY.jpg
I'm not sure if I understood the question right regarding the current answers but if you want to make the parts of the chart interactive I have 2 approaches:
To achieve the effect with pure CSS I guess you need to divide the chart in individual images as you already mentioned. The positioning is quite simple. I've used in my demo below one image an let it rotate. In your case you can cut each part of the chart individually and get the right place for them with absolute positionig.
Again as you already mentioned you can use map area to define the parts of the chart. With a plugin like this: ImageMapster you can achieve what you want. I've used this once for the following map. It's again very simple, when hovering any part of the map it's background will be replaced by another background. In your case you could save the chart with full opacity and display on hover an image of the chart with 50% opacity.
Demo
The Demo is not very clean as I didn't spent much time in position the parts perfectly but you can see how it works.
transform: rotate(45deg);
I don't know if CSS3 transition will fit to you:
http://www.w3schools.com/css/css3_transitions.asp
.chart-item { opacity: 0.5; transition:opacity 2s; }
.chart-item:hover { opacity: 1; }
Check documentation for browser support.
Maybe create a div and put each image as the background or content of one div (in order), then create a listener for the div class to change opacity upon mouseenter or mouseleave using jQuery.
Here's a simple example (pardon any mistakes):
jQuery:
$( ".somedivclass" )
.mouseenter(function() {
$(this).fadeTo(200, 0.5);
})
.mouseleave(function() {
$(this).fadeTo(200, 1);
});
Here's more info on $.mouseenter(). Here's some for $.fadeTo().
Check this demo. Hover your cursor exactly on the eyes of the owl, and you will see the opacity changing. It will not change if you hover on the rest of the image.
http://jsfiddle.net/q6d57/14/
$('.eye1').on('mouseenter mouseleave', function(e) {
$('.box2').stop(true, false).fadeToggle(1500)
});
I suggest using svg. Here is an implementation of exactly what you are trying to do, because I felt like learning d3.js today:
http://jsfiddle.net/6m26k/1/
You don't need to make the chart through code though, because you can just load the svg onto the page with html5 and use css similar to mine:
.arc.filled:hover {
opacity: .8;
cursor: pointer;
}

making an empty rectangle with Rafael JS

I am using Rafael 2.1.0 with JavaScript on Firefox 19.0.2 on Windows 7.
I would like to make a rectangle that is completely opaque around the edges but transparent in the interior. Is this possible?
I have looked at
paper.rect.attr({fill:
but it appears to only have the option of the color to fill with.
paper.rect.attr({fill: 'red', opacity:0.0});
makes the edge disappear
paper.rect.attr({fill: 'red', fill-opacity:0.0});
produces an error in the JavaScript code (in that subsequent functions do not work).
You have to set strokes instead of fill and you might also alter strokes-width.
Actually setting strokes will let you set their color and setting strokes-width will let you edit their width in viewport units.

How to create an animation sequence using RaphaelJS

so here is my question
I am using RaphaelJS to build an animation in the HTML5 canvas, the thing is I don't quite understand how do I create the animation events and how do I trigger them. The documentation isn't very helpful. Thanks
Firstly as pointed out you aren't utilising HTML5 Canvas, raphael actually uses SVG. Creating animations with raphaelJS is actually quite easy. You can just adapt the line bellow to your needs.
raphaelObject.animate({ attribute: value } , time , easing );
The raphaelObject is what you are trying to animate e.g. a shape you made earlier
attribute is what you are animating e.g. color
value is what you are changing it to e.g. "red"
time is how long the animation should take (milliseconds)
easing describes the nature of the animation, to start with use "<>" which performs a simple animation as you might expect. The easing 'bounce' causes the animation to well, bounce. Examples of different easings here: http://raphaeljs.com/easing.html
Here is an example where we are animating the object 'icon' by rotating it 90 degrees and changing its colour to red. The animation will take 300 milliseconds and will have a fancy bounce effect.
icon.stop().animate({
transform: "r90",
fill: "red"
}, 300 , 'bounce' );

Categories