So I've gone a little overboard...
April 23, 2019, 12:58 am

I have a new thing I've been working on recently. I may as well post about it here.

I've been teaching now for about 10 years. I've never been better at programming and design than right now. I have not been sitting back idle, I have been attempting to push myself forward. The questions my students bring, and the projects they conceive have been amazing for my own personal growth as a professional.

Recently I began trying to write down some of the things I wish I had more time to talk about or teach during class. Either things that I came up with on my own for my own work, or things that are just beyond the scope of a design oriented school. Tutsos.com is a tutorial website, that I am becoming quite proud of. It is an organic recording of my own tools and how to make them from scratch.

One of the things I made offhandedly one night was a set of icons for a mobile design tutorial. And it ballooned out of control. I now have over 200 icons in a set that I designed. As a guy that never considered himself a designer, this is a big feat for me. If you'd like to check them out, they are searchable at icon.tutsos.com. But I'll just embed that here.

Sometimes you gotta make a thing
March 25, 2019, 3:38 pm

Sometimes, you just have to sit down and look at every app you can find, and if you ever see an icon twice, you gotta make a version of it.

I learned a lot about current trends in icon design by doing this set. It was also a lot of fun to subvert some of those trends.

prev next hamburger list shishkabob-vertical shishkabob-horizontal grid-3 grid-2-full grid-2-open home
group profile camera heart search star bell pencil microphone reload
checkmark plus close minus arrow-left arrow-right arrow-up arrow-down gear target
chat-empty chat-full messages-empty messages-full send-message circle-i smiley circle-no thumbs-up thumbs-down
feed suitcase folder mail image lock-closed lock-open camera-video cart-empty cart-full
bluetooth bluetooth-full bars-reception-1 bars-reception-2 bars-reception-3 bars-reception-4 wifi-1 wifi-2 wifi-3 cast
world map-marker map-folded location-direction location-star location-driving timeline share note-location note-empty
layers layers-alt banner-bookmark banner-bookmark-plus cloud cloud-download cloud-upload battery-empty battery-half battery-full
circle-plus circle-minus circle-close circle-checkmark square-rounded-plus square-rounded-minus square-rounded-close square-rounded-checkmark square-plus square-minus
square-close square-checkmark book-open ticket paperclip trashcan phone pin paper flag

Indeed. I may have spent too much time on this. Even when in fact I didn't spend much time at all. Some of these might get a slight update, but this was a lot of fun. I think every one of my students should have to do this as an exercise.

This is for a thing. You may already know. I'll be announcing it soon.

Tags: icons

Javascript continues, so I make silly things
February 16, 2019, 2:56 pm

I am continuing my own javascript education. I have begun documenting some instructions, which I will divulge soon, hopefully, but I've also begun redesigning some old examples that I made for students, in order to make them more accessible. One such example is from my app development class where students often want to add more interesting interactions to their projects. It's difficult to suggest things to them, especially since simply pointing them at HammerJs rarely results in them spending effort to fully understand that library, and instead just confuses them by making them search all over the internet for a simple solution to that toolset.

So here's one fairly simplistic example. Not only for my students, but of my current goals. This is an IOS style list item swiper. You've definitely seen these before.

See the Pen Vanilla Javascript IOS style list item slide reveal by Hamilton (@bronkula) on CodePen.

The content inside of the elements, and the look of them, is mostly up to the developer. This particular class, which can be found on github, has a number of options, including an onupdate method which will be sent the swiper object to give the developer freedom do do lots of things.

Many interesting layouts can be created and used, and I'm still currently working on some other options. If you'd like to mess with these examples, you can find them on my Codepen.

The Unit Circle
December 15, 2018, 5:14 pm

I got a little bit obsessed with trigonometry this last year, and over the last week, I really tried to understand as much of it as I can, and how it is used in Javascript. I made a thing. There was a Reddit post about a unit circle gif, and I said to myself. I can make that, but better and interactive. And so I tried to. Here is an embedded version of my Unit Circle.

This thing is a kind of big deal to me, because it represents a lot of big things. One thing is my general shift over the last year toward actually documenting the things I make. I've been working hard on a lot of projects, including my drawtools and apptools libraries. I've been learning a lot about the latest ECMAScript in order to push my own knowledge and really be able to make these tools be great and useful.

And I'm kind of really proud of myself. People look at my art and they either like it or they don't. But people see the things I code and it feels like they think "I wish I understood this" Because I must be so excited about it. And they aren't. My code is like a high schooler's poetry. No one cares. I'm writing a pity party right now. That's what this is. I'm having a party just for me, and the topic is poor me. But it's what I feel sometimes.

