From 5e97f43c10f04f24017fe1f652cf6bf37a59e226 Mon Sep 17 00:00:00 2001
From: Sami Samhuri Segments
@@ -82,7 +82,7 @@ e.g. \_\_DATA or \_\_TEXT
The code exposes some more details about segment commands, but should be easy enough to follow.
- +Finally, the Ruby code describing section structs:
- +2k, 61 lines. 10 of which are Google Analytics JavaScript. Let's glance at some of it.
- +
Standard html5 doctype, and a manifest for application caching.
@@ -35,7 +35,7 @@The interesting thing about the HTML is that without any JavaScript or CSS the document would be a completely blank white page (except for a strange looking share button w/ no title). Talk about progressive enhancement. Here's a look at the HTML:
- +Onward.
@@ -59,16 +59,14 @@ background.jpg 1024x946pxThe background is the blackboard itself, and is almost square at 1024x946. The cork border and light switch are there too. This is set as the background-image of the html element and is positioned at a negative x or y in order to centre it properly. CSS media queries are used to detect the screen's orientation. This way the same image is used for both orientations, clever.
- +
Just a canvas element positioned over the chalkboard using media queries. There's also an image element called "output" used to render an image for sharing.
- +
The dimmers background color is black at 67% opacity. The shade element fades in using -webkit-transition: on its visibility property while the dimmers use CSS3 transitions on their background. The dimmers are positioned using media queries as well, one on each side of the board. Interestingly their parent shade has a height and width of 0. Rather than each having a unique id they just have the class "dim" and the :nth-child pseudo-class selector is used to position them independently.
- +If you took a look at the HTML before you'll have noticed there's no shade class defined on the body element. Looks like they're using JavaScript to add the shade class to body, triggering the transitions to the visible shades and setting the dimmers backgrounds to black at the same time, causing the fading effect. The shade fades in while the ledge and share button fade out.
@@ -99,8 +96,7 @@ chalk-sprites.pngThere are 2 layers to the tools on the ledge. There are the images of the tools and their indicators, but also an anchor element for each tool that acts as targets to select them. When tools are select the indicators fade in and out using CSS3 transitions on opacity by adding and removing the class "active" on the tool.
- +There are pattern images for each colour of chalk, and one for the the eraser. The eraser "pattern" is the entire blackboard so erasing it doesn't look ugly. I love that kind of attention to detail.
@@ -126,7 +122,7 @@ chalk-sprites.png
- +
First we get a handle on all the elements and the canvas' 2d drawing context. I almost want to say views and controls as it really feels just like hooking up a controller and view in a desktop GUI app. Sometimes the line between dynamic web page and web app are blurred, not so here. Chalk is 100% app.
@@ -138,7 +134,7 @@ chalk-sprites.png- +
createPattern(name, callback) loads one of the pattern images, chalk-tile-*, and then creates a pattern in the drawing context and passes it to the given callback.
- +
Drawing is done by listening for touch events on the canvas element. An array of points to draw is initialized to a 1-element array containing null. Null values make the draw function break up the line being drawn by skipping the next point in the array. x and y coords are initialized in touchstart, points are appended to the points array in touchmove, and the touchend handler appends two points and null to the points array to end the line. I'm not sure why [x, y] is used as the points in the touchend handler rather than coords from the event. Please leave a comment if you know why!
- + +
When the light switch is touched (or clicked) the shade class on the body element is toggled. Nothing to it.
@@ -172,7 +169,7 @@ chalk-sprites.png- +
The share window is opened after a 10ms delay, just enough time for any drawing to be completed before rendering the image. The image is created by assigning the result of canvas' toDataURL() method to the output image element's src attribute.
Have fun drawing. Thanks to 37signals for a beautiful (and useful) example of a few modern web technologies.
- + + + I think this is a pretty neat hack and have not seen this technique anywhere else so I thought I'd share it. Maybe someone else will find it interesting or useful for their blog. How far it scales won't be a concern until I have thousands of posts. That sounds like a good problem for future Sami to solve should it arise.