jQuery to shift object - javascript

I was trying to create an animation where it loads when the page loads.
Initially it creates object with white background.
Every 1 second, it shifts the object to right by 10px, at mean while change the object color by adding 10 to its RGB value.
I've create this jsFiddle, but it doesn't work (border is to distinguish the object)
Any inputs will be largely appreciated.
function RGB2HTML(red, green, blue)
{
var decColor =0x1000000* blue + 0x100 * green + 0x10000 *red ;
return '#'+decColor.toString(16).substr(1);
}
window.onload = function(){
var currentColor='white';
var red = 0;
var green = 0;
var blue =0;
setInterval(function(){
$('.object').style.top += 10px;
$('.object').style.left += 10px;
$('.object').style.background-color = RGB2HTML(red+10; green+10; blue+10)
}, 1000);
};
Here is the jsfiddle:
http://jsfiddle.net/jykG8/70/

Here you go: http://jsfiddle.net/jykG8/77/
We can set variables for the initial top and left values, so that we may pass them into jQuery's .css() and increment from there. The same principal applies with the color transformation.
window.onload = function(){
var currentColor='white';
var red = 0;
var green = 0;
var blue = 0;
var top = 0;
var left = 0;
setInterval(function(){
$('.object').css('top', top += 10);
$('.object').css('left', left += 10);
$('.object').css('background-color', 'rgb('+(red+=10)+','+(green+=10)+','+(blue+=10)+')');
}, 1000);
};
Further, since we're dealing with one selector, we can combine the CSS properties into one call:
$('.object').css({
'top' : top += 10,
'left' : left += 10,
'background-color' : 'rgb('+(red+=10)+','+(green+=10)+','+(blue+=10)+')'
});
Example: http://jsfiddle.net/jykG8/80/

Try this:
window.onload = function(){
var red = 0;
var green = 0;
var blue =0;
setInterval(function(){
var t = parseInt($('.object').css('top')) + 10;
var l = parseInt($('.object').css('left')) + 10;
red += 10;
green += 10;
blue += 10;
$('.object').css({top: t}).css({left: l}).css({'background-color': '#' + red.toString(16) + green.toString(16) + blue.toString(16)});
}, 1000);
};
http://jsfiddle.net/jykG8/79/

http://jsfiddle.net/vdU9X/
function RGB2HTML(red, green, blue)
{
var decColor = blue + 256 * green + 65536 * red;
return '#' + decColor.toString(16);
}
window.onload = function(){
var currentColor='white';
var red = 255;
var green = 255;
var blue =255;
var left = 0;
var top = 0;
setInterval(function(){
top += 10;
left += 10;
red -= 10;
green -= 10;
blue -= 10;
$('.object').css ({
'top' : top,
'left' : left,
'background-color': RGB2HTML(red, green, blue)
});
}, 1000);
};
I'm not 100% sure about the RGB2HTML function. I may have the blue & red reversed. But, if you want to go from white to black you need to start at 256 and go down. There should be some logic added to account for negative being invalid.

Related

HTML javascript function to create element, but cannot find it with other function

