Category: CSS
Jan 4, 2017

My team does a holiday card promotion each year, which gives us a chance to create something unusual. This year we decided on a “create your own holiday card” image editor idea. We’d specify a couple of backgrounds and design a bunch of “sticker” graphics, then users could arrange these how they liked and print off a foldable card. Give it a try!

For this project, I created stickerbomb, a one-command in-browser basic graphics editor. It allows you to specify backgrounds and load in as many stickers as you’d like, categorized into drawers. Users can then position and manipulate the stickers however they like. When finished, they can either print it, save it, or share a URL that causes stickerbomb to reconstuct their image.


Give it a shot by designing your own smug tech conference laptop:



The show above would be created like this:

    target: '#target',
    backdrops: [ 'images/laptop.jpg' ],
    stickers: {
        'Stickers': [
                name: 'Angular',
                src: 'images/angular.png',
                widthPercentage: 15


                name: 'WordPress',
                src: 'images/wordpress.png',
                widthPercentage: 15
        'Accessories': [
                name: 'Bag',
                src: 'images/bag.png',
                widthPercentage: 60


                name: 'Tattoo',
                src: 'images/tattoo.png',
                widthPercentage: 30

Very easy! All other options can be found on the Github page.

How it works

Stickerbomb is an HTML5 canvas library. It’s plain JS that forms a number of DOM elements as controls around a canvas where it’s watching for mouse and touch movements. Whenever an event occurs on the canvas, it checks whether the selected tool should be instantaneous or work with dragging, and then, if dragging, records the position (relative to the canvas) and angle (relative to the sticker) of the start point and current point. The position information is gathered by the tool, which then uses whatever is applicable to manipulate the layers.

image sharing dialog

Rather than grant full control over positioning, it works on whole percentages. A sticker can be 15% wide, 28% from the left, and 50% from the top, for example. Movement and changes only happen on the whole numbers. This has the twofold benefit of significantly reducing the cost of the rendering loop (as each layer from the background up must be recalculated and redrawn in order on any change to the image) and allowing for very easy reconstruction of any created image. A basic notation of the information above would be w15l28t50, for example. That makes share URLs quite simple, fully client side, and small enough to pack more stickers than you’ll ever need into a URL before length limits become an issue (something like 800).

Printing and the future

One bit of weirdness in the library is its print function. For that it does a hidden, reconstructed rendering of your image in higher resolution, opens a new window with just that image at 100% width and flipped upside down, and then opens a print dialog–which was a proper pain to get working cross-browser. Assuming the aspect ratio is 1.55 this makes for a ready-to-fold card, which was the original goal. It’s not exactly what you’d expect to happen, though, so that may be branched out as its own tool separate from “print” if any future development is done on this.

The likely outcome is that this won’t be significantly developed further, but will result in a few good basic tutorial posts. How to tell if a click landed inside the boundaries of a rotated object, maybe.

Apr 15, 2015
Update: The Sendy Invoicing add-on has now been added to Sendy’s API docs as a third party resource! View this add-on and other great supporting software at

Our organization has needed a more user-accessible mass email solution for some time, so when we saw Sendy it was a no-brainer to pick up the dead cheap $59 license and spin up an instance. The whole thing has a minimal, functional, easy-to-explain feel to it and allows the creation of as many “Brands” as needed, each with their own logins, custom templates, custom lists, etc. The sole hangup was that it only supported billing for campaigns through PayPal, and we simply aren’t allowed to accept payment that way.

Internal payments here work through an in-house system and are issued with invoices, which I’ve heard are pieces of paper that people hand to each other and put in things called “filing cabinets.” I needed to figure out a way to do invoicing with Sendy, and I’m happy to say it wasn’t all that difficult.

The resulting Sendy Invoicing add-on, available on GitHub, allows an admin to check a new box labeled “Charge via invoice” under a brand’s payment settings. Users are then shown a customizable, printable invoice when they’d normally be sent to Paypal. Upon accepting an invoice, a copy is emailed to the payee for record-keeping.

A sample Sendy invoice

The whole project plugs right into the Sendy server, and after running an install script that uses a few broad regular expressions to insert two small blocks of code into Sendy’s files, it’s ready to run. Admittedly, it’s not an ideal integration. There isn’t really any plugin architecture or hooks that I could find, so it relies on modifying a couple of the core files, but I tried to make it as minimally invasive, straightforward, and well-documented as possible so that version updates don’t necessarily put it out of commission.

View the project on GitHub and transport your own Sendy server back to the 80s!

Mar 31, 2015

Why patch? Unlike WordPress, Drupal, and Joomla!, TERMINALFOUR is very particular about where content appears in a template. The concept of loops is still present, but handled in an unusual manner. You get one main loop, which pulls in all page content marked as the text/html format, and then a predefined set of additional loops […]

Continue reading...
Feb 14, 2015

My kitchen was missing something. I’d looked at clocks and artwork, but none of the options were simultaneously affordable and nerdy enough for my liking. What I needed was a way to incorporate my love of thrift store finds and coding into something functional, attractive, and unique that would cause my visitors to be delighted […]

Continue reading...
Fork me on GitHub