I just have to say for myself that I'm proud of me. And if you're proud of me, I hope that you'll share some of the dumb things that I make sometimes.

You don't always need to be understood
October 15, 2018, 9:02 am

Yesterday I saw a car start to make a left in an intersection. After getting about 3/4 of the way through, he stopped just before entering the new lane he should be going into. It's hard to describe in words, because no one would ever do this. He was still in the middle of the intersection when he stopped. The car behind him had to stop as well, but dead in the middle of the intersection.

The second car honked. And rightfully so. A sort of nudging honk that doesn't exactly come across friendly until you step out of yourself and realize that all honks sound the same at their core, and situationally, this was just a short "hey there friend. I noticed you aren't moving, and thought you could use some encouragement" kind of honk.

The first car sort of did a hesitated bounce, then pulled forward. But only about 3 feet and then stopped again.

At this point there are three cars in the intersection, and the two cars behind are railing on their horns. What else could they do? The first car nudges forward a few more feet and then stops again once he is fully into the new lane, but the other two cars are still well out into the intersection, blocking traffic. Horns are honking. Windows are down and people are yelling.

And the guy in car number one steps out of his vehicle. In the middle of the lane, while blocking traffic. He steps out and begins yelling, and although I can't hear it, it's pretty clear the basic concept of what has happened.

He has had a complete breakdown of all of his faculties. He has gone through a barrage of emotions in a short amount of time. He was probably confused at a certain point. Then frustrated. Then suddenly scared. Then angry. Then humiliated. Then entrenched. Then confused again. Then pissed. And all of this probably happened within a 10 second window.

And then he did the only thing some can think of to do in a situation like this. He hunkered down, he backed himself into a corner, and he tried to get the world to recognize his feelings of hurt and fright and anger. Like a new dog barking at people at a party for the first time, he lashed out at anything and everything around him.

A bus pulled up to the blocked intersection and did something you rarely get to see. He got on his megaphone and started blasting at this guy loud and vocal. MOVE YOUR VEHICLE. CONTINUE TO THE SIDE. And the guy, suddenly presented with a solution instead of just loud noises... or perhaps presented with a bigger barking dog... got back in his vehicle and moved forward and to the side.

And I went about my day.

I think there could perhaps be a number of life lessons hidden within this story. And I am a big fan of finding life lessons in the situations one finds oneself. I think one life lesson is that you shouldn't just honk at a problem. Sometimes you need to yell solutions at it, until one sticks.

But I think the lesson most worth learning is actually one that people who need it might find difficult to learn. You don't need to stop the world for recognition every time you're upset. Most others will probably only become upset with you, and their resentment will not improve your condition. And even when someone presents a solution to you, you will have to be willing to become untrenched and accept an outward resolution. If all you want to do is stop the world and make everyone see that you're upset, you are not striving for a solution. If all you're doing is trying to find out whose fault it is, and not move forward, then resolution is so much more difficult.

There is a time and place for anger, for hurt, and for venting. But a person needs to learn to pull over to the side of the road, rather than forcing others to acknowledge the person's own struggles, just for the sake of acknowledgement.

The White Whale
September 23, 2018, 11:16 am

I've been drawing and painting digitally for quite a while. It's not new for me. I've used all the programs. I started coloring back in Photoshop 4. I wasn't the first in the space, and certainly many of my peers have far surpassed my skillset. Go check out people like Matt Rhodes, Becky Cloonan, Corey Lewis, or Matthew Woodson If you want to see some of my contemporaries who went off and did great things.

But I have used just about every program. On just about every device. Trying desperately to find what I have often described as "My Perfect Drawing Program". My work has given me the opportunity to make art on all kinds of devices and applications. I feel like this story needs a preface that makes clear, I'm not some fanboy on any side. I am an agnostic device user. I use an Android phone, and an iPad, and a Surface Book for a laptop, and an iMac for a work desktop. I have Raspberry Pi devices strewn throughout my house, and a Linux desktop for a home server. I just need you to understand that this is a bipartisan issue, ok?

I've made a previous article about this basic topic before. And most of that still applies today. I list off a bunch of devices, I list off a bunch of programs, and for the most part it's all still the same.

But one major thing has changed for me. Infinite Painter on Android is now also available on iPad, and it has pulled out far in front of every other program I've used. I want to take a second and describe my perfect drawing and painting program and rate Infinite Painter on all those features.

Speed

I need speed. I need your program to run fast, like the wind. Like Forrest Gump in front of a car breaking out of his little broke boy crutches.

Infinite Painter is buttery smooth on the Note 8, and on the iPad Pro. I can push it to the point of slowing down, but I have to try real hard to do it.

Canvas Size

I need to be able to draw and paint at printable sizes.

Infinite Painter lets me set any arbitrary canvas size, save regular sizes for later, and it tells me more or less how making something at that size is going to affect my use of the program. A program can only go so big effectively, most artists understand that. But that should be more or less up to the user, not the program, unless the developer knows it will absolutely become unstable at certain numbers. But if I can make a one layer giant canvas, give me that option, and tell me if anything is changing.

Pro Tools

I am a professional artist who wants to make professional works whether they look like sketches or paintings. Nothing makes me more frustrated than a developer who has a couple really great features, but holds back on others because their program is "just for sketching". So what do I mean by pro features?

  • Selection Tools
    • Lasso Selection Tool
    • Straight Line Selection Tool
    • Smart Selection Tool
  • Free Transform of layers and selections
  • Curves Color Manipulation
  • Layers
    • Merge Layers
    • Blending Modes
    • Masking
    • Clipping
    • Groups
    • Clear Layer
  • Grid
  • Vector Tools

Kaleidescope

This isn't so much for me, as it is for the times. Kaleidescope and Symmetry drawing has uses in a lot of design and drawing. Having tools like these present is something that becomes more necessary once you realize how powerful they are.

Infinite Painter does have these tools as well as tile creation tools. Some are further along than others, but they are all at least present.

Brush Creation

This is one of the bigger things that can make or break my use of a drawing program. I need clear and complex tools for creating and manipulating brushes.

Infinite Painter has something miraculous for brush creation. Curves for the amount of effect that pen pressure, tilt, and speed have on a brush and texture. Once you create a brush using these curves settings, you will be frustrated at the lack of control other systems give you.

  • Custom Heads
  • Custom Textures
  • Color Mixing
  • Clear indication of change effect on brush quality
  • Clear indication of Texture settings changes

Tools Palette

I need a palette that lets me easily swap tools, but doesn't get in my way. It's a delicate balance to strike. I need to be able to swap between standard tools (or even better a set of tools of my choosing) and set the settings of those tools independently. Some programs give you the ability to swap tools, but their settings are linked, or stuck.

My ideal program would have a tools palette that is completely customizable, able to be set anywhere in the window, and has ease of access to common manipulation options.

Infinite Painter's tools palette is fantastic. It's small. It has separate paint, eraser, and smudge tools docked into the palette. Each can be set to a separate brush, separate size, and have their own opacity and flow settings. The palette buttons can be clicked for fine control or scrubbed for instant manipulation. Each brush can be scrubbed to choose between favorite brushes quickly. The only thing that might be better would be to arbitrarily be able to choose the tools present in the palette, but the simplicity of these options is palpable. The palette can be docked anywhere, and naturally moves out of the way of other palettes when it needs to.

Swatch Tools

Color manipulation is an extremely necessary part of any painting program and process. Most programs these days have pretty excellent Swatch tools (except perhaps Photoshop), but not all of them allow you to dock a swatch palette onto the screen.

Infinite Painter gives a Swatch palette with savable swatches. Draggable colors within the swatch allow manipulation, not just creation. The swatch can be docked to the screen and dragged to access more colors.

Color Picker

Color picking is a necessary process of any painting program. The ease of this can either hinder or greatly improve the painting procedure of any artist. My perfect program can select color easily with a drag operation, and can choose to select only one pixel of color or a blend of a square.

Infinite Painter allows you to drag from the Tools palette color button to color pick onto the document. It also has a finger press to pen move option. I see a lot of programs doing a long press option these days, and I've actually begun liking that less and less. I think a drag from somewhere to pick is the right way to do it, however that might honestly be dependent on screen size whether that can begun to feel tedious.

Touch and Pen

Many artists want to use their fingers to do certain manipulation, and I get that, but it is a very physical way of working, and it is in many ways a vestigial technique from when artists learned to work before digital. In my perfect program, fingers and touch are for canvas manipulation, and the pen is for drawing. And this is where a lot of programs are just not up to snuff. Either there is no real consideration for touch, or it is slipshod and shoehorned in.

Touch should not draw, or it should be an option that can be turned off in settings.

But I work in a touch world, and once you've used touch to manipulate a canvas, you can't go back. Any modern drawing program should allow you to pan, scale, and rotate a canvas with two fingers. The process should be smooth and not limited to one option at a time, and once you do it, you realize how incredibly intuitive it is, and how much you were held back by the old methods.

