Playing with the DOM

For this week I have two sketches – both relating to interacting with DOM elements.

First – Albers

Screen Shot 2015-10-12 at 11.17.01 PM

The RGB squares on the left are DIV elements created in javascript with createDiv.  These div’s can be dragged – and when they are dropped onto the canvas they create a custom ‘square’ object that is drawn onto the canvas.  Accomplishing the draggable Div took a bunch of trial and error, but eventually I got it feel pretty good.

The general flow looked like this:

// create a div

// assign it a class

// set it’s position

// create divs

redDiv = createDiv(”);
blueDiv = createDiv(”);
greenDiv = createDiv(”);

// Assign them a class to be used for styling

redDiv.class(‘draggable’);
blueDiv.class(‘draggable’);
greenDiv.class(‘draggable’);

// set positions:
redDiv.position(0, 0);
blueDiv.position(0, 200);
greenDiv.position(0, 100);

// Register callbacks using anonymous functions
redDiv.mousePressed(function() {
divClicked = ‘red’;
});
blueDiv.mousePressed(function() {
divClicked = ‘blue’;
});
greenDiv.mousePressed(function() {
divClicked = ‘green’;
});
redDiv.style(‘background-color’, ‘red’);
blueDiv.style(‘background-color’, ‘blue’);
greenDiv.style(‘background-color’, ‘green’);

Each mousePressed callback just set’s a state var telling me which div item was under the mouse when pressed.  To drag it – I just use that information and pass it along to

function dragDiv(d) {
d.position(mouseX + 50, mouseY – 50);
}

where d is the div element.  That function is called like so dragDiv(redDiv) – updates the position of the div.

When the mouse is released, I check to see if the mouse position is over the canvas, and if so create a new Square object to draw.

function mouseReleased() {
// if Div was dropped above canvas – create a new div, and place div back
// where it was
// get div that is currently being dragged
// mouse was over canvas upon release
if (mouseX > 0 && mouseX < c.width && mouseY > 0 && mouseY < c.height) {
// create new div over the canvas
switch (divClicked) {
case ‘red’:
createCanvasElement(‘red’, mouseX, mouseY);
break;
case ‘blue’:
createCanvasElement(‘blue’, mouseX, mouseY);
break;
case ‘green’:
createCanvasElement(‘green’, mouseX, mouseY);
break;
}
}

// move div’s back to where they started
redDiv.position(0, 0);
blueDiv.position(0, 200);
greenDiv.position(0, 100);

// Null out divCLicked so You dont’ grab the same div again
divClicked = ”
}

At the end of the mouseReleased function I made sure to clear out my divClicked state var to ensure that I don’t accidentally add more squares to the screen.  If I didn’t clear out this var, then anywhere I clicked on the screen would trigger a new square to be drawn because the program thinks I’m always selecting that last div element.  The positions of the divs are also set back to their original position so they can be dragged once again.

I used a bunch of switch statements to know which div to drag, and what color squares to create.

The last fun little DOM element was a prompt.  If you click on a square that’s being drawn, you’ll get an input box that allows you to enter a hue value, so we can draw more than just RGB.  It was fairly straightforward, except for handling when the user doesn’t enter a number in the right range.  The way to accomplish it seemed to be:

if (!isNaN(hueInput) && hueInput >= 0 && hueInput <= 360 && hueInput !== null)

Basically if the input is a number, and it’s in the right range, and it’s not null, then use the input value to change the hue.

 

The second sketch was a game of cards!

Screen Shot 2015-10-13 at 4.04.42 PM

Here I played with loading DOM elements in a for loop and assigning each element a callback.  It was a really big pain.  I eventually accomplished it like so:

for (var i = 0; i < 26; i++) {
var card = createDiv(i);
card.class(“card”);
cards.push(card);
card.mousePressed(function(e) {
flipCard(e.target.innerHTML);      // mousePressed calls a flipCard function that deals with the game logic
});
}

The trick was figuring out how to get useful information of what card I was tapping using the mousePressed callback.  I googled around for a while and started to see this style of callback which takes an event as an argument.  This event has properties that we can access, like target.inneHTML which gives the text inside the tag.  It took a while for it to click, but eventually I realized I could just set the text of the tag to be the index of the card, and the output mousePressed could just be that index.  Then I could look up the card that I needed from the array of cards.  I took me a few days of frustration to finally get it all sort of working.

flipCard took a bit to figure out as well as I had to deal with various states that the game could be in.  I have to keep track of if a card is already flipped up, and if so, run an if statement to see if the current card is the same as the last card.  If not, both cards need to flip back over, which entails updating the image to the card back image.  The problem was that without some kind of delay, if the cards didn’t match, both would just flip back down so fast that you wouldn’t ever see the image of the second flipped up card.  To work around this I utilized javascript’s setTimeout() function to wait for a second after flipping the second card before running the check and either removing or flipping cards back over.

 

Leave a Reply

Your email address will not be published. Required fields are marked *