Random select value in array and next apply to jQuery function - javascript

I have this function that returns a random color, but I want to apply it to jQuery .animate() function.
How can I do that?
var colors = ["rgb(120,25,25)", "rgb(50,100,130)", "rgb(30,95,45)", "rgb(55,30,90)"];
function randomBackground() {
return colors[Math.floor(Math.random() * messages.length)];
}
$("#menu").animate({background: randomBackground()});

You could do:
var colors = ["rgb(120,25,25)", "rgb(50,100,130)", "rgb(30,95,45)", "rgb(55,30,90)"];
function randomBackground() {
return colors[Math.floor(Math.random() * colors.length)];
//use colors.length, not messages.length
}
var bgcolor = randomBackground();
$("#menu").animate({background: bgcolor });

sorry for you but if you read the jQuery documentation :
All animated properties should be animated to a single numeric value, except as noted below; most properties that are non-numeric cannot be animated using basic jQuery functionality. (For example, width, height, or left can be animated but background-color cannot be.) Property values are treated as a number of pixels unless otherwise specified. The units em and % can be specified where applicable.
that meens you cannot do the background color change using animate()

Related

Change font size using Integer not string

I am currently working on SVG text. I am trying to change fontSize dynamically. However it isn't working
It let me change the font size by doing the following
this.text.style.fontSize = "xx-small";
or
x-small, small, medium, large, x-large, xx-large
However, what I actuall want to do is
this.text.style.fontSize = 30;
or
any other integer (20, 12, etc) but it won't let me do that.
I want to be able to pass the fontSize using a value not string
The actual function is
function setSize (textSize) {
this.text.style.fontSize = textSize;
//this.text.style.fontSize = "xx-small"; //this works
//this.text.style.fontSize = 10; // this doesn't work
}
Try mention it as "30px" or "30cm" or in percentage as "30%"

CSS Random background image position within range and increment; random number for transformation timing

I am working off of a 480x480px sprite, with 225 individual 32x32px images laid out 15x15 grid so it's a perfectly square jpeg. I am trying to:
Create a way to generate random numbers in the background-position fields that will inject a random number within the range and increment I specify (range would be 0-480, inc is 32). This is in order to call random sprite background images for the div.
Generate a similar random number (just range) to be used in the timing of a div transform: rotateY(180deg) style. This is in order to get the div to "flip" and return. I have a front/back transition that already works in the code, but of course the timing is uniform.
Find a way to clone or duplicate that div, and its contents to fill a containing one.
I've been working to try and make something that would work like:
<div class="face back" style="
background-position-x: [myNumber]px;
background-position-y: [myNumber]px;
"></div>
Using a script such as:
var myNumber = Math.floor((Math.random()*14)+1);
myNumber = myNumber *32;
I know I haven't been going about it the right way at all.
The desired result is a div (background or footer maybe) with dozens (maybe hundreds) of 32x32px seemingly random images. Each one transitioning at different intervals to different images. Obviously I'm looking for any elegant way.
I am not that sure about what you are about but I would suggest the following procedure:
get an reference to the <div> that should be filled up with the tiled grid of images.
get its width and height and modulo divide (%) these values by the tile width plus one:
var rect = div.getBoundingClientRect();
var numTiles = ( rect.width % tileWidth + 1 ) * ( rect.height % tileWidth + 1 );
create numTiles is <div> elements and set their background position randomly:
var bgTop = Math.floor( Math.random() * numTilesInMap );
var bgLeft = Math.floor( Math.random() * numTilesInMap );
I would simply float all the div elements and append them to the container, thereby the container should have overflow : hidden because the grid is always a big bigger.
If you want to have unique random numbers and only as much tiles as images available in the map, than you can do something like this:
var randoms = {};
for( var i = 0; i < numImages.length; i++ ){
randoms[i] = i;
};
var rand, index;
while( Object.keys( randoms ).length > 0 ){
index = Math.round( Math.random() * ( Object.keys( randoms ).length - 1 ) );
rand = randoms[ index ];
//do something with the random number here
delete randoms[ index ];
}
I have not tested this, it should just deal as suggestion how to generate random unique numbers. It can also be done with an array what perhaps is faster.
Greetings...
Edit
What I forgot to mention here is that next to the »div« solution you can also create a <canvas> and use the drawImage() method with random values, where you just draw regions of the tile map on the canvas as long as it is full. That reduces the size of the DOM and you can create the canvas it the exact size of the container. If you do not catch any events that lead to the area of the tilemap or another image depended reference this might be the fastest solution.
procces= function() {
TimeSpeed=100;
startRange=1;
stopRange=100;
incrementRenge=5;
setTimeout(function run(){
if(startRange >=stopRange) {
console.info("stop");
}
else {
console.info("rinning");
startRange+=Math.floor(Math.random()*incrementRenge);
$(".face back").css({"background-position":startRange+"px ,"+startRange+"px"});
setTimeout(function() {
run()
},TimeSpeed)
}
},TimeSpeed)
}

YUI2 ColorPicker default value issue

I'm using the YUI2 colour picker on a project to provide a theme/colour scheme changing functionality. I'm setting the default rgb value of each colour picker to the current rgb value of an element of the colour scheme.
The rgb value that the picker holds is fine, however the Hue Slider and Picker Slider are not updating to reflect this. Whenever the colour picker appears the hue and picker are set to 0 and ffffff respectively.
I've searched through the documentation and tried a few likely methods that might update the hue/picker slider appropriately, with no luck.
Any advice would be greatly appreciated
After some more searching and playing around I managed to come up with a solution. There are two steps to the process;
Step 1
You need to compute the HSV (Hue, Saturation, Value) from the rgb value. This is done using the function rgbTohsv() below, which I got here. Its been modified from the original to account for the way the YUI HueSlider and PickerSlider expect input.
function rgbTohsv (rgb) {
var computedH = computedS = computedV = 0;
//remove spaces from input RGB values, convert to int
var r = parseInt( (''+rgb[0]).replace(/\s/g,''),10 );
var g = parseInt( (''+rgb[1]).replace(/\s/g,''),10 );
var b = parseInt( (''+rgb[2]).replace(/\s/g,''),10 );
r=r/255; g=g/255; b=b/255;
var minRGB = Math.min(r,Math.min(g,b));
var maxRGB = Math.max(r,Math.max(g,b));
// Black-gray-white
if (minRGB==maxRGB) {
computedV = minRGB;
return [0,0,Math.round(computedV*100)];
}
// Colors other than black-gray-white:
var d = (r==minRGB) ? g-b : ((b==minRGB) ? r-g : b-r);
var h = (r==minRGB) ? 3 : ((b==minRGB) ? 1 : 5);
computedH = 60*(h - d/(maxRGB - minRGB));
computedS = (maxRGB - minRGB)/maxRGB;
computedV = maxRGB;
return [(360-computedH)/2,Math.round(computedS*100),Math.round(computedV*100)];
}
Modifications:: The hue slider expects a value between 180-0, rather than the usual 0-360. As well as the shorter range it is also inverted so it goes from 180->0. The S and V values must be an integer between 0-100, whereas the original function returned 0-1.0 values. Both of these issues have been accounted for in the above function.
Step 2
Next you need to set the hsv values of the colour picker., so where colourPicker is your initialised colour picker variable;
hsv = rgbTohsv(rgb);
colourPicker.hueSlider.setValue(hsv[0],0);
colourPicker.pickerSlider.setRegionValue(hsv[1],hsv[2]);
By default updating the hue slider and picker slider do an animation when updated, you can suppress this by adding a false variable at the end of the method call.
colourPicker.hueSlider.setValue(hsv[0],0,true);
colourPicker.pickerSlider.setRegionValue(hsv[1],hsv[2], true);

How to compare colors in JavaScript?

