Over the few weeks I’ve been working on a Canvas based side project (more on that soon) that involved cutting a mask out of a source image and placing it on a Canvas. In Photoshop parlance, this would be similar to creating a clipping mask and then using it to extract a path from the image into a new layer. So visually, we’re looking to achieve something similar to:
At face value, it looks like doing this with Canvas is pretty straightforward using the getImageData function. Unfortunately, if you look at the parameters that function accepts it’ll only support slicing out rectangular areas which isn’t what we’re looking to do. Luckily, if you look a bit further in the docs it turns out Canvas supports setting globalCompositeOperation which allows you to control how image data is drawn onto the canvas. The idea is to draw the mask on a canvas, turn on the “source-in” setting, and then draw on the image that you want to generate the slice off. The big thing to note here is that putImageData isn’t effected by the globalCompositeOperation setting so you have to use drawImage to draw the mask and image data.
So concretely how do you do this? Well check it out:
The code is running over at http://symf.setfive.com/canvas_puzzle/grass.html if you want to see it in action.
Anyway, happy canvasing!
This morning, I was implimenting an AJAX “profile photo uploader” using the new HTML5 File object. With the new File object, you’re able to do a file upload using an AJAX request instead of requiring a form submission to upload the file.
This works great with the caveat that there still needs to be a <input type="file" /> on the page in order for the user to select a file. This presents a UI/UX issue because there isn’t much leway in styling HTML file inputs and consequently the input was looking out of place on our form.
After poking around for a bit I ran across jQuery File Upload which seems to solve this problem. Inspecting the CSS, the CSS “masks” the file input by using a CSS3 “transform” and then setting the opacity value to 0 so the input is visually hidden.
Implimenting the transform+opacity trick was pretty straightforward but the issue I ran into was that I couldn’t get the mouse cursor being displayed to appear as a “hand”, I kept seeing the “text selector” cursor. I had changed the transform being used and unfortunately the jQuery File Upload CSS didn’t have any comments explaining what it was actually doing to get the cursor part of the CSS to work.
It turns out what you want to do is use the CSS3 “transform” function to skew the file input so that the “Browse” button is covering the element that you want to use to trigger the “select file” behavior and then just set the opacity to 0 to make the file input invisible.
You can see the progression here http://jsfiddle.net/jpvWh/2/ The first container has no styling applied on the file input, the second one has the “Browse” button skewed into the right spot and finally the last one has the opacity set to 0. If you change the “cursor” CSS directive on the file input you’ll notice that in the 2nd and 3rd examples the cursor will change wherever your mouse is in the container. Also, you’ll notice that if you click anywhere in the container the “select a file” dialog will get triggered as expected.
Anyway, as always comments/feedback/questions are welcome!
Posted In: Demo
Preface: This is a bad idea with untested code. If you deploy it on a production server bad things will happen.
I sniped the browser detection code from Quirksmode and it seems to work fairly well. The rest of the code is below:
The trickiest part of getting this to work was Adobe’s insane rules for allowing their Socket classes to connect to servers. In order for the client to successfully connect to the server you need to serve a XML policy file from port 843. Additionally, this file can’t be served by a HTTP server but must be a custom server that only spits back the file along with a null carriage return. A detailed description of this abortion is here http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html
This really posses two problems. One, you need to be running some random “policy file server” for Flex sockets to be of any use. And two, since 843 is a privileged port, this server can’t be started by a regular user.
Anyway, I tested this on IE7+ and it seemed to work decently well. Per the warning on top I don’t want to leave this running on a live server anywhere.
If you want to get it to actually run, do the following:
What’s in the box:
Credits: I borrowed the WebWorker SHA1 implementation from John Resig who adapted it from Ray C Morgan.
So here is another crazy idea. Instead of executing the WebWorker code on the server, would it be possible to dynamically make the WebWorker code re-entrant using setTimeout() on the client where loop structures exist?
Posted In: Demo