Repository for Ideas & Research
Open Source GIS, Hydrologic Modeling, Optimization

HTML5

1   Canvas animation

http://www.html5canvastutorials.com/advanced/html5-canvas-animation-stage/

Uniqki code
#regex /^/#html /
<div>x: <span id="x"></span>, y: <span id="y"></span></div>
<div>vx: <span id="vx"></span>, vy: <span id="vy"></span></div>
<div>ax: <span id="ax"></span>, ay: <span id="ay"></span></div>
<canvas id="canvas-bouncing-ball" width="500" height="500"></canvas>
<script>
var canvas = document.getElementById('canvas-bouncing-ball');
var context = canvas.getContext('2d');
var ball = {
  radius: 0,
  x: {
    pos: 0,
    vel: 0,
    acc: 0.0*9.81,
    loss: 1, // loss from impact
    loss2: 0.01, // loss in x from y impact
  },
  y: {
    pos: 0,
    vel: 0,
    acc: 0.1*9.81,
    loss: 1, // loss from impact
    loss2: 0.01, // loss in y from x impact
  }
}
var Draw = {
  rectangle: function (x, y, w, h) {
    context.beginPath();
    context.rect(x, y, w, h);
    context.fillStyle = '#8ED6FF';
    context.fill();
    context.lineWidth = 2;
    context.strokeStyle = 'black';
    context.stroke();
  },
  circle: function(x, y, r) {
    context.beginPath();
    context.arc(x, y, r, 0, 2 * Math.PI, false);
    context.fillStyle = 'green';
    context.fill();
    context.lineWidth = 2;
    context.strokeStyle = '#003300';
    context.stroke();
  }
}

function move(coor1, coor2, min, max) {
  coor1.vel += coor1.acc;
  if (coor1.pos + coor1.vel < min) {
    // loss in coor2 from coor1 impact
    if (Math.abs(coor2.vel) > coor2.loss2)
      coor2.vel = Math.sign(coor2.vel) * (Math.abs(coor2.vel) - coor2.loss2);
    else
      coor2.vel = 0;
    var t = (coor1.pos - min) / coor1.vel; // fraction of time before impact
    // loss from impact
    if (Math.abs(coor1.vel) > coor1.loss)
      coor1.vel = -Math.sign(coor1.vel) * (Math.abs(coor1.vel) - coor1.loss);
    else
      coor1.vel = 0;
    coor1.pos = min + coor1.vel * (1 - t); // remaining travel after impact
  } else if (coor1.pos + coor1.vel > max) {
    // loss in y from impact
    if (Math.abs(coor2.vel) > coor2.loss2)
      coor2.vel = Math.sign(coor2.vel) * (Math.abs(coor2.vel) - coor2.loss2);
    else
      coor2.vel = 0;
    var t = (max - coor1.pos) / coor1.vel; // fraction of time before impact
    // loss from impact
    if (Math.abs(coor1.vel) > coor1.loss)
      coor1.vel = -Math.sign(coor1.vel) * (Math.abs(coor1.vel) - coor1.loss);
    else
      coor1.vel = 0;
    coor1.pos = max + coor1.vel * (1 - t); // remaining travel after impact
  } else {
    coor1.pos += coor1.vel;
  }
}

