Looping – js1k 2018 post mortem

Screen Shot 2018-03-08 at 11.31.21
For this year’s js1k I wanted to build a simple ray-tracer to see both how much could I fit in 1k and the performance of js.
I started by adding a very simple (trivial) camera implementation and adding a sphere primitive:
shim_01
Results where not mind blowing but, hey, that was a start. Code was pretty simple:

  //w = canvas width
  //h = canvas height
  //F = pixels skipped. At F=1 we would compute the real value each pixel, at 2, we would compute at every 2 pixels, and so on..
// where the camera is and where the camera is looking
origin=[0,0,-1000]
dst  =[0,0,1000]
fov = 90
...
  // compute direction vector and horizontal & vertical vectors (hv & vv respectively)
  cd=[dst[0]-origin[0],
      dst[1]-origin[1],
      dst[2]-origin[2]]
  u(cd)
  alpha = Math.PI*fov/360.0
  focaldist = w * Math.cos(alpha)/(2*Math.sin(alpha))
  cv=[origin[0]+cd[0]*focaldist,
      origin[1]+cd[1]*focaldist,
      origin[2]+cd[2]*focaldist]
  hv=[-cd[2],0,cd[0]]
  vv=x(hv, cd)
  // compute the view vector
  v=[cv[0]-vv[0]*h2-hv[0]*w2-origin[0],
     cv[1]-vv[1]*h2-hv[1]*w2-origin[1],
     cv[2]-vv[2]*h2-hv[2]*w2-origin[2]]
  for(i=0;i<h;i+=F) {
    vl=[v[0], v[1], v[2]];
    for(j=0;j<w;j+=F) {
      d = [vl[0],vl[1],vl[2]]
      u(d)
      os = it(origin, d)
      if(os[0] != -1) {
        c.fillStyle='#fff'
      } else {
        c.fillStyle='#28A'
      }
      c.fillRect(j, i, F, F)
      // we add the computed camera horizontal vector for each column
      vl[0] += hv[0] * F
      vl[1] += hv[1] * F
      vl[2] += hv[2] * F
    }
    // we add the computed camera vertical vector for each row
    v[0] += vv[0] * F
    v[1] += vv[1] * F
    v[2] += vv[2] * F
  }

Functions u & x are two small utilities to calculate the unit vector and cross product:

function u(v) {
  m = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2])
  v[0]/=m
  v[1]/=m
  v[2]/=m
}
function x(u,v) {
  k=[]
  k[0]=u[1]*v[2] - u[2]*v[1]
  k[1]=-(u[0]*v[2] - u[2]*v[0])
  k[2]=u[0]*v[1] - u[1]*v[0]
  return k
}

and the intersection code was straightforward:

function it(o, d) {
  os = -1
  maxt = 100000000.0
  for(k=0;k0) {
        t=tca-Math.sqrt(thc);
      }
    }
    if(t<maxt) {
      maxt = t;
      os = k
    }
  }
  return [os, maxt]
}

Shading was trivial as well (if we can even call it shading):

os = it(origin, d)
if(os[0] != -1) {
  c.fillStyle='#fff'
} else {
  c.fillStyle='#28A'
}

Draw it white if there is an intersection or background-blueish if it isn’t.
Now that we get the basics in place, let’s add more spheres, colors and some shading:

os = it(origin, d)
if(os[0] != -1) {
  // point of intersection: origin + direction ray * t
  ol=[origin[0] + d[0] * os[1],
      origin[1] + d[1] * os[1],
      origin[2] + d[2] * os[1]]
  // intersection point normal (point - sphere center)
  ir=sphereList[os[0]*S + 5]
  n=[(ol[0] - sphereList[os[0]*S]) * ir,
     (ol[1] - sphereList[os[0]*S+1]) * ir,
     (ol[2] - sphereList[os[0]*S+2]) * ir,
  ]
  u(n)
  // light position
  ll=[0,-1000,0]
  // intersection point -> light direction vector
  rl=[ll[0] - ol[0],
      ll[1] - ol[1],
      ll[2] - ol[2]]
  u(rl)
  // sphere color
  r=sphereList[os[0]*S + 5]
  g=sphereList[os[0]*S + 6]
  b=sphereList[os[0]*S + 7]
  // color factor = dot product of normal and light direction vector
  al=n[0]*rl[0] + n[1]*rl[1] + n[2]*rl[2]
  if(al>0.0){
    r*=al
    g*=al
    b*=al
  } else {
    r=0
    g=0
    b=0
  }
  r=(r*16)|0
  g=(g*16)|0
  b=(b*16)|0
  c.fillStyle='#'+hexmap[r]+hexmap[g]+hexmap[b];
} else {
  c.fillStyle='#28A'
}

Results are quite ‘gouradish’:
shim_02
So, let’s add a specular component to the light:

// compute the reflection of the ray
al=2*(n[0]*d[0]+n[1]*d[1]+n[2]*d[2])
rx=[d[0] - al * n[0],
    d[1] - al * n[1],
    d[2] - al * n[2]
]
// and the dot product with the light vector
ls=rx[0]*rl[0]+
   rx[1]*rl[1]+
   rx[2]*rl[2]
// the higher the exponent, more focused will be the specular:
ls=ls0.0){
  r=r*al+ls
  g=g*al+ls
  b=b*al+ls
}

And here the result:
shim_03
We can also play with the specular exponent. Below the differences between 20, 8 and 2:

So far, things are quite simple, but what would be a raytracer without shadows? Let’s also add some shadows!
As we have one single light, it is quite straightforward, before shading each pixel, trace a ray from the intersection point to the light position. If there is any positive intersection of an object it means that point is occluded and shouldn’t be shadowed. As we already have the function to calculate intersections written, it also very simple:

// compute the 't' value of the equation. This will be used as the maximum value for the 't'. Any object further than that will not occlude the light
tl=(ll[2] - ol[2])/rl[2]
sh=it(ol, rl, tl, os[0])
// if not intersection, let's shade the pixel normally
if(sh[0]==-1){
  ...
  // shading algorithm
  ...
} else {
  // pixel is shadowed, apply only ambient color
}

Result starts to look pretty decent:
shim_05
I’ve also added another primitive: a horizontal plane:

if(sl[k*S+7] == 0) {
  ...
  // sphere intersection
  ...
} else {
  vd=sl[k * S + 0] * d[0] + sl[k * S + 1] * d[1] + sl[k * S + 2] * d[2];
  vo=-sl[k * S + 0] * o[0] + sl[k * S + 1] * o[1] + sl[k * S + 2] * o[2] + sl[k * S + 3];
  t=vo/vd
}

Just had to add another entry to the object definition array:

 sl = [1000, 500, 2000, 250000, 0.8, 0.2, 0.3, 0,
      -1000, 500, 2000, 250000, 0.3, 0.2, 0.8, 0,
      0, 500, 3000, 250000, 0.3, 0.8, 0.2, 0,
      0, 1, 0, 1000, 0.6, 0.6, 0.6, 1
 ]

Entries in this array have the following meaning:

// x
// y
// z
// squared radius (radius * radius) or displacement if primitive is a plane
// red
// green
// blue
// object type (0 - sphere, 1 - horizontal plane)

Normal has to be computed in a different way depending on the primitive type. In the case of the plane I was planning to do a checkerboard, but to save some space I ended up creating stripes:

r=sl[os[0]*S + 4]
g=sl[os[0]*S + 5]
b=sl[os[0]*S + 6]
// normal reset to vertical vector
n=[0,-1,0]
if(sl[os[0]*S+7]==0) {
  // if we intersect a sphere, let's recalculate the normal
  n=[(ol[0] - sl[os[0]*S]),
      (ol[1] - sl[os[0]*S+1]),
      (ol[2] - sl[os[0]*S+2])
  ]
  u(n)
} else {
  //tweak color depending on distance - the 1000 was chosen in the most scientific way possible - keep playing with the value until it feels right
  cl=(ol[2]/1000|0)%2
  r=1
  b=0
  if(cl==0) {
    g=1
  } else {
    g=0
  }
}

Result was the following:
shim_07
We’re still missing one key feature of raytracers, reflections! In order to add reflections, we need to create a function that calculates the intersection & computes the resulting color. We’ll call it recursively:

// if reflection index is smaller than 3, compute a reflected ray color & merge it with current color (70% + 30%)
// we limit the amount of reflections to 3 levels
if(rc < 3) {
  rxc = cil(ol, rx, rc+1)
  r=r*0.7+rxc[0]*0.3
  g=g*0.7+rxc[1]*0.3
  b=b*0.7+rxc[2]*0.3
}

By adding reflections, looks slightly better:
shim_08
Also, as you could see in this last screenshot, there was an small intent of CSG (Constructive Solid Geometry). I added a sphere that was ‘substracting’ from other primitives.
At the end, I managed to fix the CSG intersection code. In order to make it work we’ve to calculate both the minimum and the maximum ‘t’ of the ray intersection and work out all the different options:

---- direction ray
* intersection of original object
# intersection of the subtracting object

trivial case, normal intersection
1)---------*----*----#---#-------
trivial case, normal intersection
2)---------#----#----*---*-------
trivial case, normal intersection
3)---------*----#----#---*-------
trivial case, normal intersection
4)---------*----#----*---#-------
trivial case, no intersection (subtracting object is wrapping the whole object)
5)---------#----*----*---#-------
intersection would be the exit point of subtracting object (second #)
6)---------#----*----#---*-------

And the updated intersection code. Used a ‘magic’ code -2 to detect we’re checking the CSG intersection: (Kids don’t do that at home!)

