Skip to content

Instantly share code, notes, and snippets.

@toddbranch
Last active April 12, 2020 06:59
Show Gist options
  • Save toddbranch/4bf8e7ffa7fc55b4ddfb6bd4c0404329 to your computer and use it in GitHub Desktop.
Save toddbranch/4bf8e7ffa7fc55b4ddfb6bd4c0404329 to your computer and use it in GitHub Desktop.
Binary, Bitmasking, and Mouse Buttons!
// Computers represent numbers in binary (base 2), while humans represent them in decimal (base 10).
// In javascript, we can represent a binary number by putting "0b" in front of it
0b011 // evaluates to decimal 3!
// To convert a number from base 2 to base 10, we assign a value to each position
// _ _ _
// 4 2 1
// If the bit at that position is 1, that value is added to the sum. If it's 0, it isn't.
// 011 has 0 at the 4 position, 1 at the 2 position, 1 at the 1 position.
// So we add 2 + 1 to get the decimal value of 3!
// To represent larger values, we can add more positions to the left. The value at each
// is double the value at the prior position.
// _ _ _ _ _ _
// 32 16 8 4 2 1
// In javascript, all of these statements evaluate to true:
1 == 0b001
2 == 0b010
3 == 0b011
4 == 0b100
5 == 0b101
135 == 0b10000111
// To convert values from base 10 to base 2, we can reverse the process.
// Let's convert 39 to binary.
// Remember:
// _ _ _ _ _ _
// 32 16 8 4 2 1
// I start at the left and find the biggest value that fits into my number.
// In this case, it's 32 - so I put a 1 there.
// 1 _ _ _ _ _
// 32 16 8 4 2 1
// So I've represented 32. 39-32 == 7, so I only have to represent 7 more.
// 16 and 8 don't fit into 7, so I'll mark them 0.
// 1 0 0 _ _ _
// 32 16 8 4 2 1
// 4 fits into 7 - mark it 1.
// 1 0 0 1 _ _
// 32 16 8 4 2 1
// 7-4 == 3, so I only have to represent 3 more.
// 2 fits into 3 - mark it 1.
// 1 0 0 1 1 _
// 32 16 8 4 2 1
// 3-2 == 1, so I only have to represent 1 more.
// 1 fits into 1 - mark it 1.
// 1 0 0 1 1 1
// 32 16 8 4 2 1
// And I don't have anything left - all done!
39 == 0b100111 // true!
// Let's talk about boolean logic for a minute.
// Boolean means we're in a world where the only values are TRUE and FALSE (1 and 0).
// The AND operation means both arguments must be true.
// So:
// TRUE AND TRUE == TRUE
// TRUE AND FALSE == FALSE
// FALSE AND TRUE == FALSE
// FALSE AND FALSE == FALSE
// In javascript, the '&' operator means 'bit-wise AND'. It does an 'AND' operation on
// each bit in two binary numbers and outputs the result.
// It will only output a 1 in a position if both bits in that position are 1.
// So all of these evaluate to true:
(0b1 & 0b1) == 0b1
(0b0 & 0b1) == 0b0
(0b10 & 0b01) == 0b00
(0b101 & 0b001) == 0b001
(0b1010 & 0b0010) == 0b0010
// We can use this operator if we want to extract single bits of information.
// This is called "masking".
// Lets imagine we only care about the far-right bit - we want to know whether it's 1 or 0.
// We define a mask with a 1 in the position we care about, then use &:
var mask = 0b000001;
var value = 0b100111;
var result = value & mask;
// result == mask if it's set, result == 0 if not!
// Sometimes programmers use binary to represent information rather than numbers.
// Javascript's MouseEvent does this to tell us which buttons are pressed.
// Here's how we listened to the canvas for mouse movement:
canvas.addEventListener('mousemove', function(event) {
});
// event has a property called "buttons" that tells us which mouse buttons are pressed.
// if event.buttons == 1, the left button is pushed
// if event.buttons == 2, the right button is pushed
// if event.buttons == 3, the left AND right buttons are pushed
// Let's think about these values as binary:
// 0b01 means left button is pushed
// 0b10 means right button is pushed
// 0b11 means left and right are pushed
// Each bit represents the state of a mouse button! 0 means not pressed, 1 means pressed!
// So, using bitmasking, let's define functions that tell us the state of the different mouse buttons:
function isLeftPushed(buttonsValue) {
var mask = 0b01;
return (mask & buttonsValue) == mask;
}
function isRightPushed(buttonsValue) {
var mask = 0b10;
return (mask & buttonsValue) == mask;
}
canvas.addEventListener('mousemove', function(event) {
if (isLeftPushed(event.buttons)) {
console.log("left pushed!");
}
if (isRightPushed(event.buttons)) {
console.log("right pushed!");
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment