How to get a part of CSS code to JavaScript/jQuery? - javascript

I have asked a question few days ago and I got a answer, that wasn't truly answering it but it gave me an idea... The code below was in that answer and I quite understood it after a moment...Except one part. I wanted to animate some radial gradients and that guy made a jQuery plugin that wasn't doing what I wanted but it at least was some base. So the part that I don't understand is the one with command
.match(\d+/g))
He somehow (if I am right) got the RGB from the gradient and than used it to animate between the two colors. I tried to find something on google and jQ documentation but I wasn't able to find something startable with.
So my question is how can I get some stuff out of CSS like parts of gradients etc.? I want to make a gradient animating plugin for jQuery but I can't until I figure out how to change only parts of css attribs without changing the whole one as the guy did.
-- His example
jQuery.fx.step.gradient = function(fx) {
if (fx.state == 0) { //On the start iteration, convert the colors to arrays for calculation.
fx.start = fx.elem.style.background.match(/\d+/g); //Parse original state for numbers. Tougher because radial gradients have more of them
fx.start[0] = parseInt(fx.start[0]);
fx.start[1] = parseInt(fx.start[1]);
fx.start[2] = parseInt(fx.start[2]);
fx.end = fx.end.match(/\d+/g);
fx.end[0] = parseInt(fx.end[0]);
fx.end[1] = parseInt(fx.end[1]);
fx.end[2] = parseInt(fx.end[2]);
}
fx.elem.style.background = "-webkit-linear-gradient(rgb(" + [
Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0),
Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0),
Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0)
].join(",") + ")," + "rgb(0,0,0))";
}
$(this).animate({"gradient": "rgb(0, 255, 0)"});
--David

Well be careful, in his example the final code is actually
$(this).animate({"gradient": "rgb(" + c.join(",") + ")"});
You have what looks like a hard coded string in your question.
$.match() is a regex function that queries the object (fx.end or fx.elem.style.background) for the specified search string (/\d+/g). As he commented, he is parsing for numbers:
fx.start = fx.elem.style.background.match(/\d+/g); //Parse original state for numbers. Tougher because radial gradients have more of them
A regex pattern matching guide (one of gazillions) can be found here.
As far as assigning CSS values, in the end they are just strings. So you can retrieve any CSS value you want and parse it and plug it back in.
$('#myobject').css('<css property name>') // get value
$('#myobject').css('<css property name>', '<value'>) // set value
The logic you will have to work out yourself but it looks like the gentleman above has already pointed you in the right direction.
Or rather than just set the CSS property for gradient, in your case it seems you'd be using the animate plugin in jQuery UI along with his "gradient" method which does the CSS insertion for you.
$(this).animate({"gradient" : "<your parsed/calculated gradient value>"});

If you have a look at this JSFiddle, you'll see you can grab the gradient CSS for an element, however, it's the entire gradient definition instead of each value.
In the example above, FF6 spews out
-moz-radial-gradient(50% 50% 45deg, circle closest-side, rgb(255, 165, 0) 0%, rgb(255, 0, 0) 100%)
You could parse (sort of) with regex, but everyone writes their CSS differently so this would be pretty difficult.
There's a solution for setting the gradient, but not getting it. There should be good information in this answer.

Related

How to set color of the entity from the script in Amazon Sumerian?

I am learning Amazon Sumerian for Web VR development. I am trying to change the color property from the script of that entity in the update() method. The code looks like this:
function update(args, ctx) {
ctx.entity.transformComponent.setTranslation(0.6, 166, distance);
distance += 10;
if (distance > 1500) {
distance = -10;
ctx.entityData.color = "blue";
}
}
I have tried setting the color property by ctx.entity.color and ctx.entity.setAttribute('color', 'blue') too but that also doesn't work. I also couldn't find any documentation on their official site for setting color. I think there is a simple catch that I am missing.
What is the correct way to update color of an entity from a script?
The following approach is undocumented. That could just be a symptom of incomplete Sumerian documentation or it could indicate that the approach is not officially supported and therefore may be subject to change in the future. But for now, you can use the following approach to accomplish what you want.
function update(args, ctx) {
ctx.entity.transformComponent.setTranslation(0.6, 166, distance);
distance += 10;
if (distance > 1500) {
distance = -10;
// Color is a 4 component array in the order: red, green, blue, alpha
const blueColor = [0, 0, 1, 1];
ctx.entity.setDiffuse(blueColor);
}
}
Answer below is for the Preview/new version of the Sumerian API. Answer for the Legacy version of the Sumerian API can be found above in Kris Schultz' answer.
Just wanted to contribute an answer to this question.
In this case, I am trying to change the shirt color of a host entity. For example, I would like to change the shirt color of the Cristine Polo entity to red dynamically using a script.
The answer can be obtained from the Amazon Sumerian scripting API's official documentation, which I recommend to everyone starting out:
https://content.sumerian.amazonaws.com/engine/latest/doc/#content://sumerian-common/Guide/Quick%20Start
import * as s from 'module://sumerian-common/api';
export default function RotatorAction(ctx) {
ctx.start( EnabledAction );
}
function EnabledAction(ctx) {
ctx.start(
[ s.material.SetMaterialColorAction, { color: s.color.Red } ]
);
}
I ended up using Legacy API.
Furthermore, with the Legacy API, I noticed that it's possible to just use three RGB values [r, g, b] without the alpha value. Also, that the RGB values that setDiffuse() takes are between 0-1, which needs conversion from the 0-255 scale usually found.