var csi=0
if(z!=-2 &&t!=t2){
  var csg=it(o,d,maxt,-2)
  if(csg[0]==5) {
    if(csg[1] < t && csg[2] > t && csg[2] < t2) {
      t=csg[2]
      csi = 1
    }  else if(csg[1] < t && csg[2] > t2) {
      t = maxt
    }
  }
}

In addition, I also added another primitive: a vertical cylinder.

if(sl[k*S+7] == 0) {
 // sphere intersection
} else if(sl[k*S+7] == 1) {
 // plane intersection
} else {
 // cylinder
  var rd2=1.0-d[1]*d[1]
  var b=sl[k*S + 3]*rd2
  var b2=d[0]*(o[2]-sl[k*S + 2]) - d[2]*(o[0]-sl[k*S + 0])
  b-=b2*b2
  if(b>0) {
    b2 = Math.sqrt(b)
    b=d[0]*(o[0]-sl[k*S + 0]) + d[2]*(o[2]-sl[k*S + 2])
    t=-(b+b2)/rd2
    t2=-(b-b2)/rd2
  }
}

And here is the result:
shim_09

Unfortunately, after using Uglify (https://github.com/mishoo/UglifyJS) and RegPack (http://siorki.github.io/regPack.html) the resulting size was over 1600 bytes so I had to start a heavy optimization to get it under 1024. I removed the CSG intersection code :(, simplified the RGB filling color to:

r=(col[0]*255)|0
g=(col[1]*255)|0
b=(col[2]*255)|0
c.fillStyle='rgba('+r+','+g+','+b+',1)'
c.fillRect(j, i, F, F)

instead of using the hexmap and 16 different shades per component – I kind of liked it the pixelated/oldschool effect, but it was slightly shorter & definitely faster.
After some time optimizing and doing some sacrifices I managed to get it under 1024. It was a pity I couldn’t spend any more time on it as I would really tried to squeeze the CSG code in! ๐Ÿ˜‰
Here is the final source code:

w=window.innerWidth
K=500
J=K*K
E=1000
D=1500
G=0
l=n=[]
O = [0, K, 0, J*2, 1, 0, 0, 0,
     0, K, 0, J, 0, 0, 1, 0,
     0, K, 0, J, 0, 1, 0, 0,
     0, E, E*2, J, 1, 1, 1, 2,
     0, 1, 0, E, 1, 0, 0, 1]

// dot product
dp = (u,v) => u[0]*v[0]+u[1]*v[1]+u[2]*v[2]

// unit vector
u = v => {
  m = Math.sqrt(dp(v,v))
  v[0]/=m
  v[1]/=m
  v[2]/=m
}

it = (o, d, T) => {
  u(d)
  s = -1
  t = T
  for(z=0;z<40;z+=8){
    t=(-O[z] * o[0] + O[z + 1] * o[1] + O[z + 2] * o[2] + O[z + 3])/(O[z] * d[0] + O[z + 1] * d[1] + O[z + 2] * d[2])
    if(O[z+7] == 0) {
      e=[O[z] - o[0],
         O[z + 1] - o[1],
         O[z + 2] - o[2]]
      p=dp(e,d)
      t=p-Math.sqrt(O[z+3]-dp(e,e)+p*p)
    }
    if(O[z+7] == 2) {
      p=1-d[1]*d[1]
      q=d[0]*(o[2]-O[z + 2]) - d[2]*(o[0]-O[z])
      t=-(d[0]*(o[0]-O[z]) + d[2]*(o[2]-O[z + 2])+Math.sqrt(O[z + 3]*p-q*q))/p
    }
    if(t>.1&&t<T) {
      T = t
      s = z
    }
  }
  return [s, T]
}

cil = (o,d) => {
  var r=[.4,.4,.5]
  I = it(o, d, E*E)
  if(I[0]>=0) {
      y=I[0]
      for(k=0;k<3;k++) {
        o[k]=o[k] + d[k] * I[1]
        n[k]=o[k] - O[y+k]
        l[k]=O[2-k]-o[k]-D*k
      }
      if(O[y+7]==1) {
        n=[0,-1,0]
        O[y + 5]=(o[2]/E|0)%2
      }
      if(O[y+7]==2) n[1] = 0
      u(n)
      H=it(o, l, E*E)
      A=2*dp(n,d)
      rx=[d[0] - A * n[0], d[1] - A * n[1], d[2] - A * n[2]]
      A=L=0
      if(H[0]<0) {
        L=dp(rx,l)
        L=L<0?0:Math.pow(L,9)
        A=dp(n,l)
      }
      for(k=0;k<3;k++) r[k]=O[y+4+k]*A+L
      R = cil(o, rx)
      for(k=0;k<3;k++) r[k]=(r[k] + R[k])/2
  }
  return r
}

setInterval(() => {
  //animation
  for(i=2;i>=0;i--) {
    O[i*8] = l[2] = D*Math.sin(G + i*2)
    O[i*8 + 2] = l[0] = D*Math.cos(G + i*2) + D;
  }
  //render
  for(;i<window.innerHeight;i+=6) {
    for(j=0;j<w;j+=6) {
      x=cil([0,0,-D*2], [w/2-j, i-w/6, D-w/6])
      c.fillStyle='rgb('+[x[0]*255|0,x[1]*255|0,x[2]*255|0]+')'
      c.fillRect(j, i, 6, 6)
    }
  }
  G+=.02
}, 10)

and the result can be checked here: https://js1k.com/2018-coins/demo/3101

xmas live-coding

Last week, I was invited to take part in one of our development communities. The challenge was to explain something different than what are they using every day and, at the same time, make some fun of me ๐Ÿ˜‰
I just had a small special request, to explain how I created my 2016 js1k entry. So, I used half the session for that purpose and, on the second part, I did a bit of live coding on a HTML5 canvas. As I already imagined I’d be running out of time, I prepared a bit the example the night before and, after some steps, I cheated and used the snippets I had already prepared (explaining though the steps and changes on every single step)
At the end, I showed how to build a very simple snowman only using plain 2D primitives, but simulating, more or less, a 3D effect.
Below there is the result:

Voxeling – js1k 2016 postmortem

CeAcHlAUYAAP-ua (1)
This year, as usual, I got the inspiration from somewhere else ๐Ÿ™‚
Checking twitter while commuting I saw a re-tweet with a voxel image, I dug up a bit and, to be honest, I was really impressed by the amazing work of @Sir_carma:
More work of Sir_carma
More specifically in this voxel image:
mm2WNK7 copy
ย 
Source: https://twitter.com/Sir_carma/status/651500940822974464
So I did my best to recreate it in 1k and here is the result:
http://js1k.com/2016-elemental/demo/2497
or go to the js1k page for bigger preview: http://js1k.com/2016-elemental/demo/2497
and feel free to leave a message in the reddit thread:
https://www.reddit.com/r/js1k/comments/48ndh9/demo_2497_voxeling_by_raimon_r%C3%A0fols_canvas_1024/
and, of course, do not hesitate to check all the other amazing entries this year: http://js1k.com/2016-elemental/demos
Some details of the source code, scroll down to see the whole thing:
First I created a height map of the plane, but to optmize it a bit, I made it a bit smaller & symmetric:

//full plane
p = [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
1, 1, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 0,
8, 4, 3, 2, 2, 3, 3, 5, 5, 4, 3, 2, 1,
1, 1, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 0,
1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0];
//reduced & symmetric plane
p = [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 0,
5, 2, 2, 2, 3, 3, 5, 5, 4, 3, 2, 1
]

I tried to optimize it by using a string and then splitting the array into numbers but after executing the code compressor, final size was bigger, so at the end I left it this way.
Terrain and clouds are a interpolated noise function. First we need to generate some random noise:

V = 50
H = 100
D = 1000
// ...
n = new Uint8Array(D)
w.crypto.getRandomValues(n)

V & H are the number of cells we will render (Vertical and Horizontal). We just reuse the variable D instead of calculating the right amount of noise values we need… so, we actually generate too many noise values, but memory is infinite.. right?
Then, to generate a smooth terrain, we interpolate values using a cosine interpolator. To generate a field of 50×1000 points, we need 5×100 and interpolate each single value for 10×10 new generated values.
To get the integer values of the coordinate we divide by 10 (B in our case) and we do a binary OR logic operation by 0 to get rid of the floating point part. It is one of the javascript tricks that save me few precious bytes.
Another approximation I used in the code below is to get rid of PI. As we have to calculate (1.f – Math.cos(value * Math.PI)) / 2.f and value has to be between 0 and 1 I originally did the following:

x = (j / 10) | 0
y = (i / 10) | 0
F = (i % 10) / 10
E = (j % 10) / 10
E = (1 - Math.cos(E * Math.PI)) / 2
F = (1 - Math.cos(F * Math.PI)) / 2

but, as turns out, both i % 10 and j % 10 values will be between 0 & and 9, so dividing them by 3, gives us a result between 0 and 3 which is “good enough” as an approximation of a value between 0..1 multiplied by PI, hence the division by 3 and no PI mentioned anywhere in the code:

B = 10
o = []
T = S = s = 0
i = V
while (i--) {
  j = D
  while (j--) {
    y = (i / B) | 0
    x = (j / B) | 0
    k = y * H + x
    F = (i % B) / 3
    E = (j % B) / 3
    E = (1 - Math.cos(E)) / 2
    u = 1 - E
    F = (1 - Math.cos(F)) / 2
    v = 1 - F
    v = n[k] * u * v + n[k + 1] * E * v + n[k + H] * u * F + n[k + H + 1] * E * F
    o[s++] = v < 180 ? 0 : (v - 180) / 7
  }
}

Last part is to “normalize” the value. If the interpolated value is smaller than 180 we assume is water or 0. Otherwise we scale it down dividing by 7 (7 felt good, not any big reason why it is 7 and not 8 or at least, not any I could remember right now, as far as I remember was trial & error)
Another optimization I had to do, although not really proud of this one is to get rid of one gradient color. Initially voxels had 3 colors (top, front, left) but at the end, for size constraints, front and left shared the same color value. At the time I did this optimization it felt acceptable enough, but definitely looks way nicer with 3 colors, you can judge yourself in the screenshot below (left – current version, right – old version with 3 colors)
screenshots_combined
To render the voxels and avoid any depth checks or z-fight between voxels, they are always drawn from the far end (top of screen) to the bottom of the screen and from right to left, so all overdrawn voxels are correct. In the initial version I introduced checks to avoid drawing left & front faces of the voxel if they were occluded, but I had to get rid of the optimizations because of size constraints.
Clouds are rendered vertically-centered, and small mountains are just a height function from 0.
clouds_terrain
Finally all the voxels are rendered (water, mountains, clouds & plane) in a single loop with the help of a precalc table:

A = [0, -6, 1,
9, -7, 1,
7, -11, 1,
-2, -10, 1,
0, 0, 0,
9, -1, 0,
9, -7, 1,
0, -6, 1,
0, 0, 0,
-2, -4, 0,
-2, -10, 1,
0, -6, 1
]

Each value indicates the X, Y and height multiplier of the rectangle to draw. There are 3 groups of 4 coordinates, rendering 3 distorted (perpective) rectangles for each voxel.

C = [
"#A87", "#754", //0-mountains
"#f96", "#C53", //3-plane
"#fff", "#ccc", //1-clouds
"#799" //2-water
]
// number of faces to draw (on water this will be set to 1)
r = 3
// h is the value of the height map for that voxel, if height multiplier is 1
// in the 3rd coordinate of the precalc table it will be added to the y
// coordinate of the rectangle
G = -h * 4
v = 0
// s contains the value of the clouds above only when rendering water &
// mountains, "shadows" are only an alpha function
// color is computed depending on which layer are we rendering and
// which face
while (r--) {
  c.fillStyle = C[f * 2 + (!v ? 0 : 1)]
  c.globalAlpha = 1 - s / 2
  c.beginPath()
  c.lineTo(A[v++] + E, A[v++] + F + A[v++] * G)
  c.lineTo(A[v++] + E, A[v++] + F + A[v++] * G)
  c.lineTo(A[v++] + E, A[v++] + F + A[v++] * G)
  c.lineTo(A[v++] + E, A[v++] + F + A[v++] * G)
  c.fill()
}

This code is executed three times, each with a different translate (see the while(–z) loop below) and some logic depending on which phase it is. Initially there were 3 different loops which was way more clear what was being drawn each time, but took too many space and the whole thing didn’t fit in 1k.
I had plans to actually move the plane using the keyboard and even fire bullets, but I was, maybe, a bit too optimistic ๐Ÿ˜‰
Below you can find the whole source code (works using the js1k shim file). Code is quite unreadable due to being highly optimized for space. Compressed file under 1k is achieved by using: uglify and RegPack with 2, 1, 1 score weight values..

p = [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 0,
5, 2, 2, 2, 3, 3, 5, 5, 4, 3, 2, 1
]
V = 50
H = 100
B = 10
D = 1000
w = window
n = new Uint8Array(D)
w.crypto.getRandomValues(n)
w = w.innerWidth
A = [0, -6, 1,
9, -7, 1,
7, -11, 1, -2, -10, 1,
0, 0, 0,
9, -1, 0,
9, -7, 1,
0, -6, 1,
0, 0, 0, -2, -4, 0, -2, -10, 1,
0, -6, 1
]
C = [
"#A87", "#754", //0-mountains
"#f96", "#C53", //3-plane
"#fff", "#ccc", //1-clouds
"#799" //2-water
]
o = []
T = S = s = 0
i = V
while (i--) {
  j = D
  while (j--) {
    y = (i / B) | 0
    x = (j / B) | 0
    k = y * H + x
    //F&E will be less than 3.333 - good approximation for PI
    F = (i % B) / 3
    E = (j % B) / 3
    E = (1 - Math.cos(E)) / 2
    u = 1 - E
    F = (1 - Math.cos(F)) / 2
    v = 1 - F
    v = n[k] * u * v + n[k + 1] * E * v + n[k + H] * u * F + n[k + H + 1] * E * F
    o[s++] = v < 180 ? 0 : (v - 180) / 7
  }
}
setInterval(function() {
  s = w / (D + V)
  t = T % 9
  a.width = w
  b.style.background = '#635'
  c.save()
  c.scale(s, s)
  c.translate(9, H * 3)
  c.fillStyle = "#568"
  c.beginPath()
  c.lineTo(0, -H * 2)
  c.lineTo(H * 9, -H * 3)
  c.lineTo(D, -H)
  c.lineTo(D, H)
  c.lineTo(0, 0)
  c.fill()
  c.save()
  c.translate(H * 9 - t, t / 9 - H)
  c.save()
  z = 4
  while (--z) {
    if (z == 2) c.translate(-t, t / 9)
    if (z == 1) c.translate(V + B, B)
    i = 0
    while (i++ < V) {
      j = z == 1 ? 12 : H
      while (j--) {
        k = i * D + j + (z == 3 ? S : S * 2)
        if (z == 2) k += H
        f = (z == 3 && o[k]) ? 0 : z
        h = z == 1 ? p[(i 1) s = 1
        v = G = E = F = 0
        if (f < 3) {
          r = 3
          G = -h * 4
          if (f) {
            E = 40
            F = -160 + h * 2
            s = 0
            if (!h) r = 0
          }
        }
        while (r--) {
          c.fillStyle = C[f * 2 + (!v ? 0 : 1)]
          c.globalAlpha = 1 - s / 2
          c.beginPath()
          c.lineTo(A[v++] + E, A[v++] + F + A[v++] * G)
          c.lineTo(A[v++] + E, A[v++] + F + A[v++] * G)
          c.lineTo(A[v++] + E, A[v++] + F + A[v++] * G)
          c.lineTo(A[v++] + E, A[v++] + F + A[v++] * G)
          c.fill()
        }
        c.translate(-9, 1)
      }
      c.translate(z == 1 ? H + B : H * 9 + 2, z == 1 ? -9 : -H + 4)
    }
    c.restore()
  }
  T++
  S = (T / 9) | 0
  }, B)

JS1k 2014 entries

Last year I said I had a very ambitious idea for the js1k 2013 competition but I didn’t had the time and I thought to leave it for the following year. This year, once again, I could only work on my entry the day before the deadline, so I decided to do something else and start from scratch.
I saw this animated gif long time ago (which, by the way, I don’t know the original source or author)

So I thought it would be good to make a 1k version of it.
To be honest I’m not very happy with the result, I’m pretty sure it could be done better & nicer. Anyway I submitted it to the competition and here is the result:
http://js1k.com/2014-dragons/demo/1973
Find below the full source code or check the details page on js1k

//values are just trial & error
w=window
f=w.innerHeight/w.innerWidth
w=1343
h=w*f
_=Math
C=_.cos
S=_.sin
R=_.random
F=512
Z=2200
P=6.28
l=[]
A=[]
B=[]
L=54
p=P/L
Y=N=0
//generate lamp posts in a circle on both sides and pointing to the center
df='000100110010000001011010010110110010010011011010'.split('')
for(i=0;i=3;k--) {
    x=k*F*S(p*i)
    z=k*F*C(p*i)
    x2=(k+v)*F*S(p*i)
    z2=(k+v)*F*C(p*i)
    for(j=0;j9&&j&2){
        xv=x2
        zv=z2
      }
      A[N++]=xv+df[j*3  ]*10
      A[N++]=-df[j*3+1]*512
      A[N++]=zv+df[j*3+2]*8
    }
    i+=.5
    v=-v
  }
}
//store where lamp posts end
K=N
//generate random lines
k=0
for(i=L*8;i--;) {
  l[k++]=R()*P
  l[k++]=R()
  l[k++]=-R()*128-64
  l[k++]=R()*.2+.2;
}
N+=L*96;	//8*12
setInterval(function(){
  Y+=.004
  b.style.background='#000'
  //clear screen
  a.width=w
  a.height=h
  //generate trail lines & move them
  j = K
  k=i=0;
  for(;i<l*8;i++) {
    d=l[k++]
    p=l[k++]
    y=l[k++]
    e=l[k++]
    r=(3.1+p*.8)*F
    v=4*S(y+i)
    g=[0,v,v,0]
    for(v=0;v<4;v++) {
      x=r*S(d)
      z=r*C(d)
      A[j++]=x
      A[j++]=y+g[v]
      A[j++]=z
      if(v&1) d+=e
    }
    l[k-4]+=.02
    // // move lines in both directions
    // if(i= K - trail lines, half red #f22, half white #fff
  k=i=0
  for(;i=K) {
      if(i*12=2) {
        c.lineTo(B[k],B[k+1]);
      }
      k+=3
    }
    c.fill()
    //draw lamp post light after drawing the last top horizontal quad
    //lamp posts are formed of 4 quads:
    //0 & 1 vertical
    //2 & 3 top horizontal
    //avoid drawing lights on trail lights
    if(i % 4 == 3 && i*12<k) {
      c.fillStyle="#fff"
      c.beginPath()
      c.arc(B[k-3], B[k-2], (2-B[k-1])*13,0,P)
      c.fill()
    }
  }
}, 20)