I am trying to program a scrambling puzzle in Javscript/HTML, in which I draw blue and red squares on an HTML file page. When the blue squares are clicked on, they move depending on their location with respect to the red square. I wrote a method that draws the squares and names them "blue1, blue2, blue3, red" etc. However, when I try to find the square named "red" with getElementById("red") and call getBoundingClientRect() on it, I get an error for
trying to call getBoundingClientRect() on a null object.
I'm not sure why it would be null since I can see the square named "red" when I run my code.
Here is the code that draws the squares:
var board = [["blue3", "blue2"],["blue1", "red"]];
var dim = 2;
var width = 50;
var height = 50;
// add the squares
function addSquares()
{
for(var i = 0; i < dim; i++)
{
for(var j = 0; j < dim; j++)
{
// create square
var label = j + i * dim;
var name = board[i][j];
var div = document.createElement(name);
div.style.width = width + "px";
div.style.height = height + "px";
div.style.left = width * j + "px";
div.style.top = height * i + "px";
div.style.position = "absolute";
// determine color of square
if(i != dim - 1 || j != dim - 1)
{
div.style.backgroundColor = "blue";
}
else
{
div.style.backgroundColor = "red";
}
document.getElementById("container").appendChild(div);
// do something when clicked
div.addEventListener("click", function(){getMove(this);});
}
}
}
And here is the code for getMove(), where there is an error once I call var red = redelem.getBoundingClientRect();
function getMove(elem) {
var move = elem.getBoundingClientRect();
var redelem = document.getElementById('red');
var red = redelem.getBoundingClientRect();
mwcenter = 0.5 * (move.right + move.left);
mhcenter = 0.5 * (move.bottom + move.top);
rwcenter = 0.5 * (red.right + red.left);
rhcenter = 0.5 * (red.bottom + red.top);
if (mwcenter - rwcenter == 50 && mhcenter == rhcenter)
{
leftPress(elem);
rightPress(redelem);
}
else if (mwcenter - rwcenter == -50 && mhcenter == rhcenter)
{
rightPress(elem);
leftPress(redelem);
}
else if (mhcenter - rhcenter == 50 && mwcenter == rwcenter)
{
upPress(elem);
downPress(redelem);
}
else if (mhcenter - rhcenter == -50 && mwcenter == rwcenter)
{
downPress(elem);
upPress(redelem);
}
}
"name" is not the same as "id". getElementById does not find the div by looking for it's name, it gets it by id, so it will not find the element whose name is "red", without an id. You have two options:
Either:
Use getElementByName() instead of getElementById(), using the following line instead of the one that causes the error:
var redelem = document.getElementByName('red');
Or:
Give each of the divs an id:
You created the element and gave it a name, so you will also need to give it an id like this:
div.id = "red";
Actually, in your code it should be
div.id = name;
but I wanted my first example to be less confusing by showing you what you literally wanted for the red div. So, you can give your divs an id each and then you will be able to use getElementById successfuly.

js background colour transition

I've got the following piece of code and I'd like the 'rect' element (which is a canvas element) transition the colour from black to white. It doesn't. Please advise:
var background = document.getElementById("rect");
setInterval(function() {
for (i=0;i<255;i++) {
background.style.backgroundColor = 'rgb(' + [i, i, i].join(',') + ')';
}
}, 900);
By changing the colors in a loop, you're effectively doing it all at once. Instead, do one change per interval callback:
var background = document.getElementById("rect");
var i = 0;
var timer = setInterval(function() {
background.style.backgroundColor = 'rgb(' + [i, i, i].join(',') + ')';
if (++i > 255) {
clearInterval(timer);
}
}, 900);
Note that at 900ms per change and 255 changes, that will take a long time to complete, so you may need to adjust the interval.
Here's an example using an interval of 20ms:
var background = document.getElementById("rect");
var i = 0;
var timer = setInterval(function() {
background.style.backgroundColor = 'rgb(' + [i, i, i].join(',') + ')';
if (++i > 255) {
clearInterval(timer);
}
}, 20);
#rect {
height: 4em;
}
<div id="rect"></div>

Draw clickable grid of 1 million squares

I need to find a way to draw a 1000x1000 squares grid, each square is clickable and they must be independently color changeable. Like mines game. I can use HTML (pure or using Canvas or SVG), CSS and JavaScript for this.
I know how to create one grid with these characteristics with JavaScript and CSS, it does well with 10x10 squares, with 100x100 the squares will turn into tall rectangles and 1000x1000 it loads, but the "squares" are soo much compressed that borders meet each other and renders a full gray page.
I tried using HTML and JavaScript to draw SVG squares, the squares' size problem solves, but I don't know how to make they change color when clicked and when I set to load 1000x1000 squares it will freeze the browse and eventually crash the tab.
Is this feasible in any way?
EDIT
Sorry if I wasn't clear, but yes, I need scroll bars in that. They are no problem for me.
You can see the two trials I described here:
JavaScript and CSS
var lastClicked;
var grid = clickableGrid(100,100,function(el,row,col,i){
console.log("You clicked on element:",el);
console.log("You clicked on row:",row);
console.log("You clicked on col:",col);
console.log("You clicked on item #:",i);
el.className='clicked';
if (lastClicked) lastClicked.className='';
lastClicked = el;
});
document.body.appendChild(grid);
function clickableGrid( rows, cols, callback ){
var i=0;
var grid = document.createElement('table');
grid.className = 'grid';
for (var r=0;r<rows;++r){
var tr = grid.appendChild(document.createElement('tr'));
for (var c=0;c<cols;++c){
var cell = tr.appendChild(document.createElement('td'));
++i;
cell.addEventListener('click',(function(el,r,c,i){
return function(){
callback(el,r,c,i);
}
})(cell,r,c,i),false);
}
}
return grid;
}
.grid { margin:1em auto; border-collapse:collapse }
.grid td {
cursor:pointer;
width:30px; height:30px;
border:1px solid #ccc;
}
.grid td.clicked {
background-color:gray;
}
JavaScript and HTML
document.createSvg = function(tagName) {
var svgNS = "http://www.w3.org/2000/svg";
return this.createElementNS(svgNS, tagName);
};
var numberPerSide = 20;
var size = 10;
var pixelsPerSide = 400;
var grid = function(numberPerSide, size, pixelsPerSide, colors) {
var svg = document.createSvg("svg");
svg.setAttribute("width", pixelsPerSide);
svg.setAttribute("height", pixelsPerSide);
svg.setAttribute("viewBox", [0, 0, numberPerSide * size, numberPerSide * size].join(" "));
for(var i = 0; i < numberPerSide; i++) {
for(var j = 0; j < numberPerSide; j++) {
var color1 = colors[(i+j) % colors.length];
var color2 = colors[(i+j+1) % colors.length];
var g = document.createSvg("g");
g.setAttribute("transform", ["translate(", i*size, ",", j*size, ")"].join(""));
var number = numberPerSide * i + j;
var box = document.createSvg("rect");
box.setAttribute("width", size);
box.setAttribute("height", size);
box.setAttribute("fill", color1);
box.setAttribute("id", "b" + number);
g.appendChild(box);
svg.appendChild(g);
}
}
svg.addEventListener(
"click",
function(e){
var id = e.target.id;
if(id)
alert(id.substring(1));
},
false);
return svg;
};
var container = document.getElementById("container");
container.appendChild(grid(100, 10, 2000, ["gray", "white"]));
<div id="container">
</div>
I will be trying implementing the given answers and ASAP I'll accept or update this question. Thanks.
SOLUTION
Just to record, I managed to do it using canvas to draw the grid and the clicked squares and added an event listener to know where the user clicks.
Here is the code in JavaScript and HTML:
function getSquare(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: 1 + (evt.clientX - rect.left) - (evt.clientX - rect.left)%10,
y: 1 + (evt.clientY - rect.top) - (evt.clientY - rect.top)%10
};
}
function drawGrid(context) {
for (var x = 0.5; x < 10001; x += 10) {
context.moveTo(x, 0);
context.lineTo(x, 10000);
}
for (var y = 0.5; y < 10001; y += 10) {
context.moveTo(0, y);
context.lineTo(10000, y);
}
context.strokeStyle = "#ddd";
context.stroke();
}
function fillSquare(context, x, y){
context.fillStyle = "gray"
context.fillRect(x,y,9,9);
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
drawGrid(context);
canvas.addEventListener('click', function(evt) {
var mousePos = getSquare(canvas, evt);
fillSquare(context, mousePos.x, mousePos.y)
}, false);
<body>
<canvas id="myCanvas" width="10000" height="10000"></canvas>
</body>
Generating such a large grid with HTML is bound to be problematic.
Drawing the grid on a Canvas and using a mouse-picker technique to determine which cell was clicked would be much more efficient.
This would require 1 onclick and/or hover event instead of 1,000,000.
It also requires much less HTML code.
I wouldn't initialize all the squares right off, but instead as they are clicked -
(function() {
var divMain = document.getElementById('main'),
divMainPosition = divMain.getBoundingClientRect(),
squareSize = 4,
square = function(coord) {
var x = coord.clientX - divMainPosition.x + document.body.scrollLeft +
document.documentElement.scrollLeft,
y = coord.clientY - divMainPosition.y + document.body.scrollTop +
document.documentElement.scrollTop;
return {
x:Math.floor(x / squareSize),
y:Math.floor(y / squareSize)
}
}
divMain.addEventListener('click', function(evt) {
var sqr = document.createElement('div'),
coord = square(evt);
sqr.className = 'clickedSquare';
sqr.style.width = squareSize + 'px';
sqr.style.height = squareSize + 'px';
sqr.style.left = (coord.x * squareSize) + 'px';
sqr.style.top = (coord.y * squareSize) + 'px';
sqr.addEventListener('click', function(evt) {
console.log(this);
this.parentNode.removeChild(this);
evt.stopPropagation();
});
this.appendChild(sqr);
});
}());
#main {
width:4000px;
height:4000px;
background-color:#eeeeee;
position:relative;
}
.clickedSquare {
background-color:#dd8888;
position:absolute;
}
<div id="main">
</div>
Uses CSS positioning to determine which square was clicked on,
doesn't initialize a square until it's needed.
Granted I imagine this would start to have a negative impact to use r experience, but that would ultimately depend on their browser and machine.
Use the same format you noramlly use, but add this:
sqauareElement.height = 10 //height to use
squareElement.width = 10 //width to use
This will add quite a large scroll due to the size, but it's the only logical explanation I can come up with.
The canvas approach is fine, but event delegation makes it possible to do this with a table or <div> elements with a single listener:
const tbodyEl = document.querySelector("table tbody");
tbodyEl.addEventListener("click", event => {
const cell = event.target.closest("td");
if (!cell || !tbodyEl.contains(cell)) {
return;
}
const row = +cell.getAttribute("data-row");
const col = +cell.getAttribute("data-col");
console.log(row, col);
});
const rows = 100;
const cols = 100;
for (let i = 0; i < rows; i++) {
const rowEl = document.createElement("tr");
tbodyEl.appendChild(rowEl);
for (let j = 0; j < cols; j++) {
const cellEl = document.createElement("td");
rowEl.appendChild(cellEl);
cellEl.classList.add("cell");
cellEl.dataset.row = i;
cellEl.dataset.col = j;
}
}
.cell {
height: 4px;
width: 4px;
cursor: pointer;
border: 1px solid black;
}
table {
border-collapse: collapse;
}
<table><tbody></tbody></table>

