O'Reilly

Create xkcd-Style Comics with Comix

By on  

Mad Men Comic

Everyone loves the epic comic xkcd.  These comics aren't usually masterclasses of artwork but expressions of whit, usually of a tech-related subject.  I've always thought I could eventually create witty comics but never had the illustration skills to bring them to fruition.  Luckily an incredible tool called cmx.js has come along.  Comix I/O allows developers to create xkcd-style comics using a reasonable SVG API.

Getting Comix

You can download or clone Comix from the GitHub project page.  The project uses npm and bower to install dependencies, and a simple grunt command to launch Comix for hacking:

# Install
git clone git://github.com/darwin/cmx.js.git
cd cmx.js
npm install
bower install

# Launch!
cd cmx.js
grunt server

# ...
# yeoman will open browser with editor and sample.html (http://localhost:3501)

A few moments and you're up and running!

Hacking Comix

Comics are created in one of two ways:  direct source code manipulation within your text editor or by using Comix's awesome in-browser comic editor (powered by ACE).  There are about a half-dozen tags in play:

  • scene - The outer box / container frame
  • label - Box containing text that overlaps the frame border (usually at the top left)
  • tspan - Text containers with x and y attributes for text label stacking
  • drawing - A method to create basic drawings (custom shapes) within the a scene (just as you would in SVG)
  • actor - A representation of a stick figure in the scene, customized by the pose attribute
  • bubble - A container for text

Each element has its own meaningful attributes -- consult the documentation for further explanation as this API is sure to evolve.

Creating a Comic

With Comix launched via grunt, it's time to edit the example comic or create one from scratch.  The Comix editor provides an ACE editor to do in-browser code editing; you can also use your mouse to reposition and rotate actors within the scene.  Here's the code for a comic I created:

<scene id="scene1">
  <label t="translate(0,346)">
    <tspan x="0" y="0em">9 a.m. Monday Morning</tspan>
  </label>
  <drawing t="translate(0,31)">
    <line stroke="green">
      <point x="0" y="0"></point>
      <point x="250" y="20"></point>
    </line>
  </drawing>
  <actor t="translate(71,19) rotate(-2)" pose="-11,9|-5,117|-11,99|-11,89|-11,79|-11,59|-16,34|-21,9|-6,34|-1,9|-18,79|-18,59|-6,79|-1,59">
    <bubble t="translate(9,11)" pose="0,0|-20,10|-81,49|19,66|-21,145|-73,109">
      <tspan x="0" y="-3em">Just got a call from</tspan>
      <tspan x="0" y="-2em">the client</tspan>
      <tspan x="0" y="2em">They want a</tspan>
      <tspan x="0" y="3em">new design by </tspan>
      <tspan x="0" y="4em">the end of day</tspan>
    </bubble>
  </actor>
  <actor t="translate(159,15)" pose="28,1|30,109|28,91|28,81|28,71|28,51|18,31|18,1|33,26|38,1|23,71|18,51|38,71|38,51">
    <bubble t="translate(-2,-9)" pose="0,0|-14,24|-36,69|27,28|8,72|-35,93">
      <tspan x="0" y="0em">you can't</tspan>
      <tspan x="0" y="1em">be serious</tspan>
    </bubble>
  </actor>
</scene>

<scene id="scene2">
  <drawing t="translate(0,31)">
    <line stroke="green">
      <point x="0" y="0"></point>
      <point x="250" y="20"></point>
    </line>
  </drawing>
  <actor t="translate(71,19) rotate(-2)" pose="-11,9|-1,114|-11,99|-11,89|-11,79|-11,59|-16,34|-21,9|-6,34|-1,9|-18,79|-18,59|-6,79|13,83">
    <bubble t="translate(-3,0)" pose="0,0|-12,22|-83,104|45,21|-37,182|-58,162">
      <tspan x="0" y="-2em">Yep.
      <tspan x="0" y="0em">They want responsive</tspan>
      <tspan x="0" y="1em">design, async loading,</tspan>
      <tspan x="0" y="2em"><tspan fill="blue">(keyword)</tspan>, <tspan fill="blue">(keyword)</tspan>,</tspan>
      <tspan x="0" y="3em"><tspan fill="blue">(keyword)</tspan> ...</tspan>
      
      <tspan x="0" y="5em">This is</tspan>
      <tspan x="0" y="6em">all easy,</tspan>
      <tspan x="0" y="7em">right?!</tspan>
    </tspan></bubble>
  </actor>
  <actor t="translate(159,15)" pose="28,1|30,109|28,91|28,81|28,71|28,51|18,31|13,1|33,26|38,1|23,71|18,51|38,71|38,51">
    <bubble t="translate(-2,-9)" pose="0,0|7,33|14,66|-63,30|-52,62|-94,113">
      <tspan x="0" y="1em">... Let me go back</tspan>
      <tspan x="0" y="2em">to my desk and</tspan>
      <tspan x="0" y="3em">draft that.</tspan>
    </bubble>
  </actor>
