Close
Simone Seagle

Simone Seagle

Independent Web and Educational Software Developer

Read More

Search

Play

Winter Scene in Moonlight

Mouse-over or touch/drag to interact with Winter Scene in Moonlight. Or, view fullscreen.

About the Art

Winter Scene in Moonlight, painted in 1869, is the first known watercolor landscape painted by Henry Farrer. Farrer was the younger brother of another artist (Thomas Farrer) who specialized in painting landscapes as well, but usually worked in oils. Farrer is one of only a few artists at the time to work in watercolors almost exclusively. "Winter Scene in Moonlight" likely represents a location in Brooklyn.

About the Programming

I've added animation to three components of the painting - the clouds, the moon, and the land. I'll go through them.

  1. Clouds - Those are pretty simple. I add them to the stage behind the foreground and they simply update their x position so they float by. Interaction either slows them down or speeds them up depending on the side.

  2. Moon - The moon follows an elliptical path through the sky. It has an angular velocity that can be effected by interaction. In order to get the moon to follow the elliptical path, I consulted Wikipedia's Ellipse page and then wrote the following code:

    // Ellipse parameters
    var a = size.width * .8; // semi-major axis
    var b = size.height * .65; // semi-minor axis
    var cx = size.width; // center x
    var cy = 870 * scale; // center y

    function updateMoon() {
        // Too impatient to let the moon do a full cycle
        if (moonAngle > maxAngle) {
            moonAngle = minAngle;
        }

        var interactPhi = 0;
        if (trackLoc.x > 0) {
            var dist = distance(trackLoc.x, trackLoc.y,
                                moon.x, moon.y);
            if (dist < maxDist) {
                interactPhi = (maxDist - dist)/(700 *maxDist) 
                    * Math.sign(moon.x - trackLoc.x);
            }
        }

        moonAngle += moonPhi + interactPhi;

        // Parametric equations as per the link above
        var u = Math.tan(moonAngle/2);
        moon.x = a * (1 - u*u)/(u*u + 1) + cx;
        moon.y = 2 * b * u / (u*u + 1) + cy;

    }
  1. Land - The land darkens and lightens in response to the position of the moon. I have three pngs of shadows that I made in Photoshop, and I also change the overall tint. The pngs of shadows are simply faded in and out, so I'm omitting that code. The tint is a little more interesting.
// Linear interpolation of the tint on the foreground (y = mx + b)
var minimumTint = 88;
var tintM = (255 - minimumTint)/(3.9 - Math.PI);
var tintB = 255 - tintM * 3.9;

function updateTint() {
    var targetTint = minimumTint;
    if (moonAngle > 3.9) {
        targetTint = 255;
    } else if (moonAngle >= Math.PI) {
        // Use the linear interpolation (y is the target tint and x is the angle of the moon)
        targetTint = tintM * moonAngle + tintB;
    }

    var diff = targetTint - foreground.targetTint;
    // Tween the difference between the tint we have and the tint that we want
    if ( Math.abs(diff) > 0.5) {
        foreground.targetTint += diff/40;

        // get a tint and turn it into hexadecimal
        var tint = Math.floor(foreground.targetTint).toString(16);
        var hex = '0x' + tint + tint + tint;
        // The tint is a shade of gray, so it darkens the whole land
        foreground.tint = hex;
    }
}