Code is compressed under 1k thanks to Google Closure Compiler and RegPack v3
As I wasn’t really happy with the result I did another quick entry based on the old good daCube2 colors & idea:
[youtube https://www.youtube.com/watch?v=OYABLIPjF7Q?rel=0&w=640&h=480]
Find below the result:
http://js1k.com/2014-dragons/demo/1969
and the source code or check the details page on js1k:

w=window
h=w.innerHeight
w=w.innerWidth
_=Math
mC=_.cos
mS=_.sin
R=_.random
F=512
Z=2048
N=L=X=Y=0
A=[]
B=[]
C=[]
D=[]
addCube=function(s) {
  k=N/3
  j='000100010110001101011111'.split('')
  for(i=0;i<24;i++) {
    A[N++]=(j[i]-.5)*2*s
  }
  l='011332200445514662577367'.split('')
  for(i=0;i<24;i++) {
    D[L++]=k+(l[i]|0)
  }
}
for(z=200;z--;){
  addCube(100+z*5)
}
anim=.004
setInterval(function(){
  Y+=anim*R()+anim
  X+=anim*R()+anim
  y=Y
  x=X
  //X+=.01
  b.style.background='#444'
  //clear screen
  a.width=w
  a.height=h
  k=0
  //dy rotation
  for(i=N;i--;) {
    if(k%24*3==0) y-=anim*2
    C[k+2]=A[k+2]*mC(y)-A[k]*mS(y)
    C[k  ]=A[k+2]*mS(y)+A[k]*mC(y)
    k+=3
  }
  k=0
  //dx rotation
  for(i=N;i--;) {
    if(k%24*3==0) x+=anim*2
    B[k+1]=A[k+1]*mC(x)-C[k+2]*mS(x)
    B[k+2]=A[k+1]*mS(x)+C[k+2]*mC(x)
    k+=3
  }
  //transform 3d-2d
  k=p=0
  for(i=N;i--;) {
    C[k++]=F*C[p  ]/(C[p+2]+Z)+w/2
    C[k++]=F*B[p+1]/(C[p+2]+Z)+h/2
    p+=3
  }
  p=0
  for(i=0;i<l/24;i++) {
    c.strokeStyle="#fff"
    c.globalAlpha=(i/(L/24))
    c.beginPath()
    for(k=24;k--;){
      j=D[p++]
      c.moveTo(C[j*2],C[j*2+1]);
      j=D[p++]
      c.lineTo(C[j*2],C[j*2+1]);
    }
    c.stroke()
  }
}, 20)

My js1k entry

I was thinking to take part into the javascript 1k competition (here) but as I didn’t had too much free time and never really did that much in javascript targeting at 1k, I discarded the idea. Until I got a very ambitious idea the last day before the deadline.. how appropriate.. So I started trying few things and, to be honest, they didn’t work as I expected.. so I saved my ambitious idea for the next competition ๐Ÿ˜‰
At the end, as I was already programming in Javascript I did a waving catalan flag in roughly 1k without paying attention to optimization. Pretty simple but enough for being my first time on a 1k javascript competition. Anyway, after doing some basic optimizations I still got a couple hundred bytes left so I’ve decided to add some extras. Check the demo for more details ๐Ÿ™‚
Click the image below for the demo:
Screen Shot 2013-04-01 at 1.11.46 AM
Just in case anyone is interested here is the fully uncompressed code with few comments.

k = 0
w=window
h=w.innerHeight
w=w.innerWidth
h2=h/2
W=H=40
setInterval(function(){
    // clear screen
    c.width=w
    c.height=h
    o = 0;
    p = []
    //Generate flag points. Before size-optimizing the code they were generated only once and stored in an external array.
    //To save one loop from the code they're generated every single frame.. oh well..
    for(j = 0; j < H; j++) {
        for(i = 0; i < W; i++) {
            x = 1.2 * i * w / W +8 * Math.sin((j + k) * 0.15)
            y = 1.2 * j * h / H + 8 * Math.sin((i + k) * 0.3)
            z = 512 + 32*Math.sin((i+j+k) * 0.2)
            p[o] = (512 * x) / z
            p[o+1] = (512 * y) / z
            p[o+2] = z;
            o+=3
        }
    }
    // draw the flag
    o = 0
    for(j = 0; j < H-4; j++) {
        for(i = 0; i < W-1; i++) {
            // compute cross product to compute light factor
            // this can be probably done in waaaay less bytes
            l = []
            l[0] = p[o+3] - p[o]
            l[1] = p[o+4] - p[o+1]
            l[2] = p[o+5] - p[o+2]
            m = []
            m[0] = p[o+W*3] - p[o]
            m[1] = p[o+W*3+1] - p[o+1]
            m[2] = p[o+W*3+2] - p[o+2]
            n =[]
            n[0] = l[1]*m[2] - l[2]*m[1]
            n[1] = l[2]*m[0] - l[0]*m[2]
            n[2] = l[0]*m[1] - l[1]*m[0]
            n = n[2] / Math.sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
            // square it to make results more dramatic
            n *= n;
            // choose flag color (red/yellow) to render the different color stripes depending on the vertical coordinate
            g = 221
            b = 9
            if(((j / 4) % 2|0) == 0){
                r = 253
            } else {
                r = g
                g = b
            }
            // apply the lightning factor and convert it back to integer using "|0"
            r=r*n|0
            g=g*n|0
            b=b*n|0
            a.fillStyle="rgba("+r+","+g+","+b+",1)"
            a.strokeStyle=a.fillStyle
            // actual render of the quad. Fill & stroke to polish (antialiasing, subpixel,..)
            a.beginPath()
            a.lineTo(p[o], p[o + 1])
            a.lineTo(p[o+3], p[o + 4])
            a.lineTo(p[o + 3 + W*3], p[o + 4 + W*3])
            a.lineTo(p[o + W*3], p[o + 1 + W*3])
            a.fill()
            a.stroke()
            o+=3
        }
        o+=3
    }
    // draw the "nyan cat" like trail
    w4=4*w/6
    w1=w/10
    cols=["#5E96FF","#387DFF","#0F47AF","#0D3E99","#0B347F","#08265B"]
    for(j = 0; j < 32; j++) {
        for(i = 0; i< 6;i++) {
            a.fillStyle=cols[i]
            a.strokeStyle=a.fillStyle
            wb=w4 / 32
            hb=w1 / 6
            x=j * wb
            y=h2 + (i-3) *hb - hb*Math.sin(k*0.2 + j *0.6)
            a.fillRect(x,y,wb,hb)
            a.strokeRect(x,y,wb,hb)
        }
    }
    // draw the star
    a.fillStyle="#ffffff"
    a.strokeStyle=a.fillStyle
    a.beginPath()
    for(i = 0; i < 5; i++) {
        s = Math.sin(k * 0.2)*32
        l = w1 * Math.sin(i* 1.256) + s/4
        m = w1 * -Math.sin(i* 1.256 + 1.57) + s
        n = w/25 * Math.sin(i* 1.256 + 0.628)
        o = w/25 * -Math.sin(i* 1.256 + 2.19) + s
        a.lineTo(w4 + l, h2 + m)
        a.lineTo(w4 + n, h2 + o)
    }
    a.fill()
    a.stroke()
    k+=0.5
},20);

And the compressed result thanks to Google Closure Compiler and JSCrush:

k=wJdow;h&HV;w&Wid^;h2=h/2;H=W=4setInterval(function_{c.wid^;c.hV=h;o=p=[]j<hui<wx=~i*w/W+815*(j!y=~j*h/H+83*`!zK2+Z`+j!]Kx/z,1]Ky/z,2]=z,o=ji=cols[i,wb4/Z,hb1/6,x=j*wb,y=N`-3)*hb-hbk+6*j,;="#ffffff";;;5>is=Zkl1*O/4,m1*-+~57O,nY+628oY-+2.19Ow4+l,Nm)w4+n,No);_;_;k+=5},20);GJ(+X,a.lJeTo(a.strokefor`=~256*i[2]	[0][1]a.fillX=Rect(x,y,wb,hb)],++)3*W*;for(j=a.begJPa^_=w),p[o*n|0,0;2*F #;i]-o+=3!+k)$])&.Jner@*mC=GMa^.sJinK=51L+",Nh2+O)+sQ=[U;jVeightXStyleY/25*Z32^th_()`(i~1.0.';for(Y in $='~`_^ZYXVUQONLKJGC@&$!	')with(_.split($[Y]))_=join(pop());eval(_)

Presentation about BlackBerry 10

Next week during Mobile World Congress I am going to do a presentation about BlackBerry 10 together with Jorge del Casar, BlackBerry Developer Evangelist in Spain. The event is organized by GDG Barcelona and will be held in the Facultat Informร tica Barcelona
[googlemaps https://maps.google.es/maps?ie=UTF8&cid=17558281092145204566&q=Facultat+d’Inform%C3%A0tica+de+Barcelona&gl=ES&hl=en&t=m&ll=41.389415,2.113323&spn=0.005634,0.00912&z=16&iwloc=A&output=embed&w=425&h=350]
If you’re a developer it’s a good opportunity to get to know BlackBerry 10 as we will speak about both html5 and native development.
Here is the link to the event:
https://plus.google.com/u/0/events/ckc7u8j5b138o6rfas9l8hkb0hk
More information:
https://developer.blackberry.com/