Let's face it, canvas stuff is never terse and annoying. Creating buttons on a canvas is even harder. First you have to draw the button, change it's state, and other complicated things.
For instance, if the user pushes the mouse down on one clickable region, and drags it over to ANOTHER clickable region, the "click" event will still fire and (therefore) fire the second region's click event.
So what kinds of things do we actually need to figure this stuff out?
Well, for starters, let's demystify the mouse event positions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This will give you a way to get the mouse location of any click event. So let's build our clickable region first.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
..and the only things that are missing are the click events...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Today I wanted to share another nice and small use case for the forEach loop for the intermediate/beginner javascript developer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
As a disclaimer, my code isn't perfect, it can be optimized, and my goal isn't give you snippets of code to steal. However, I do this to show you how to make your own javascript functions yourself. Take my code and tweak it, add some useful functions that may help you finish your project.
I hope my samples help grow and motivate you to strive and become a better programmer.
Some techniques aren't new or novel. They are just fun. This isn't really new, or novel either, but it's quite fun.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In fact, some people would probably criticize that it is essentially the same thing as an Immediately Invoked Functional Expression. There are some key differences here though. Take a look at the following code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
It's starting to look like the module pattern, but it creates an object and ships it via function baz to the variable foo with bar's prototype. Alas, the this keyword shows it's confusing head again, but look closely. "this" is the object literal itself.
Finally I'll leave you with a working example.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Even in a hypothetical world where objects are packaged into black boxes it would seem that convention and configuration butt heads repeatedly until developers are quite frustrated with their code. In the real world it's even more difficult to package up black boxes because the language architecture design is fundamentally flawed. (I'm looking at you Javascript global namespaces!)
So, I've personally set out to develop quick easy ways to make boxes that appear to be black boxes, but are highly configurable.
Here were some of the goals I had in mind for designing my personal plugin Architecture.
Had to be easy!
Had to be quick!
Plugin Convention over configuration
Boilerplate-able
Should give access to constructor options to determine where the construction of the object goes
Should provide a local scope for hidden variables relative to each object.
Here's a boilerplate you can use to create something like I'm describing.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
If some of that code looks confusing to you, I suggest looking at the concept of functional expressions. They give you a "pseudo-blackbox" that can see the global namespace.
If you are good on closures, then we move on to the next step. Actually defining the code to make plugins work. Here's what I personally use:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This code is rather simplistic, but lets take a look a bit deeper to see the real beauty of it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This little function right here is where ALL the magic happens. Let me show you an example of why this is "magic." Writing a plugin is very easy to do here.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
As if that wasn't enough... let's go back and look at another example. A full on event emitter API.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Take some serious time to learn what just happened here. Each one of the functions created in that script are local to the object itself, because the plugin constructor code is called only once. This allows you to enclose private variables into a black box namespace. It's completely abstracted away to the developer behind the curtain.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
...are a functional portion of the javascript language and allow you to repeat functionality of code for a certain number of times specified by the conditions of the loop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
These examples are fairly easy and trivial. If you are not proficient in javascript loops, I highly recommend learning how to construct one from scratch here.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Functional loops provide a different mechanism for looping over the items in an array. They also have much larger implications for memory management and coding techniques.
Example: a user wants to loop over items in an array and perform a static operation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This example is obviously bad, because the same result could be achieved by calling target = array.slice();, but look a little bit closer at the example below.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Boom. Now you can enclose objects with functions and local variables.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
So now that we have our toolset, let's make a few rules on when certain loops are needed.
Native loops
When a functional context is not needed
Concatenating strings
Looping through strings
Anywhere that performance matters greatly
To put it simply, if the code requires speed and performance, chances are a for loop may be indicated. Especially for simple operations.
Lastly, the indications for functional loops...
Functional loops
When a closure is needed(I.E. Variables need to be obscured)
Chaining Maps (see example below)
When the calling function needs to be called multiple times in other places in the code (using a named function)
When Performance probably doesn't matter (and trust me, javascript is pretty fast)
When file size DOES matter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
I have been writing small posts lately, so it's probably best if I just cut to the chase.
Handlebars has been tried and true for templating.
Also, I'm in no way advocating for the use of these samples, but I think they speak for themselves. You don't always need a library because you are making an intranet application, or your users use modern browsers. You can code the language yourself!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"But Josh! I don't want to edit the prototype!"
Fine! Here you go.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In javascript, using the .call() method allows you to specify the context of whatever object you pass to it. This allows you to call a string method from an array context, and vice versa.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In all honesty, it may not be a good idea to use these methods, because they aren't supported on these objects, but check out what happens!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters