Friday, February 10, 2017

live-server

A quick post today to talk about a nice Node.js tool called live-server. This app starts up a simple development http server to serve your web apps on your local computer. It also watches for changes to your pages and tells the browser to reload them automatically.

There was a time when you used to be able to just run your web apps straight from the file system. Those days are gone due to increased security with browsers. Also, if you want your page to make ajax calls that won't happen over the file protocol either, again due to security restrictions. So this is a really simple way to start up a server without having to configure something like IIS.

All you have to do is go to the folder in your file system where you want to serve files from and fire it up from a node command line. And just like that you're in business, it couldn't be any easier.

Monday, October 3, 2016

Debugging Touch Events on the Desktop

It can be a pain in the behind to debug touch events when developing your web application on the desktop. But I found this great setting in Chrome that makes it a whole lot easier. Just put this into the browser:

chrome://flags/#touch-events

If you set the value to "enabled" it will then emulate touch events whenever you are emulating a touch device. How do you emulate a touch device, you ask?

To emulate a touch device open up developer tool (F12) and click on the "Toggle Device Toolbar" button. At the time of this writing it's in the upper left corner of the window (it seems to move around with each new release so you may have to hunt for it).


When you turn this feature on it shows how the web page would look on that device, allows you to rotate the device, and allows you to choose from multiple devices including iPhone and Nexus or even define your own device.



When you have both of these features enabled you will start getting touch events instead of mouse events. To switch back to mouse events just turn device emulation off. You can leave the touch-events flag on, it won't hurt anything.

Code hard!

Thursday, August 25, 2016

HTML5 Canvas DrawImage Artifacts

I'm working on an HTML5 canvas game that requires smooth scrolling of images across the screen. The coordinates of the images are real numbers, not integers. The canvas can handle real number coordinates just fine and antialiases everything to make it look smooth. The problem is that it also sometimes produces some weird artifacts to be drawn.

What do I mean by artifacts? Artifacts are pixels that are drawn that you don't expect. In my case, for example, I have an image that has a significant amount of transparent pixels. When it's drawn at particular locations thin gray lines get drawn in some of the space where it should be transparent. It's not a lot, but it's noticeable.

So what can you do about it? There are a couple things, but they have their disadvantages. For one thing you can convert all of your coordinates to integers. One way to do this is with a little JavaScript trick; binary "or" the value with 0.

var x = 1.67;
x = x | 0; // x is now 1

That eliminates the artifacts because the images are drawn on whole pixel boundaries, so there's no need for the canvas to smooth out the image. The problem is that it makes your animations really choppy, especially if you have a lot of images scrolling next to each other.

Another thing I tried was to use Math.round() instead of just lopping off the fraction. I figured that would reduce the amount of choppiness. Unfortunately it didn't make much of a difference.

var x = 1.67;
x = Math.round(x); // x is now 2

But wait, there's one more. The canvas context has an imageSmoothingEnabled property you can set to true or false. By default it's true. I found that when you set it to false it's basically the same as using Math.round() above. It forces your images to be drawn on whole pixel boundaries. Which also produces choppiness.

context.imageSmoothingEnabled = false;
context.mozImageSmoothingEnabled = false;
context.webkitImageSmoothingEnabled = false;
context.msImageSmoothingEnabled = false;

So now we're right back where we started. In the end I decided not to use any of these methods and just stick with the occasional artifact being drawn. It looks crappy, but it only seems to happen at certain screen locations. In my case having smooth animations was far more important than the occasional artifact.

I think in most cases the choppiness wouldn't be such an issue and one of these techniques would work. It's up to you to determine what looks best. I would go with using imageSmoothingEnabled property because then you don't have to add any extra code to convert to an integer. Let the system do the work for you.

Code hard!