thingsinjars

  • 17 Nov 2011

    Poor man's touch interface

    Here's a little code snippet for today.

    While I was making the 3D CSS Mario Kart, I needed a simple, drop-in bit of code to handle touch interfaces. I looked through some old experiments and found a rough version of the code below. It was based on this KeyboardController by Stack Overflow user Bob Ince.

    It doesn't do anything clever. All it does is provide a simple way to attach functionality to touch events in different areas of the screen – top-left, top-center, top-right, middle-left, middle-center, middle-right, bottom-left, bottom-center, bottom-right. My apologies to any Brits for the spelling of centre as 'center'. It's the Internet, we have to.

    How to use

    Include this code:

    
    function TouchController(areas, repeat) {
      var touchtimer;
      document.onmousedown = document.ontouchstart = document.ontouchmove = function(e) {
        var position;
        e.preventDefault();
        e.touches = [{'clientX':e.pageX,'clientY':e.pageY}];
        switch(true) {
        case (e.touches[0].clientY<window.innerHeight/3) : 
            position = 'top';
            break;
        case (e.touches[0].clientY>(2*window.innerHeight)/3) : 
            position = 'bottom';
            break;
        default : 
            position = 'middle';
            break;
        }
        position+='-';
        switch(true) {
        case (e.touches[0].clientX<window.innerWidth/3) : 
            position += 'left';
            break;
        case (e.touches[0].clientX>(2*window.innerWidth)/3) : 
            position += 'right';
            break;
        default : 
            position += 'center';
            break;  
        }
    
        if (!(position in areas)) {
          return true;
        }
    
        areas[position]();
        if (repeat!==0) {
          clearInterval(touchtimer);
          touchtimer= setInterval(areas[position], repeat);
        }
        return false;
      };
      // Cancel timeout
      document.onmouseup = document.ontouchend= function(e) {
      clearInterval(touchtimer);
      };
    };
    

    Now, all you need to do to attach a function to a touch event in the top-left area of the screen is:

    TouchController({
      'top-left': function() { topLeftFunction();}
    }, 20);
    

    I use this for direction control in the Mario Kart experiment which maps exactly onto the cursor keys used for the normal control.

    TouchController({
      'top-left': function() {  // UP + LEFT
    				drawMap.move({y: 2}); 
    				drawMap.move({z: drawMap.z + 2}); 
    				drawMap.sprite(-1) 
    			  },
      'top-center': function() {  // UP
    				drawMap.move({y: 2}); 
    			  },
      'top-right': function() {  // UP + RIGHT
    				drawMap.move({y: 2}); 
    				drawMap.move({z: drawMap.z - 2}); 
    				drawMap.sprite(1) 
    			  },
    
      'middle-left': function() {  // LEFT
    				drawMap.move({z: drawMap.z + 2}); 
    				drawMap.sprite(-1) 
    			  },
      'middle-right': function() {  // RIGHT
    				drawMap.move({z: drawMap.z - 2});
    				drawMap.sprite(1) 
    			  },
    
      'bottom-left': function() {  // DOWN + LEFT
    				drawMap.move({y:  - 2}); 
    				drawMap.move({z: drawMap.z + 2}); 
    				drawMap.sprite(-1)  
    			  },
      'bottom-center': function() { 
    				drawMap.move({y:  - 2}); 
    			  },
      'bottom-right': function() {  // DOWN + RIGHT
    				drawMap.move({y:  - 2}); 
    				drawMap.move({z: drawMap.z - 2}); 
    				drawMap.sprite(1)  
    			  },
    }, 20);
    

    If you need anything clever or you need two or more touches, you should use something else. This is just a simple drop-in for when you're copy-paste coding and want to include touch-screen support.

    Javascript, Geek, Guides

  • 4 Aug 2011

    You must be able to read before you get a library card

    I like JavaScript. JS. ECMAScript. Ol' Jay Scrizzle as nobody calls it.

    I also like jQuery. jQ. jQuizzie. jamiroQuery. Whatever.

    Ignoring the stoopid nicknames I just made up, did you notice how I referred to JavaScript and jQuery separately? I didn't say "I like JavaScript, there are some really great lightbox plugins for it" just the same as I didn't say "I wish there was a way to do indexOf in jQuery".

    I'm regularly amazed at how many new (and some not-so-new) web developers either think they know JavaScript because they know jQuery or wish there was a way to do something in jQuery that they read about in an article about JavaScript. jQuery is a library written to make coding in JavaScript easier. It's made in JavaScript so you can say "jQuery is JavaScript" but only in the same way that "Simon is male". To confuse jQuery as all of JavaScript is the same as saying "Simon is all men" (don't worry, there's still only one of me).

    For most web site or web app development, I do recommend using a library. Personally, I've used jQuery and Prototype extensively and decided I prefer jQuery. Libraries are designed to make coding faster and more intuitive and they can be a great productivity aid. You can get a lot more done quicker. There is a downside, however.

    Downside

    If you're doing what the library was intended to help with, great. Slide this panel up, pop open a modal window, scroll to the bottom of the page and highlight that header. Brilliant. The difficulties come when you're either trying to do something the library wasn't intended to do or something nobody's thought of before or you're just plain doing something wrong. If you are fluent in your library of choice but don't know the JavaScript underpinnings, your usual debugging tools can only help you so far. There will come a point where there's an impenetrable black-box where data goes in and something unexpected comes out. Okay, it's probably still data but it's unexpected data.

    Don't let this point in the process be the discouragement. This is where the fun bit is.

    Learning to read

    Library authors are very clever groups of people. Often large groups. Reading through the unminified source of a library can be an awesomely educational experience as it's usually the culmination of many years best practice. If you want a nice introduction to some of the cool things in jQuery, for instance, check out these videos from Paul Irish:

    • http://paulirish.com/2010/10-things-i-learned-from-the-jquery-source/
    • http://paulirish.com/2011/11-more-things-i-learned-from-the-jquery-source/

    I've dug around in jQuery many, many times to try and figure out why something does or doesn't do what it should or shouldn't. The most detailed investigation was probably Investigating IE's innerHTML during which nothing was solved but I found out some cool stuff.

    Learning to write

    The best way to get your head around libraries is to write your own. Yes, there are literally millions of them (not literally) out there already but you don't need to aim for world dominance, that's not the point of writing your own. Start simply, map the dollar symbol to document.getElementById. Done. You've written a tiny library.

    function $(id){ 
        return document.getElementById(id);
    }

    Now you can add some more stuff. Maybe you could check to see if the thing passed to the $ is already an element or if it's a string. That way, you could be a bit more carefree about how you pass things around.

    function $(id){ 
      if(id.nodeType) {
        return id;
      } else {
        return document.getElementById(id);
      }
    }

    Add in a couple of AJAX methods, some array manipulation and before you know it, you've got a full-blown web development toolkit.

    If you're wanting a boilerplate to start your library off, I recommend Adam Sontag's Boilerplate Boilerplate.

    Here's your Library Card

    By now, you've rooted around in the jQuery undergrowth, dug through some of Moo's AJAX and pulled apart Prototype's string manipulation. You've written your own mini library, gotten a bit frustrated and wished you had a community of several thousand contributors to make it more robust. Now you're ready to start getting irked every time someone on Forrst asks if there's a jQuery plugin for charAt. Enjoy.

    This article is modified from a chapter in a book Andrew and I were writing a couple of years ago about web development practical advice. Seeing as we both got too busy to finish it, I'm publishing bits here and there. If you'd like to see these in book form, let me know.

    Geek, Opinion, Javascript, Guides

  • 18 Jul 2011

    Multi-user pages

    Whenever I'm away from home, my usual stream of random ideas tends to become more focused on projects involving sharing. Usually something about creating a connection between people where the interaction point is the Internet. This is what first inspired the now defunct MonkeyTV project back in 2007 or noodler.net in 2008 – both created while I was living in Tokyo as ways to connect to people back in Edinburgh.

    Until the beginning of August, I'm in Berlin finding somewhere to live while Jenni and Oskar are in Edinburgh packing up our flat (although, I'm not entirely sure Oskar is doing much more than drooling over packing boxes). The result of this is that I started to wonder about how to best show Jenni some of the flats I'm looking at remotely. What I figured I wanted was a way for us both to be looking at the same web page and for each of us to be able to point out things to the other. I tidied up my idea and posted it to the Made By Ideas site hoping that someone else would run off and make it so I could focus on apartment hunting.

    The inevitable happened, I couldn't let it lie:

    Multi-user page (installable bookmarklet).

    If you install that bookmarklet by draggin’ it to your bookmarks bar then launch it anywhere, your cursor position and how far you've scrolled the page will be sent to anyone else viewing the same page who has also launched it. If you launch it on this page just by clicking it just now, you'll see cursors from other people reading this post who've also clicked it.

    Technical

    This is built in node.js with socket.io.

    It heavily reuses Jeff Kreeftmeijer's multiple user cursor experiment but updated to use socket.io v0.7. I also used the socket.io 'rooms' feature to contain clients to a given window.location.href so that it could be launched on any page and interactions would only appear to users on that same page. I also removed the 'speak' feature to simplify things. I'm planning on talking via Skype when I'm using it. In theory, mouse events other than cursor coordinates and scroll could be shared – keyboard input, clicks, selects.

    The day after I built this, Christian Heilmann pointed out on twitter a different solution to the same problem. Browser Mirror uses the same technology (node + websockets) but instead of passing cursor positions, it passes the entire DOM of the page from the instigator's computer to their node relay and then out to any invited viewers. This approach gets round a lot of the problems and is probably a more robust solution, all in all. They also have an integrated chat feature.

    Warning

    The server side is running on a borrowed VPS. It's not even been daemonised using Forever so it might fall over and not come back up. Don't rely on this for anything, just think of it as a point of interest.

    The Code

    I'm not really going to do any further development with it but for interest, here's the node.js server, almost entirely Jeff Kreeftmeijer's work but updated for the latest socket.io

    var sys = require('sys'),
        http = require('http'),
        io = require('socket.io').listen(8000),
        log = sys.puts;
    
    io.sockets.on('connection', function (socket) {
    	socket.on('set location', function (name) {
    	    socket.set('location', name, function () { socket.emit('ready'); });
    		socket.join(name);
    	});
    	socket.on('message', function (request) {
    		socket.get('location', function (err, name) {
    			if(request.action != 'close' && request.action != 'move' && request.action != 'scroll') {
    				log('Invalid request:' + "\n" + request);
    				return false;
    			}
    			request.id = socket.id;
    			socket.broadcast.to(name).json.send(request);
    		});
    	});
    	socket.on('disconnect', function () {
    		socket.broadcast.json.send({'id': socket.id, 'action': 'close'});
    	});
    });

    And here's a bit of the client-side JS that I modified to connect via socket.io v0.7 (again, modified from Jeff Kreeftmeijer's):

    
    var socket = io.connect('http://yourserver.com', {port: 8000}),
    socket.on('connect', function() {
    	socket.emit('set location', window.location.href);
    	socket.on('message', function(data){
        if(data['action'] == 'close'){
          $('#mouse_'+data['id']).remove();
        } else if(data['action'] == 'move'){
          move(data);
        } else if(data['action'] == 'scroll'){
    			clearTimeout(noscrolltimeout);
    			disabled = true;
          scroll(data);
    			noscrolltimeout = setTimeout('disabled = false;',2000);
        };
      });
    });

    If you'd like to snoop around the code more, it's all available on the lab: Multi-user pages

    Props to Andrew for letting me use his server, by the way. It was enough hassle having to learn node for this little experiment, he saved me from having to build my own.

    Toys, Javascript, Ideas

  • 27 Jun 2011

    Knots

    Game design

    I had an idea around Christmas for a new game design. it was basically to be a single or multi-player game where you would tie knots in a piece of ‘string’. The single-player game would focus on discovering new patterns while the multi-player one would be a time-based challenge where each would tie a knot, pass it over to their opponent and the first to untie it would win.

    I built a basic prototype and had some fun inventing a few interesting knots (my favourite being ‘Yoda’) but didn't get round to doing anything with it. As I'm tidying up all my projects before immigrating to Germany, I figured I should just go ahead and put this out into the world.

    Knot v0.1

    Slightly technical bit

    The system is built using an invisible 3x3 grid and 4 quadratic curves. The curves' start, control and end points are the centre of a tile. When you move a tile, it basically swaps position with the tile nearest where you drop it. This can also be done with multiple tiles simultaneously if you're on a multi-touch device. You can see the tiles if you enable debug mode. You can also switch between the two colour schemes it has at the moment.

    Yoda in Knot form
    Yoda Knot

    The only addition I've made to it since Christmas was to add on a system to allow players to save knots back into the system. I've only built in 22 patterns so if you make a nice, interesting or funny one, give it a recognisable name (nothing too rude, please) and save it, it will then be available to everybody who plays with it. You can also set whether the pattern is to count as ‘matched’ when rotated 90°, 180°, flipped vertically or flipped horizontally. Calculating the isomorphisms (when two knots look the same to the viewer but aren't necessarily the same to the computer) was probably the trickiest bit of the system.

    Go, make.

    If you're interested in taking the idea further, grab the code from GitHub and make something from it. The usual rules apply, if you make something from it that makes you a huge tonne of neverending cash, a credit would be nice and, if you felt generous, you could always buy me a larger TV.

    Knot v0.1

    Javascript, Development, Geek, Ideas, Toys

  • newer posts
  • older posts

Categories

Toys, Guides, Opinion, Geek, Non-geek, Development, Design, CSS, JS, Open-source Ideas, Cartoons, Photos

Shop

Colourful clothes for colourful kids

I'm currently reading

Projects

  • Awsm Street – Kid's clothing
  • Stickture
  • Explanating
  • Open Source Snacks
  • My life in sans-serif
  • My life in monospace
Simon Madine (thingsinjars)

@thingsinjars.com

Hi, I’m Simon Madine and I make music, write books and code.

I’m the Engineering Lead for komment.

© 2025 Simon Madine