Move text up with javascript

So I need function like this one, -link- but just to move text up, not left. How to achieve this?
So, this is code that moves text left:
//Text fade
var bgcolor;
var fcolor;
var heading;
//Number of steps to fade
var steps;
var colors;
var color = 0;
var step = 1;
var interval1;
var interval2;
//fade: fader function
// Fade from backcolor to forecolor in specified number of steps
function fade(headingtext,backcolor,forecolor,numsteps) {
if (color == 0) {
steps = numsteps;
heading = "<font color='{COLOR}'>"+headingtext+"</strong></font>";
bgcolor = backcolor;
fcolor = forecolor;
colors = new Array(steps);
getFadeColors(bgcolor,fcolor,colors);
}
// insert fader color into message
var text_out = heading.replace("{COLOR}", colors[color]);
// write the message to the document
document.getElementById("fader").innerHTML = text_out;
// select next fader color
color += step;
if (color >= steps) clearInterval(interval1);
}
//getFadeColors: fills colors, using predefined Array, with color hex strings fading from ColorA to ColorB
//Note: Colors.length equals the number of steps to fade
function getFadeColors(ColorA, ColorB, Colors) {
len = Colors.length;
//Strip '#' from colors if present
if (ColorA.charAt(0)=='#') ColorA = ColorA.substring(1);
if (ColorB.charAt(0)=='#') ColorB = ColorB.substring(1);
//Substract red green and blue components from hex string
var r = HexToInt(ColorA.substring(0,2));
var g = HexToInt(ColorA.substring(2,4));
var b = HexToInt(ColorA.substring(4,6));
var r2 = HexToInt(ColorB.substring(0,2));
var g2 = HexToInt(ColorB.substring(2,4));
var b2 = HexToInt(ColorB.substring(4,6));
// calculate size of step for each color component
var rStep = Math.round((r2 - r) / len);
var gStep = Math.round((g2 - g) / len);
var bStep = Math.round((b2 - b) / len);
// fill Colors array with fader colors
for (i = 0; i < len-1; i++) {
Colors[i] = "#" + IntToHex(r) + IntToHex(g) + IntToHex(b);
r += rStep;
g += gStep;
b += bStep;
}
Colors[len-1] = ColorB; // make sure we finish exactly at ColorB
}
//IntToHex: converts integers between 0 - 255 into a two digit hex string.
function IntToHex(n) {
var result = n.toString(16);
if (result.length==1) result = "0"+result;
return result;
}
//HexToInt: converts two digit hex strings into integer.
function HexToInt(hex) {
return parseInt(hex, 16);
}
var startwidth = 0;
//scroll: Make the text scroll using the marginLeft element of the div container
function scroll(startw) {
if (startwidth == 0) {
startwidth=startw;
}
document.getElementById("fader").style.marginLeft = startwidth + "px";
if (startwidth > 1) {
startwidth -= 1;
} else {
clearInterval(interval2);
}
}
function fadeandscroll(txt,color1,color2,numsteps,fademilli,containerwidth,scrollmilli) {
interval1 = setInterval("fade('"+txt+"','"+color1+"','"+color2+"',"+numsteps+")",fademilli);
interval2 = setInterval("scroll("+containerwidth+")",scrollmilli);
}
Something like this seems to do what you want, but jQuery would have been easier.
Demo: Vertical Marquee Demo
window.document.addEventListener("DOMContentLoaded", function()
{
var elm = window.document.querySelectorAll("#display span")[0], height = elm.parentNode.offsetHeight;
elm.style.position = "relative";
elm.style.top = "0px";
var timer = setInterval(function()
{
var top = Number(elm.style.top.replace(/[^\d\-]/g, ''));
top = top > -height ? top - 1 : height;
elm.style.top = top + "px";
}, 50);
/*
* If you want to stop scrolling, call clearInterval(timer);
*
* Example set to stop when clicked.
*/
elm.addEventListener("click", function()
{
clearInterval(timer);
}, false);
}, false);

