Simone Seagle

Simone Seagle

Independent Web and Educational Software Developer

Read More



Cat Watching a Spider

Mouse-over or touch/drag to interact with the spider. He'll follow your finger if you hover over the bottom part of the image. Or, view fullscreen.

About the Art

Cat Watching a Spider is a Japanese ink painting by Ōide Tōkō on silk from the 1890s. The Met doesn't have too much information about this piece for me to talk about, however. I was inspired by National Cat Day on Twitter to do a cat interactive, and the Japanese have a flair for depicting them. I wish I had more to say on the subject, but that's about it.

About the Programming

This works in a similar way to the Portrait Gallery interactive, where the eyes are a separate png behind the heads that follows something around. It uses pretty simple math to work:

    var dy = spider.y - (eyeLocations[1].y*scale);
    var dx = spider.x - (eyeLocations[1].x*scale);

    var angle = Math.atan2( dy, dx);

    var x = scale *(eyeLocations[1].x + 4 * Math.cos(angle));
    var y = scale *(eyeLocations[1].y + 2 * Math.sin(angle));

    catEyes.x = x;
    catEyes.y = y;

I do the same thing for the cat heads on the right and the left, and I show or hide one of the heads depending on which side of the cat the spider is on.

The spider moves by finding goal points and then trying to race to them, and for some reason it often overshoots. It's probably going too fast or something. Anyway, here's how I decide where the spider goes:

    function newSpiderPt() {

        if (trackLoc.y < 1416 * scale || spider.y < 1400 * scale) {
            // If the tracking location or the spider is out of bounds, get a random point in the box
            var x = Math.random() * size.width;
            var y = Math.random() * (size.height 
                         - 1416 * scale) + 1416 * scale;

        } else {
            // It goes to the tracking location if in bounds
            //console.log("tracking!", trackLoc);
            var x= trackLoc.x;
            var y = trackLoc.y;

        spiderGoalPt = {x: x, y:y};

        var angle = Math.atan2(y - spider.y, 
                               x - spider.x);

        var vx = (Math.random() + 0.7) * 
                    4 * Math.cos(angle);
        var vy = (Math.random() + 0.7) * 
                    4 * Math.sin(angle);

        spiderVelocity = {x:vx, y:vy};

        if (spiderVelocity.x < 0) {
        } else {
            spider.scale.set(scale * -1, scale);

And then I just update the spider with the given velocity.