</scene>

<scene id="scene3">
  <drawing t="translate(0,31)">
    <line stroke="green">
      <point x="0" y="0"></point>
      <point x="250" y="20"></point>
    </line>
  </drawing>
  <label t="translate(0,346)">
    <tspan x="0" y="0em">Moments later ...</tspan>
  </label>
  <actor t="translate(208,20) rotate(2)" pose="-41,48|-10,105|0,88|0,78|0,68|0,48|-5,23|-10,-2|5,23|10,-2|-11,70|-4,54|17,86|-4,110">
    <bubble t="translate(-2,-9)" pose="1,35|-12,59|-28,87|-85,31|-98,114|-164,105">
      <tspan x="0" y="-1em">Why every Monday morning?</tspan>
      <tspan x="0" y="1em">Oh, right, <tspan fill="red">Mad Men</tspan></tspan>
      <tspan x="0" y="2em">last night.</tspan>
      <tspan x="0" y="4em">Not sure who was</tspan>
      <tspan x="0" y="5em">drunker; the rep</tspan>
      <tspan x="0" y="6em">this morning</tspan>
      <tspan x="0" y="7em">or the client</tspan>
      <tspan x="0" y="8em">last night</tspan>
    </bubble>
  </actor>
</scene>

The code above translates to the following visual gem:

Mad Men Comic

The Comix project has awesome written all over it.  Creating a comic from scratch will be a task in the short term so experiment with editing the existing comic and see what cleverness results.  Be sure to post any comics you create within the comment section below as we all need our true genius to be seen!

Track.js Error Reporting

Upcoming Events

Recent Features

Incredible Demos

  • HTML5 Placeholder Styling with CSS

    Last week I showed you how you could style selected text with CSS. I've searched for more interesting CSS style properties and found another: INPUT placeholder styling. Let me show you how to style placeholder text within INPUTelements with some unique CSS code. The CSS Firefox...

  • Using Dotter for Form Submissions

    One of the plugins I'm most proud of is Dotter. Dotter allows you to create the typical "Loading..." text without using animated images. I'm often asked what a sample usage of Dotter would be; form submission create the perfect situation. The following...

Discussion

  1. Wow, that’s a lot of code just to create a comic strip, what happened to the balance between images and code. Wouldn’t it be easier to create a comic strip in photoshop, leave enough room to add font text so It can be changed using web fonts.

    This would ultimately be quicker and use a lot less code. Resulting in faster loading pages. Coding is all every good, but trying to create everything in code is plan crazy. Again, everything is about Balance.

  2. Awesome. Let me know when they come out with a way of animating that. Likely through another JS library. Could even see something like flip-book style.

  3. Take a look at StripThis! :p

    http://www.kesiev.com/stripthis/

  4. MaxArt

    Well… ladies and gentlemen, this is pure WIN!

    *slow clap*

  5. Jay

    wit, not whit (bit, particle, iota or jot).

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • OâReilly Velocity Conference â New York

    My favorite front-end conference has always been O'Reilly's Velocity Conference because the conference series has focused on one of the most undervalued parts of client side coding:  speed.  So often we're so excited that our JavaScript works that we forget that speed, efficiency, and performance are just as important. The next Velocity...

  • Free Download: Font Bundle Featuring 17 Incredible Typefaces

    The only thing we love more than a good font, is a good free font. So we’ve combed the Web for some of our favorite free fonts, and gathered them here in a single download. You’ll find a variety of useful typefaces, from highly geometric designs...

  • OâReilly Velocity Conference â Amsterdam

    My favorite front-end conference has always been O'Reilly's Velocity Conference because the conference series has focused on one of the most undervalued parts of client side coding:  speed.  So often we're so excited that our JavaScript works that we forget that speed, efficiency, and performance are just as important. The next Velocity...

  • CanIUse Command Line

    Every front-end developer should be well acquainted with CanIUse, the website that lets you view browser support for browser features.  When people criticize my blog posts for not detailing browser support for features within the post, I tell them to check CanIUse:  always up to date, unlike...

  • Generating Alternative Stylesheets for Browsers Without @media

    If your CSS code is built with a mobile-first approach, it probably contains all the rules that make up the "desktop" view inside @media statements. That's great, but browsers that don't support media queries (IE 8 and below) will simply ignore them, ending up getting the...