Keyboard Shortcuts?

I don't even want a keyboard when I'm drawing. A perfect drawing program should have everything available without the need of any keyboard shortcuts, even though I totally understand that they should still be there on desktop applications.

  • CTRL Z? Give me history tools at a glance. Desktop size devices should have 3 finger scrub to go back through history (not 3 finger tap) and Infinite painter gives always on undo redo buttons and shows a history slider for a few seconds.
  • ALT/OPTION? We already discussed color picking, and how it should be a drag out action.
  • SPACEBAR? Two finger pan zoom and rotate.
  • Tools? All those options should be on the Tools palette.
  • Tool Size/Opacity? On the palette.

Get rid of the keyboard and a reliance on it. Touch devices should remove that necessity.

Reference

My perfect drawing program has a reference layer. This unique layer palette is set apart from the rest of the document and always gives a view to a reference image while drawing. This reference should be able to be cropped, pinned to anywhere, and rotated or zoomed as needed. Colors should be able to be chosen from this reference image, and it should move out of the way when drawing near it.

Infinite Painter ticks most of these boxes off, and the ability to simply turn on and off the reference is very nice.

Hide Interface

Hiding the interface to allow a simpler drawing experience is nice. It's also extremely useful on mobile devices. But there should probably be levels of hiding. Hiding everything is nice sometimes, but hiding everything but the most basic tools seems like a more useful option.

Infinite Painter definitely lets you hide the main interface, while the only thing that stays will be your reference photo, and since you can switch tools with the secondary pen button click, you can still switch between erasing and drawing on phone. This mode should, however, only be thought of as a sketching mode.

Video Output

Any modern drawing program should have the ability to record and playback a video of the drawing being created. It should be able to simply output to mp4. It should start recording from the beginning of any drawing, or at least have an option to opt out. I draw too many drawings to remember if this option is an opt in.

Infinite Painter allows you to choose whether you want to output as a stationary document of your drawing, or a rotating moving screengrab of the actual view of your interface while you were drawing.

Export and Import

Any program should be able to at least import any jpg or png. But they should probably also be able to do the same for PSD, TIFF, or PDF.

Infinite Painter can handle import and export of most standard formats, and saves to its own proprietary format. I would actually like it if it saved to a more standard normal format like TIFF.


If you've been searching for the perfect drawing or painting program, it actually doesn't exist yet. But I am of the opinion that Infinite Painter is the closest thing we have at the moment. If you haven't given it a chance on Android or iPad, you should. The initial program is free to try, and you'll only have to pay a reasonable sum to access its full potential.

There is an active community of users on Google Plus, and Sean Brakefield is actively developing both the Android and iOS versions of the application.

This is really just for me...
August 11, 2018, 12:21 pm

So you want to write in vanilla Javascript. But you've definitely noticed it's missing some shit. And if you haven't noticed, it's because you never really learned how to write jQuery.

One of the major reasons I will probably not give up jQuery any time soon, is because of event delegation. Event delegation is a great way to make event listeners that don't require an existing element yet. This lets us set up events for any element that MIGHT exist some time in the future.

Well here's a small function to add super basic event delegation for a space separated string of classes to your code setup.

function delegateEvent(delegate,event,target,callback){ var targets = target.split(" "); delegate.addEventListener(event, function (e) { targets.forEach(function(o){ if ( e.target.classList.contains(o) ) callback.apply(e.target,[e]); }); }, false); }

It's pretty simple. But it's a major relief to have this written out even for myself.

You could even take this one step further. You could add a delegate function to all object prototypes. This is technically a bad idea for big projects, but you shouldn't be writing very much code like this for that size of a project anyways. You should be using some framework or library.

Object.prototype.delegate = function(event,target,callback){ this.addEventListener(event, function (e) { var targets = document.querySelectorAll(target); [].forEach.call(targets,function(o){ if ( e.target == o ) callback.apply(e.target,[e]); }); }, false); }

This even gives us the ability to create query selectors instead of just class lists like the previous example.

Javascript Functions, Closures, and the IIFE
June 29, 2018, 9:14 am

When writing code in Javascript or any programming language, one of the core concepts that a developer has to wrap their heads around is the function. If variables are values to be referred to at a later time, functions are whole sets of code to be referred to later.

Function