Particles with CSS and JavaScript

I'm trying to create something like a very simple particle system. No physics required at this point, just divs that are animated to look like bubbles, or bees, or whatever. The code below creates the divs and through CSS I can make them change position, floating upwards. But I can't seem to workout how to destroy particles. Each particle does it's motion and then returns back to it's original point. I would prefer if it was removed completely.
Thank you.
/* ==================== PARTICLES CONTROLLER ==================== */
/**
* Particle controller interates through all elements with
* CSS class name PARTICLE_CSS and when found a ParticleController is instantiated
* for each of the elements.
*/
function ParticleBaseController(){
var ParticleContainer = document.querySelectorAll(PARTICLE_CSS),
ParticleContainerLength = ParticleContainer.length;
for (var i = ParticleContainerLength - 1; i >= 0; i--){
new ParticleController(ParticleContainer[i]);
};
};
function ParticleController(element) {
var particleElement, fragment = document.createDocumentFragment();
var numberOfParticles = 1;
for (var i = 0; i < numberOfParticles; i ++) {
particleElement = document.createElement("div");
particleElement.addClassName(PARTICLE_ELEMENT_CSS_CLASS);
var Ypos = Math.floor((Math.random()*200)+1);
var Xpos = Math.floor((Math.random()*200)+1);
particleElement.style.top = Ypos + "px";
particleElement.style.left = Xpos + "px";
fragment.appendChild(particleElement);
}
element.appendChild(fragment);
setTimeout(ParticleBaseController, 3000);
};
This worked for me. I am guessing that the way it works is that particles are only appended to the container as long as there are fewer than 15. Although I do not know how they are actually destroyed. But on screen I can only ever see 15 particles at a time, or however many I set then number to.
/* ==================== PARTICLES CONTROLLER ==================== */
const NumberOfParticles = 15;
function smoking()
{
var container = document.getElementById('particleContainer');
for (var i = 0; i < NumberOfParticles; i++)
{
container.appendChild(createParticle());
}
}
function randomFloat(low, high)
{
return low + Math.random() * (high - low);
}
function createParticle()
{
var particleDiv = document.createElement('div');
particleDiv.style.top = "-300px";
particleDiv.style.left = "200px"
particleDiv.style.webkitAnimationName = 'smoke-rise, smoke-fade';
var SmokeDuration = randomFloat(5, 10)+"s";
var FadeDuration = randomFloat(4, 11)+"s";
var SmokeDelay = randomFloat(0, 5)+"s";
var FadeDelay = randomFloat(2, 9)+"s";
particleDiv.style.webkitAnimationDuration = SmokeDuration + ', ' + FadeDuration;
particleDiv.style.webkitAnimationDelay = SmokeDelay + ', ' + FadeDelay;
return particleDiv;
}
window.addEventListener("DOMContentLoaded", smoking, false);

Categories