Sorting Colours Using Delta-E

I would like to sort a set of colours so that I can display them in the most visually pleasing way. I understand that this is a wide topic and what is deemed as visually pleasing is open to debate, so I have chosen to use the Delta-E algorithm. I am using a JS library called Delta-E.
I can use this algorithm to compare two colours at a time and find the perceived difference between them and it is trivial to run through all colour combinations and store this difference for each combination.
However I am unsure how to proceed beyond this point. Once I have deltas for each pair of colours how do I use these values to order the colours?
What kind of sort do I need to use?
I'm actually dealing with the same problem right now. One solution I am tinkering with is to set an anchor color. What I mean by that is that you'd call your deltaE function with the same anchor color and then the color you wish to compare, which will return the difference values from the same color. You can then use that difference value in your Array.sort() call:
const colors = ['#333333', '#f1f1f1', '#00aacc', '#ff6666', '#000000'];
const anchorColor = '#fff'; // White or black might be a decent choice of anchor color
colors.sort((colorA, colorB) => {
// For each color, determine the color difference FROM the anchor color (not each other)
const colorADelta = deltaE(anchorColor, colorA);
const colorBDelta = deltaE(anchorColor, colorB);
if (colorADelta > colorBDelta) {
return 1;
}
if (colorADelta < colorBDelta) {
return -1;
}
return 0;
});
However, in my personal testing, I've found that the deltaE difference values weren't exactly right for this anchor technique, and I instead used the Euclidean distance as the value, from this library (which also has a Delta-E function).

How to detect an empty space on a web page

Is there a way to detect an empty area, without text or images within a web page, using JavaScript?
More precisely, how to determine whether point [x,y] is within a blank area, like in the following example (marked in red)
EDIT: I want to make my question clearer, I'm building an extension which supposed to mark search results as trustworthy or as spam, I want to put my marking at the end of the text of a result item URL.
I also want to do it in a generic way, so it wouldn't work only in Google web page. an example is shown below:
You can test for genuine white space like this :
function isWhiteSpace(coords) {
var element = document.elementFromPoint(coords.x, coords.y);
var whitespace = $(document).add("body, html");
return (whitespace.get().indexOf(element) > -1) ? true : false;
}
where coords is an object with .x and .y properties.
DEMO
document.elementFromPoint(), documented here, is "an experimental technology", so I wouldn't trust my life to it. Test thoroughly on all target platforms.
Edit
For the full detection of all the white you seek, isWhiteSpace() would be the first of two stages. The second stage would be isVisualWhiteSpace() implemented with #remdevtec's approach for example.
As my isWhiteSpace(coords) is inexpensive, you would perform it first and only if it returned false go for the expensive test. You could use the protective property of ||
var isWhite = isWhiteSpace(coords) || isVisualWhiteSpace(coords);
But your real problem will be writing isVisualWhiteSpace(). I can't help with that.
One approach would be to work with a screenshot of the window.
You can use libraries like html2canvas to load a screenshot to a HTML canvas element.
Next, on window.onclick, use the automatic event parameter to get an RGBA array of the clicked coordinate:
var pixelData = canvas.getContext('2d').getImageData(
event.offsetX,
event.offsetY, 1, 1)
.data;
Now if all (or at least the first three) pixelData's items equal 255, it means that this point is white.
if (pixelData[0] == 255 && pixelData[1] == 255 && pixelData[2] == 255) {
// the clicked point is white,
// and if the background-color is white,
// it can be considered an empty point
}
Of course, the down side is that you have to know the background color of the site you're testing, or the background color of the element you click in.
You can build a matrix with width and length of the page.
Set all matrix cells to zero.
Get all elements of the DOM.
Get x, y, width, and height of each element, this link may help
Retrieve the position (X,Y) of an HTML element
Draw the elements in the matrix
for(k=0;k < dom_elements.length;k++) {
for(i=dom_elements[k].y;i < dom_elements[k].length;i++) {
for(j=dom_elements[k].x;j < dom_elements[k].width;j++) {
matrix[i][j] = 1 ;
}
}
}
And finally check if matrix[i][j] is set to zero or 1

