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.
Related
I'm editing plotly.js library source code to have scalable plots, I set viewBox and preserveAspectRatio (plotly.js use d3 library) but have problem with font-size if I use no unit the property get changed to px
I've tried to test from console if font is changed to have no unit using this:
[...document.querySelectorAll('text')].forEach((text) => {
text.style.fontSize = text.style.fontSize.replace('px', '')
});
but it seems that if you don't use unit, the px is added automatically.
I've also tried to use rem unit and set 62.5% on html where original font size is divided by 10 but it don't scale when I resize the plot.
Also tried this new CSS typed OM API:
[...document.querySelectorAll('text')].forEach((text) => {
var size = +text.style.fontSize.replace('px', '');
text.attributeStyleMap.set('font-size', CSS.number(size))
});
but got error:
Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
Any solution to have font-size without unit set from javascript, or other way to proportional text?
In SVG, having no units specifier is the same as using px. So font-size: 10 and font-size: 10px mean the same. They will behave the same.
I don't know why it matters to you that the value has no units. It sounds like you think that it is why your text is not scaling. That will not be why. There must be something else going on. If you want help with that problem, then add a MCVE to your question.
in svg each style property have corresponding attribute so you can use:
d3.select('text').attr('font-size', 10);
and it will set font-size without unit. The plot still don't scale but this was the question.
I'm having trouble describing the issue, but here goes:
I'm trying to make a SVG circle progress bar and I've found a perfect example of what I want to do without any third part libraries like snap:
http://codepen.io/JMChristensen/pen/Ablch
The problem is that I'm having real issues with changing the origin of the stroke. As you'll notice if you try it out, the origin is on the right hand side. I need it to come from the top.
Now, I'm a developer, so I've tried myself, but I can't for the life of me figure out how to do it. If I change the stroke-dasharray attribute the stroke won't match the percentage set in stroke-dashoffset.
I understand it all comes down to math with the stroke-dasharray value, but I don't quite understand what to do.
The dashoffset is calculated like this:
var pct = ((100-val)/100)*(Math.PI*(r*2));
And there has to be some kind of correlation between that and the standard dasharray value 565.48. There's no mention of it anywhere.
Add this to the 2nd <circle ...></circle> in the SVG:
transform="rotate(270,100,100)"
Demo here
Regarding your last bit of inquiry:
And there has to be some kind of correlation between that and the standard dasharray value 565.48. There's no mention of it anywhere.
Well, π(r*2) or simply 2πr will give you the circumference of a circle, which in turn gives you the appropriate value for the dash-array that completes the circle.
For example:
Your SVG circle has a radius of 90.
2π(90) = 565.48, therefore your dash-array will be 565.48.
If your radius is 45...
2π(45) = 282.74, so your dash-array will be 282.74.
An alternative for 270deg rotation:
transform="matrix(0,-1,1,0,0,200)"
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/
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.
I'm using canvas of HTML5 to create a "preview" image which mainly consists of some rectangles and simple lines. Works fine so far, but there's one problem I cannot fix somehow. Presume the following situation:
context.fillStyle = "rgba(0,0,0,0.75)";
context.fillRect(100.64646,100,50.94967,20);
context.fillRect(100.64646+50.94967,100,100,20);
So I'm drawing 2 rectangles with some opacity. The x-starting coordinate plus the x-length of the first rect is equal to the x-starting coordinate of the second rect, so in theory they should collide without any margin between. Sadly, the result is different:
(see http://files.clemensfreitag.de/thin_spacing.jpg)
There's a very tiny spacing between the boxes, and the background color is visible. But:
This problem doesn't occur if the coordinates and lengths are integer values.
Is there any way to get it done by using float values? Converting them to integers before drawing might be acceptable in my application, but I'm just wondering why this should not work with floats.
Best,
Clemens
What you're seeing is the result of overlaying two opaque colors. When the first rectangle ends at 151.59613, the rectangle is automatically antialiased, filling in the rightmost column with rgba(0,0,0,0.4470975). When the second rectangle starts at the same x coordinate, it is also antialiased, filling in the leftmost column (the same as the first rectangle's rightmost) with rgba(0,0,0,0.3029025). The two values do add up to rgba(0,0,0,0.75), but that's not how they are blended. Instead, the second color (rgba(0,0,0,.3029025)) is drawn on top of the first, resulting in rgba(0,0,0,0.4470975+(1-0.4470975)*0.3029025) = rgba(0,0,0,0.61457305). So there isn't actually a gap between the two rectangles, but rather a 1px column that is a slightly lighter shade of grey.
Similarly, if you were using solid colors then the second rectangle's antialiased column would overwrite the first's, resulting in an even lighter shade of grey in the "gap".
The issue does not show up with integer values because no antialiasing is required - each rectangle ends at the edge of a pixel.
It looks like none of the globalCompositeOperation settings fix this, and turning off antialiasing would sometimes result in a 1px gap, so I think your simplest solution is to force integer values (alternatively, you could clear that column then fill it in with the desired color).
This problem is related to the way objects are drawn on a float based grid (especially vertical and horizontal lines and thus rects).
See there for an explanation and a schema : http://canop.org/blog/?p=220
Depending on the size of your objects, you need to use integer or mid-integer coordinates and sizes for your shapes, the goal being to fill complete pixels in both dimensions.
For example :
use a mid-integer for a thin line (one pixel width)
use an integer coordinate for a 2 pixels wide line
(and extend the logic for rects)