Why doesn't this work? Even though the colour is equal to #ECECF4 it still alerts "No".
It is selecting the corrent element as I have tested it. Is there a better way to write this?
<script type="text/javascript">
function weekclick() {
if (document.getElementById('w1').style.backgroundColor == "#ECECF4") {
alert("Yes");
} else {
alert("No");
}
}
</script>
Comparing colors as part of the business logic should be avoided at all cost.
Instead, keep the logic in JavaScript and act according to a state kept somewhere. Then, if you want to send a visual feedback to the user through a change of color, add a class to the element. That way, JavaScript only knows about class names and the styling is always isolated in the CSS as it should.
$(".list").on("click", "li", function(){
$(this).toggleClass('active');
});
.list {
width: 100%;
padding: 0;
}
.list li {
padding: 5px 10px;
list-style: none;
cursor: pointer;
}
.list li:hover {
background-color: rgba(0, 0, 0, 0.05);
}
.list li.active {
background-color: #eeeecc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list">
<li>test 1</li>
<li>test 2</li>
<li>test 3</li>
</ul>
That being said, OP's code works for me with Chrome 17.0.963.56 and Firefox 8.0. When you don't know what to compare, just use console.log() to see what it looks like.
Note that #ECECF4 is the same color as rgb(236, 236, 244) but in a different representation.
IE7 and IE8 output the HEX value, IE9 and up and other browsers output the RGB format. So comparing color with cross-browser compatibility is a tricky task and the best way to do it isn't beautiful.
I made a simple function which works for most cases with most browser, even with color set through CSS.
function weekclick() {
var elemColor = getStyle(this, "backgroundColor"),
color = "rgb(238, 238, 204)";
console.log("Broswer returned elem color: ", elemColor);
// IE7 and IE8 output the hex value
if (elemColor.slice(0, 1) === '#') elemColor = hexToRgb(elemColor);
console.log(elemColor, " === ", color, "?", elemColor === color);
}
// Source: https://stackoverflow.com/a/41354868/1218980
// Inspired by: https://stackoverflow.com/a/22744598/1218980
function getStyle(el, prop) {
return (typeof getComputedStyle !== 'undefined' ?
getComputedStyle(el, null) :
el.currentStyle
)[prop];
}
// Slightly modified version to quickly return a string
// https://stackoverflow.com/a/5624139/1218980
function hexToRgb(hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? "rgb(" + [
parseInt(result[1], 16),
parseInt(result[2], 16),
parseInt(result[3], 16)
].join(', ') + ")" : null;
}
#css-div {
background-color: #eeeecc;
}
<div style="Background-color:#eeeecc" onclick="javascript:weekclick.call(this);">#eeeecc</div>
<div style="Background-color:#EEC" onclick="javascript:weekclick.call(this);">#EEC</div>
<div style="background-color:hsla(60, 50%, 86.7%, 1)" onclick="javascript:weekclick.call(this);">hsla(60, 50%, 86.7%, 1)</div>
<div style="background-color:rgb(238, 238, 204)" onclick="javascript:weekclick.call(this);">rgb(238, 238, 204)</div>
<div id="css-div" onclick="javascript:weekclick.call(this);">css</div>
I call the weekclick function with javascript:weekclick.call(this) passing the element itself as the context of the callback, making it easy to access the element with this.
It could be extended to take alpha into account when using HSLA or RGBA.
When I originally wrote this answer back in 2012, I used navigator.appName === "Microsoft Internet Explorer" to know if it was IE7 and the color to compare was changed to its HEX equivalent. Don't do that as it won't work today.
Use a canvas to compare colors.
Fill one pixel using the color string
and the other pixel using the Element getComputedStyle color property.
Compare the two pixels data using Array.from and JSON.stingify
/**
* Test if Element color property holds a specific color.
* https://stackoverflow.com/a/60689673/383904
*
* #param {Object} el The DOM Node Element
* #param {String} prop A CSS property color property
* #param {String} color A valid CSS color value
* #return {Boolean} True if element color matches
*/
function isElPropColor(el, prop, color) {
const ctx = document.createElement('canvas').getContext('2d');
ctx.fillStyle = color;
ctx.fillRect( 0, 0, 1, 1 );
ctx.fillStyle = getComputedStyle(el, null).getPropertyValue(prop);
ctx.fillRect( 1, 0, 1, 1 );
const a = JSON.stringify(Array.from(ctx.getImageData(0, 0, 1, 1).data));
const b = JSON.stringify(Array.from(ctx.getImageData(1, 0, 1, 1).data));
ctx.canvas = null;
return a === b;
}
// TEST (PS: see CSS!):
const el = document.body;
const prop = 'background-color';
console.log(isElPropColor(el, prop, 'red')); // obviously true :)
console.log(isElPropColor(el, prop, '#f00')); // true
console.log(isElPropColor(el, prop, 'rgb(255, 0, 0)')); // true
console.log(isElPropColor(el, prop, 'hsl(0, 100%, 50%)')); // true
console.log(isElPropColor(el, prop, 'hsla(0, 100%, 50%, 1)')); // true
body {background: red; }
The buts and whys
Most modern browsers calculate and convert the color value to RGB/A.
But we should not rely on doing strict equality comparison like:
// (Say the element is really red)
const isRed = myElement.style.backgroundColor === "rgb(255,0,0)"; // false
False because it's actually "rgb(255, 0, 0)", with spaces.
No guarantee some browser tomorrow will not convert to "rgba(255, 0, 0, 1)", or HSLA perhaps?
Edge and IE will return the value used in CSS or overwritten by our JS
We cannot reliably compare two DIV styles using getComputedStyle
and we cannot even create an "in-memory" DIV element since we need to - append it to the DOM, than use getComputedStyle(tempDIVElement, null).getPropertyValue('background-color') and than remove it from the DOM. It's a waste of DOM recalculations, paints, and it's not guaranteed some wondering stylesheet !important did not messed up our temporary DIV styles div {background: fuchsia !important; } giving false-positives "Is red? True! blue is blue because of !important".
Why canvas?
A canvas can stay in memory. No need to append to DOM, set colors, remove element.
The returned pixel data is always guaranteed to be [R, G, B, A] (RGBA being 0-255 values)
A wondering CSS rule will not mess up the assigned color
Useful links:
Canvas_API MDN
CanvasRenderingContext2D/getImageData MDN
Array/from MDN
JSON/stringify MDN
Window/getComputedStyle MDN
I'm actually just learning javascript, but instead of creating a function that converted rgb() to hex you can create a div of the same background-color you are looking for and compared it to that div's background color. If you happen to already have a div of that hex value you can just do this:
//javascript
if (document.getElementId('desiredElementToCompare').style.backgroundColor === document.getElementId('elementWithTheDesiredHexString').style.backgroundColor)
//jQuery
if ($('#desiredElementToCompare').css('background-color') === $('#elementWithTheDesiredHexString').css('background-color')
You can create a div with a function and then do the comparison like this:
var compareHex = (hex) => {
var hexString = document.createElement('div')
hexString.style.backgroundColor = `${hex}`
return hexString.style.backgroundColor
}
//then compare
//javascript
if (document.getElementId('desiredElementToCompare').style.backgroundColor === compareHex("#ECECF4"))
//jQuery
if($('#desiredElementToCompare').css('background-color') === compareHex("#ECECF4")
This way suggests using JQuery's background-color which standardises the response to rgb(r, g, b).
How to get the background color of an element using javascript?
Maybe this answer could help. Convert the color code to hex and then compare each RGB color/channel (i don't know the word)
https://stackoverflow.com/a/25666938/1757214
I think is better and easy compare two numbers than two strings
I would advice using the '===' stric equal (i think this is the name).
Like:
if (document.getElementById('test').style.backgroundColor === "rgb(236, 236, 244)") {

Change canvas gradient object's properties

var i = 0;
var x = 960;
var y = 540;
var interval = window.setInterval(render, 100);
function render()
{
gradient = cxt.createRadialGradient(x, y, i, x, y, i+10);
gradient.addColorStop(0, "rgba(0,0,0,0)");//white inside
gradient.addColorStop(.4, "rgba(255,255,255,1)");//white inside
gradient.addColorStop(.6, "rgba(255,255,255,1)");//white inside
gradient.addColorStop(1, "rgba(0,0,0,0)");//fade to transparent black outside;
cxt.fillStyle= "#000000";
cxt.fillRect(0,0,WIDTH,HEIGHT);
cxt.fillStyle = gradient;
cxt.fillRect(0,0,WIDTH,HEIGHT);
cxt.fill();
cxt.drawImage(logo,0,0);
i+=5;
}
I'm trying to animate a feathered loop expanding.
This code is pretty inefficient, because I'm using the constructor to change as single property each loop. How can I change a single property that is passed as a parameter to the constructor?
From the Canvas specs...
interface CanvasGradient {
// opaque object
void addColorStop(in float offset, in DOMString color);
};
...and earlier it says about fillStyle and strokeStyle...
On getting, if the value is a color,
then the serialization of the color
must be returned. Otherwise, if it is
not a color but a CanvasGradient or
CanvasPattern, then the respective
object must be returned. (Such objects
are opaque and therefore only useful
for assigning to other attributes or
for comparison to other gradients or
patterns.)
Lastly, introspecting a gradient just reveals the addColorStop function.
So I think the constructor is the only place those values can be set; but are you sure the constructor is really slowing it down? If your animation is slow maybe it's something else. Have you timed it?

Categories

Resources