Determining the background-color or color in numeric format across browsers

I have been through a number of responses to similar questions. I just want to clarify if I am understanding correctly. My purpose is to do some colour calculations.
I have been working in fire fox where:
var bkg_Colour = $("#test_Box_1").css("background-color"); // is red
var fgd_Colour = $("#test_Box_2").css("background-color"); // is blue
returns rgb(255, 0, 0) and rgb(0, 0, 255) respectively.
Which is fine and I have calculated the distance between the foreground and background appropriately by splitting out the tuples and comparing them.
BUT:
In internet explorer this same code returns "red" and "blue" and of course the calculation fails.
Form the previous answers it appears that there isn't a consistent way of getting the colour back (whether background-color or color) in a numeric format - if using $(...).css. And it appears that all sorts of hoops have to jumped through to cover all the bases.
So is there a way of doing this without using $(...).css?
Edit
Just following this up when I apply the example code given here in my script and I run it in FF I get rgb(255,0,0) when I run it in IE i see the word "red" in result. BUT
when I run the above link in IE result is rgb(xxx,xx,xx) I am therefore very confused. Is there a server setting or something that is causing IE to behave this way on the page I am serving??
Edit
As far as I can tell at the moment in IE it reports back the colour as specified in the css, namely "green" "blue" "red" or #808080 etc. whereas in ff it always reports it back as a rgb value.
I think you are going to have to resort to a color names dictionary. This is similar to this question: Javascript function to convert color names to hex codes in concept at least.

how to use attr's stroke-dasharray,stroke-linecap,stroke-linejoin in raphaeljs

Can anyone give me an example of these attributes in action: stroke-dasharray, stroke-linecap, stroke-linejoin i tried using them, but i don't quite understand the sentext structure for their values.
Phrogz's answer is great for plain SVG, but this question is also tagged Raphael, where things are similar, but slightly different. There aren't many good examples of stroke settings in Raphael, so here's a complete live demonstration.
It has examples documenting how to use stroke-dasharray (dotted lines and dashed lines), stroke-linejoin (stroke corner style) and stroke-linecap (path stroke cap style) in Raphael.js.
Link to jsfiddle live demo
Use .attr({'stroke-dasharray': option}) for dotted / dashed lines in Raphael, with one of these options (no numbers, unlike pure SVG):
["", "-", ".", "-.", "-..", ". ", "- ", "--", "- .", "--.", "--.."]
Use .attr({'stroke-linejoin': option}) for rounded, bevelled or sharp (mitre) corners in Raphael (same as SVG except inherit):
["bevel", "round", "miter"]
You can also set .attr({'stroke-miterlimit': decimal}) which controls the cut-off point based on the stroke width and the angle beyond which miter (sharp) joins are blunted. Same as SVG stroke-miterlimit so SVG docs apply. Cross-browser variation in this can be seen in the jsfiddle above (e.g. between Chrome & Firefox on Windows)
Use .attr({'stroke-linecap': option}) to control the caps on the end of a stroked raphael path:
["butt", "square", "round"]
stroke-linecap
Legal Values: butt | round | square | inherit
Example
stroke-linejoin
Legal Values: miter | round | bevel | inherit
Example
stroke-dasharray
Legal Values: comma- or space-delimited list of lengths or percentages,
e.g. "100 20 0 20"
Example (using above values)
Please note that this answer covers only stroke-dasharray and is a supplement to answer by Phrogz.Raphael does not provide a lot of freedom to set stroke-dasharray as stated by user568458 and as I needed it to work like other svg creators I did a little tweak in raphael.js to accommodate all possible stroke-dasharray values.
addDashes = function (o, value, params) {
var nvalue = dasharray[Str(value).toLowerCase()];
if (nvalue!==undefined) {
var width = o.attrs["stroke-width"] || "1",
butt = {round: width, square: width, butt: 0}[o.attrs["stroke-linecap"] || params["stroke-linecap"]] || 0,
dashes = [],
i = nvalue.length;
while (i--) {
dashes[i] = nvalue[i] * width + ((i % 2) ? 1 : -1) * butt;
}
$(o.node, {"stroke-dasharray": dashes.join(",")});
}else{
$(o.node, {"stroke-dasharray": Str(value).toLowerCase()});
}
}
Replacing the previous code in the file just below where dasharray object is defined.
If you want to apply a dashed line in a standard SVG way on a Raphael line object, this worked well for me; whereas I didn't have any luck using period and hyphens as done in the Raphael way.
myLine.attr({stroke:'green'}).node.setAttribute('stroke-dasharray', '10,10');
The parameters (10,10 in this example) are the length,gap and you can iterate that as much as you want. Like 5, 5, 1, 5 would be shorter dashes with dots.
Reference: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray

Categories

Resources