function animate() {
  if (ball.x.vel == 0 && ball.y.vel == 0) {
    ball.radius = Math.random() * ((canvas.width - 6) * 0.5 - 1) + 1;
    ball.x.pos = Math.random() * (canvas.width - 2 * ball.radius - 4) + ball.radius + 2;
    ball.y.pos = Math.random() * (canvas.height - 2 * ball.radius - 4) + ball.radius + 2;
    ball.x.vel = Math.random() * 100 - 50;
    ball.y.vel = Math.random() * 100 - 50;
  }

  move(ball.x, ball.y, ball.radius + 2, canvas.width - ball.radius - 2);
  move(ball.y, ball.x, ball.radius + 2, canvas.height - ball.radius - 2);

  context.clearRect(0, 0, canvas.width, canvas.height);
  Draw.rectangle(1, 1, canvas.width - 2, canvas.height - 2);
  Draw.circle(ball.x.pos, ball.y.pos, ball.radius);

  window.requestAnimationFrame(animate);

  document.getElementById('x').innerHTML = ball.x.pos.toFixed(3);
  document.getElementById('y').innerHTML = ball.y.pos.toFixed(3);
  document.getElementById('vx').innerHTML = ball.x.vel.toFixed(3);
  document.getElementById('vy').innerHTML = ball.y.vel.toFixed(3);
  document.getElementById('ax').innerHTML = ball.x.acc.toFixed(3);
  document.getElementById('ay').innerHTML = ball.y.acc.toFixed(3);
}
animate();
</script>
#noregex /^/
Uniqki output
x: , y:
vx: , vy:
ax: , ay:

2   Web Socket

2.1   Web Socket Screencasting

This .NET program takes the screen shot of a small window of the desktop and outputs pixel information every 1 second.

using System;
using System.Drawing;
using System.Threading;

namespace WebSocketScreencast
{
    class Program
    {
        static void Main(string[] args)
        {
            // https://stackoverflow.com/a/5049138
            using (Bitmap bmp = new Bitmap(100, 100))
            {
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    while (true)
                    {
                        g.CopyFromScreen(0, 0, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy);
                        for (int x = 0; x < 100; x++)
                        {
                            for (int y = 0; y < 100; y++)
                            {
                                Color color;

                                color = bmp.GetPixel(x, y);
                                Console.WriteLine("{0} {1} {2} {3} {4} {5}", x, y, color.R, color.G, color.B, color.A);
                            }
                        }
                        Console.WriteLine("draw");
                        Thread.Sleep(1000);
                    }
                }
            }
        }
    }
}

This comandline starts the web socket daemon to serve screencasting using the above .NET program.

websocketd.exe --staticdir=. --port 8000 cmd /c WebSocketScreencast.exe

The following HTML5 code receives the pixel information that the web socket daemon sends and draws it on the canvas.

<canvas id="canvas" width="500" height="500"></canvas>
<script>
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var imageData = context.createImageData(100, 100);

function setPixel(imageData, x, y, r, g, b, a) {
  var index = (x + y * imageData.width) * 4;
  imageData.data[index+0] = r;
  imageData.data[index+1] = g;
  imageData.data[index+2] = b;
  imageData.data[index+3] = a;
}

function drawImage(imageData, x, y) {
  context.putImageData(imageData, x, y);
}

var ws = new WebSocket('ws://localhost:8000/');
ws.onmessage = function(event) {
  var data = event.data;
  if (data == "draw") {
    drawImage(imageData, 0, 0);
  } else {
    var d = data.split(" ");
    x = parseInt(d[0]);
    y = parseInt(d[1]);
    r = parseInt(d[2]);
    g = parseInt(d[3]);
    b = parseInt(d[4]);
    a = parseInt(d[5]);
    setPixel(imageData, x, y, r, g, b, a);
  }
};
</script>

3   SVG.js demo

Uniqki code
#regex /^/#html /
<input type="text" value="Dragon----- - - - ->" placeholder="Type text here...">
<div id="drawing"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.7.1/svg.min.js"></script>
<script>
var input = document.querySelector('input[type=text]')
var draw = SVG('drawing').viewbox(0, 0, 300, 140)
var text = draw.text(function(add) {
	add.tspan( input.value )
})

text
	.path('M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80')
	.animate(1000, '<>')
	.plot('M10 80 C 40 150, 65 150, 95 80 S 150 10, 180 80')
	.loop(true, true)

input.addEventListener('keyup', updateText(text))

function updateText(textPath) {
	return function() {
		textPath.tspan(this.value)
	}				
}
</script>
#noregex /^/
Uniqki output