function myFunc() { // Do something }

You can also define a function as a value, or as an anonymous function. Normally functions are hoisted to the top of the code and run first, but an anonymous function is created inline with the rest of the code around it.

Anonymous Function

var myFunc = function() { // Do something }

There is value in both of these methods. It is important to know your options and explore their relevance. But there are even more options.

Sometimes it can be handy to define a function that defines it's own lexical scope. This allows local variables to be set up statically.

Closure

function foo(){ var id = 5; var bar = function() { console.log(id); } return bar; } var foobar = foo(); foobar();

This series of code has some very interesting implications for scope and how to create functions that have their own values. The id variable only exists inside the foo function, but the foo function returns the bar function as a value, and since the bar function was made inside foo, and after id, it also has access to the id value. Closures allow you to segregate your values and give unique scope to parts of your project. This becomes especially useful when you want to write code for libraries and larger repositories.

Immediately Invoked Function Expression

(function() { // Do something })()

Then there is this beast. A function with no name. No real declaration, but put inside of an expression syntax that fires it off immediately. What is the point? Why wouldn't the do something code simply be code, why does it need to be wrapped up like this?

Well, defining a function anonymously allows it to be passed around by value in a much more flippant manner. Most often anonymous functions are used for callback reasons. However, if it tries to access values that were created outside of it's scope it accesses them dynamically at their current value. This can be an unwanted effect, that is most often run into when defining a callback function inside of a loop.

If you make 3 buttons dynamically in a loop, and have them each print out the iterator value on click, all of them will print out the last value, because at the time of clicking, the iterator would have only its final value.

for(let i=0;i<3;i++){ $("body").append($("< button>").click(function() { console.log(i); })); }

This exact situation is when an anonymous function called immediately to provide closure to its scope is most effective. But it gets more complicated. Any method that is expecting a function to be passed into it must receive a function. And a closure that returns a function as a value is a goofy thing to look at.

Anonymous Closure Callback Immediately Invoked Function Expression

var i = 5; $("button").click( (function(id) { return function() { console.log(id); } })(i) ); i = 10;

Now, that's just weird to look at your first time. It will start to make sense the more you end up using it. The IIFE is being passed a variable in order to give closure to it's current value. The i variable gets passed in at the end of the closure, and then is referred to on the inside as id. This means that no matter what might happen to i in the future, when the click happens, the value of i has been stuck into the static value of 5 in id.

[edit] So um... turns out that loop example doesn't produce the result I said it would which means.... That's not actually a problem when you use the let declaration, instead of the var. But the final example still matters.

Don't hold onto hate
May 30, 2018, 5:48 pm

Today has been a disheartening day for me. The amount of people I've seen defend racism is staggering. But the worst is the casual ambivalence toward what people are referring to as "only a little racist" or "just racist that one time". As if that's how it works. I don't know what to do with this information, but I know that I compiled the data from numerous sources.

I'm not sure I'll ever have the answers. Maybe no one ever will. But I like to think I can at least see the forest when it comes to this kind of thing.

Keep examining yourself, folks. Cut out hate where you find it. Latch onto love if you can. I'm not talking about backing off of your principles. I'm not saying be a pushover. I'm saying choose to be kind rather than mean. Truly mean. You can be playful. Don't be cruel. Don't hold that in your heart.

Tags: self, journal

I finally found a reason to curry
April 25, 2018, 6:43 pm

Currying functions is not necessarily a hard concept to understand. It goes like this: You make a function that returns a function for something else to call as a function.

...

Hold on. Let me give you an example.

var a = function(num1) { return function(num2) { return num1 + num2; } } var b = a(3); var c = b(3); // output 6;

But here's the thing. That example really makes no sense. What's going on here? And why would I do this?

Well first of all, you wouldn't. That's a too simplistic bad example. I can see you saying "I would just make one function with two parameters" and you would be right of course. That's a much better use for that example.

But what if you needed a kind of a function that needed to do some things, and prepare some things, and then have a unique kitchen table prepared for a meal to be prepared again and again in the future?

What if you needed a table command that prepared a particular kind of bread. And then anyone could come along to the table they liked and make sandwiches out of the bread at that table. Sandwiches always get made the same way, but the bread needs to be prepared first.

var makeBread = function(breadtype){ return function(jamType,pbType) { return `${pbType} and ${jamType} on ${breadtype}`; } } var wheatSandwich = makeBread("wheat"); var sandwich1 = wheatSandwich("jelly","creamy pb"); var sandwich2 = wheatSandwich("marmalade","crunchy pb");

So now we don't have to define wheat anymore. It's part of the function. But using the original makeBread sandwich we could still define another style of sandwich if we wanted to.

I recently found currying useful while working on my drawtools library. Currying a tool for loading images into a canvas allows me to set up a function that caches a particular image into it's own memory to then draw onto a canvas.