Doors doors doors, c'mon down to the door store! The challenge is twofold:

Make a program that builds a door. ASCII, HTML or otherwise

Make the door functional. Opens and closes

Either open-able through input or interaction!


Non-functional door +5 points.
Just a open-able door +10 points.
Interactive door +15 points.
Fancy door +20 points. This means revolving,bifold etc
Animated +20 points.
&lt;100 characters +50 points.
-100 points for using a program specifically designed for drawing or animation. 


If you have criteria suggestions leave them in the comments.

Non-functional open door example:

&lt;?php
$idiots_in_room=true;

if($idiots_in_room)
{

$count=20;
$count2=7;
for($i=0;$i&lt;$count;$i++)
{

if($i==0)
{
echo str_repeat("-",10);
if($i==0){echo ".";}
echo "\n";
}
elseif($i==9)
{
echo str_repeat("-",10);
echo str_repeat("Â ",7)."o"."|";
echo "\n";
}
elseif($i&lt;=9)
{

echo str_repeat("-",1).str_repeat("Â ",8).str_repeat("-",1);

echo ($i&lt;5) ? str_repeat("Â ",$i*2)."\\" : str_repeat("Â ",8)."|";
echo "\n";
}
elseif($i&lt;=14)
{
if($i&gt;9){echo str_repeat("Â ",$i)."\\";}
echo str_repeat("Â ",$count2--)."|";
echo "\n";
}

}
}


Example Output:

----------.
-        -  \
-        -    \
-        -      \
-        -        \
-        -        |
-        -        |
-        -        |
-        -        |
----------       o|
          \       |
           \      |
            \     |
             \    |
              \   |
JavaScript, 4380 characters, 65(?) points

ASCII? Check. HTML? Check. Is a door? Check. Openable door? Check. Interactive? Check. Fancy? Double doors with properly positioned hinges, I hope that counts. Animated? Check. Under 100 characters? Ha. Not using facilities intended for drawing? Check.

Live demo. (Note: In my testing with Firefox, clicking the doors more than once doesn't work — for some reason the event handler doesn't fire again and I'm baffled as to why; pointing out what I did wrong would be welcome. Though, you might want to run this in Chrome anyway for decent JS performance.)

&lt;title&gt;Door&lt;/title&gt;
&lt;pre onmouseup="turn();" style="display: table; margin: auto; font-family: 'Monaco', monospace; font-size: 0.6em; line-height: 0.7em;"&gt;
&lt;/pre&gt;
&lt;p&gt;Click doors to open or close.&lt;/p&gt;
&lt;script&gt;

  // Appearance of hit surface - global used to avoid allocating a record to return
  var mat;

  // Scene construction tools
  function box(size,ms) {
    return function (x, y, z) {
      var vdist0 = Math.abs(x) - size[0];
      var vdist1 = Math.abs(y) - size[1];
      var vdist2 = Math.abs(z) - size[2];
      mat = vdist0 &gt; vdist1 &amp;&amp; vdist0 &gt; vdist2 ? ms[0] :
            vdist1 &gt; vdist0 &amp;&amp; vdist1 &gt; vdist2 ? ms[1] :
            ms[2];
      return Math.max(vdist0, vdist1, vdist2);
    };
  }
  function translate(vec, obj) {
    var dx = vec[0];
    var dy = vec[1];
    var dz = vec[2];
    return function (x, y, z) { return obj(x - dx, y - dy, z - dz); };
  }
  function mirror(obj) {
    return function (x, y, z) { return obj(-x, y, z); };
  }
  function spin(obj) {
    return function (x, y, z) {
      var a = Date.now() / 1000;
      var s = Math.sin(a);
      var c = Math.cos(a);
      return obj(
        x * c + z * s,
        y,
        x * -s + z * c
      );
    };
  }
  function doorturn(obj) {
    return function (x, y, z) {
      var a = pos;
      var s = Math.sin(a);
      var c = Math.cos(a);
      return obj(
        x * c + z * s,
        y,
        x * -s + z * c
      );
    };
  }
  function rotx(a, obj) {
    return function (x, y, z) {
      var s = Math.sin(a);
      var c = Math.cos(a);
      return obj(
        x,
        y * c + z * s,
        y * -s + z * c
      );
    };
  }
  function roty(a, obj) {
    return function (x, y, z) {
      var s = Math.sin(a);
      var c = Math.cos(a);
      return obj(
        x * c + z * s,
        y,
        x * -s + z * c
      );
    };
  }
  function union(as, bs) {
    return function (x, y, z) {
      var a = as(x, y, z); var am = mat;
      var b = bs(x, y, z);
      if (a &lt; b) {
        mat = am;
        return a;
      } else {
        return b;
      }
    };
  }

  // Display parameters
  var vw = 80, vh = 80;
  var timestep = 1/30;

  // Scene
  var wallhwidth = 30;
  var wallhheight = 35;
  var wallmat = [";", "\u2014", ":"];
  var dhwidth = 10;
  var dhheight = 20;
  var hthick = 2;
  var door = translate([-dhwidth*2, 0, 0], doorturn(translate([hthick, 0, dhwidth], box([hthick, dhheight, dhwidth], [".", "\u2014", "|"]))));
  var doors = union(door, mirror(door));
  var wall = union(
    union(
      translate([dhwidth*2+wallhwidth, 0, -hthick], box([wallhwidth, wallhheight, hthick], wallmat)),
      translate([-dhwidth*2-wallhwidth, 0, -hthick], box([wallhwidth, wallhheight, hthick], wallmat))),
    translate([0, wallhheight-(wallhheight-dhheight)/2, -hthick], box([dhwidth*2, (wallhheight-dhheight)/2, hthick], wallmat)));
  var floor = translate([0, -dhheight - 1.1, 0], box([100, 1, 100], ["/","/","/"]));
  var sill = translate([0, -dhheight - 1, -hthick], box([dhwidth*2, 1, hthick], ["\\","%","\\"]));
  var sbox = translate([0, 0, -12], spin(box([8, 8, 8], ["x", "y", "z"])))
  var scene = union(sbox, union(union(wall, doors), union(floor, sill)));
  var view = translate([vw/2, vh/2, -100], rotx(0.2, roty(-0.6, scene)));

  // Animation state
  var pos = -Math.PI/2;
  var dpos = 0;
  var interval;

  // Main loop function
  function r() {
    // Update state
    pos += dpos * timestep;
    if (Math.abs(pos) &gt;= Math.PI/2) {
      dpos = 0;
      pos = Math.PI/2 * pos / Math.abs(pos);
      if (pos &lt; 0) { // no animation needed
        clearInterval(interval); interval = undefined;
      }
    }

    // Render scene
    var t = [];
    for (var y = vh - 1; y &gt;= 0; y--) {
      for (var x = 0; x &lt; vw; x++) {
        var z = 0, distance;
        while ((distance = view(x,y,z)) &gt; 0.12) {
          z -= distance;
          if (!isFinite(z) || z &lt; -1000) {
            mat = " ";
            break;
          }
        }
        t.push(mat);
      }
      t.push("\n");
    }
    document.getElementsByTagName("pre")[0].textContent = t.join("");
  }

  // Click handler
  function turn() {
    if (dpos !== 0) {
      dpos *= -1;
    } else {
      dpos = (pos &lt; 0 ? 1 : -1) * 2.3;
    }
    if (!interval) {
      interval = setInterval(r, timestep*1000);
    }
  }

  // Render initial state
  r();
&lt;/script&gt;


When closed, the doors look like this: