I have a question which is about when I trying to add color to my draw rectangle:
ctx.fillStyle = "rgba(0,102,153,1)";
ctx.fillRect(100,100,100,100);
the color in my draw rect is light blue but when I am trying to make some modification on my opacity value to make its half-transperrant:
var opacityVar = 1;
ctx.fillStyle = "rgba(0,102,153,opacityVar/2)";
ctx.fillRect(100,100,100,100);
this is not working at all untill i trying:
var opacityVar = 1;
ctx.fillStyle = "rgba(0,102,153,"+opacityVar/2+")";
ctx.fillRect(100,100,100,100);
this just works fine, my question is why would I need to add double "marks and +between my opacityVar/2variable?
I am trying to search this around but seems does not have a detailed information about rgba()arguments expression.Would anyone please help me with this?
ctx.fillStyle is a string. You are trying to execute javascript as part of your string. In order to do so, you have to execute that javascript outside of the string and then concatenate it into your string.
this is a string -> "rgba(0,102,153,"
this is javascript -> opacityVar/2
this is a string -> ")"
the + concatenates your strings and your javascript result into one string. The " tells the engine where your string starts and where it ends.
You can also use template literals in javascript now.
"opacityVar/2"
isnt a valid value for the rgba color. You want a String, that can be converted to a float. So you can test that like this:
parseFloat("opacityVar/2") // NaN => not a number
Your second code does work:
parseFloat( ""+(opacityVar/2));// 0.5 => a valid number
Because it evaluates to a valid Number.
Related
I'd like to use Seshat—a handwritten math expression parser—for a project I'm working on, but I'm having some trouble understanding how to provide the program its proper input, an InkML or SCG Ink file.
I've taken a long look at an online example that exists here, and I see that they get a Javascript array of stroke information from an HTML Canvas field with this JS library applied, but I don't know what happens that array after it gets POSTed to their server.
I've read the SCG Ink spec, and I think it might be relatively easy to parse the array into the format, but I'm hoping there's something obvious I'm missing that would make this trivial. Any help would be greatly appreciated.
I emailed the Seshat author and he suggested I convert the input to SCG Ink, which turned out to be pretty easy if you take the JavaScript libraries used at http://cat.prhlt.upv.es/mer/. Specifically, you want jquery.sketchable.memento.min.js, jquery.sketchable.min.js, and jsketch.min.js in addition to regular old jQuery. Here's what I did in case anyone else is interested in Seshat.
Notice from the same page that in main.js they apply the Sketchable library to the HTML canvas area with this block of code:
var $canvas = $('#drawing-canvas').sketchable({
graphics: {
strokeStyle: "red",
firstPointSize: 2
}
});
Now we can take a look at their submitStrokes() function to see how to take the strokes from Sketchable and convert to SCG Ink. The line var strokes = $canvas.sketchable('strokes'); gets the strokes, and then the line strokes = transform(strokes); applies a quick transformation to extract only the data they need. Here's the transform() function for reference:
function transform(strokes) {
for (var i = 0; i < strokes.length; ++i)
for (var j = 0, stroke = strokes[i]; j < stroke.length; ++j)
strokes[i][j] = [ strokes[i][j][0], strokes[i][j][1] ];
return strokes;
};
The value returned fro transform() is a three-dimensional array of strokes and points. (Each element of the first dimension is a stroke, each element of the second dimension is a point, and the third dimension is x-, y-coordinates.) On that site they go ahead and POST that array to the server which must handle the final conversion to SCG Ink. I wrote a JavaScript function to handle it:
function strokesToScg(strokes) {
var scg = 'SCG_INK\n' + strokes.length + '\n'
strokes.forEach(function (stroke) {
scg += stroke.length + '\n'
stroke.forEach(function (p) {
scg += p[0] + ' ' + p[1] + '\n'
})
})
return scg
}
And that's it. The value returned from strokesToScg() is a string describing a series of strokes in the SCG Ink format.
I'm drawing a simple interpolated line using D3.js (output as path). However, I want part of the path to have a dashed stroke if a boolean in a data point is set to true:
Link to image
An easy solution would be to just draw it with <line> segments instead - but that way I lose the interpolation.
Then I found an example from mbostock, showing how to draw a gradient along a interpolated path. I modified it to just draw transparent path fills whenever the boolean was set to true and white fills when false - while my old path is all dashed.
That works (queue the above screenshot) - but by adding around thousand path elements to the DOM contra having only a single path.
It's not desirable with that many DOM elements, especially since I'm going to make more curves and the site needs to be mobile optimized. Am I missing a much simpler solution?
Wouldn't mind a modified version of mbostock's example doing the heavy calculations in advance, as long as the DOM output is simple.
Thanks!
I prepared this example for another SO question. Screenshot is here:
I think you have enough material there to devise a solution that fits your needs.
Take a look also at this page:
SVG Path Styling
You could use stroke-dasharray to add dashes in the stroke of the generated path in the right places. That would entail finding the proper dash lengths. This can be done by calling pathElm.getPathLength() on the path up to the point where you want it to start being dashed, and to where you want it to end.
Let's say path A that is the part that is before the dashes should start. Set the d attribute with that part and call getPathLength() on it. Let's call this length a.
Append the the part of the path that should be dashed to the d attribute, then call getPathLength() again. Let's call this length b.
Create a new path element with the remaining part of the path, then call getPathLength() on that. Let's call this length c.
Construct a stroke-dasharray property string something like this:
var a = getPathLengthA();
var b = getPathLengthB();
var c = getPathLengthC();
var dasharray = a + " ";
for(var usedlen = 0; usedlen < (b-a); ) {
dasharray += "5 10 "; // just whatever dash pattern you need
usedlen += 15; // add the dash pattern length from the line above
}
dasharray += c;
pathElement.style.strokeDasharray = dasharray;
Here's a static example of that.
I'm using d3 to animate text to show a user's progress towards completing a task. For example, if they've completed 32.51% of the task, the text will animate from 0% to 32.51% over 2 seconds or so.
To do this, I'm using d3's attrTween method on an svg text element in conjunction with d3.interpolate. The interpolation is working great, but I'm having a little trouble formatting the text. I'd like the text to always display 4 digits, so 0% = 00.00%, 4.31% = 04.31% etc. It would be nice to be able to do this without necessarily having to post process what the interpolator returns. In other words, without having to take the returned percentage and check to see if there are 4 digits and add zero padding on either side before placing it in the DOM.
As a test, I tried specifying the format that I would like by setting the a and b values to the interpolator like so d3.interpolate("00.00", "30.00"), but the final text is "30" with the trailing zeros cut off.
Any suggestions?
You can add a custom interpolator to d3.interpolators - see the docs. The example given in the docs is very close to yours - the only real change is specifying the output format, which in your case should be:
d3.format('05.2f'); // 0-padding, string width 5, 2 decimal places
Plugging this into the doc example (note that I also changed the regex appropriately and added the percentage sign):
d3.interpolators.push(function(a, b) {
var re = /^(\d\d\.\d\d)%$/, ma, mb, f = d3.format('05.2f');
if ((ma = re.exec(a)) && (mb = re.exec(b))) {
a = parseFloat(ma[1]);
b = parseFloat(mb[1]) - a;
return function(t) {
return f(a + b * t) + '%';
};
}
});
d3.interpolate("00.00%", "30.00%")(1/5); // "06.00%"
d3.interpolate("00.00%", "30.00%")(1/3); // "10.00%"
I making some graphs using HTML canvas but I want to draw line with multiple colors, at every point it should change to a new random color,
ctx.moveTo(Ximg+46,Yimg+200);
for(i=0;i<num;i++){
if(js_array[i]=="900"){ctx.strokeStyle = "Grey";}
else{ctx.lineTo(Ximg+50+i*mul,(Yimg+200)-(js_array[i]*(height/max)));}
}
am gonna change grey to random but the problem is it colors the previous path(line) with grey,i want each piece of line in a different color,is it possible in Javascript?
in OpenGl there was command we used to write to take always the last given color or not,is there a similar one in Javascript?
With the context, the strokeStyle property can take rgba, rgb, and Hexadecimal colors as well as the name of the color.
I would suggest something along the lines of:
ctx.strokeStyle = "rgba(" + (Math.Random()*255) + "," + (Math.Random()*255) + "," + (Math.Random()*255) + ", 1)";
Or perhaps a new function that returns the color, or assigns it.
If that wasn't what you were looking for, could you supply some values for the undeclared variables so that we can test it more thoroughly?
I'm taking some information from some variables I have already defined outside this function to create a html svg text box.
Here is the function which is causing me trouble:
RenderTextBox:function()
{
alert('this.x: ' + this.x);
alert('this.y: ' + this.y);
this.textBox = paper.text(this.x, this.y, this.htmlTextBox);
}
The alerts works prefectly, and prompt me with the values expected. However, the final line which is supposed to create the text box puts them nowhere to be seen. Does anybody know why?
If I replace 'this.x, this.y..' with numerical values in the final line of the function, the text box is placed correctly. It's only when I use the 'this.x' and 'this.y' that I have issues.
Sometimes numerical values are converted in strings. That's one of the very bad point about javascript : variables are not needed to be typed.
You should try to parse them as int in order to make them react as integers again : http://www.w3schools.com/jsref/jsref_parseInt.asp
Wild Guess: an you try putting this.x and this.y into variables and then passing these variables to the function call in the last line?
Something like:
var tx = this.x;
var ty = this.y;
this.textBox = paper.text(tx, ty, this.htmlTextBox);