Javascript

so here is vyw

I supposed to write this weeks ago though, anyway. Here is vyw, it’s a client side file browser. Vyw actually is a continuation of this post. At least the idea was already popped up around that time, but I only had the chance to tinker around it few weeks ago. So the idea was to have this fully functional file browser, or specifically, images browser with thumbnail view, which usually achieved with server-side app, backed only with nginx.
Read more

shreds: on the javascript

Currently working on the re-implementation of shreds client-side and move to es6 while I’m on it. Figured out I might as well write some note on its current implementation, annotating the caveats or something.

Anyway, the main concept was to be able to add new feature (to the app) quickly, while maintaining the whole (supposed to be modular) structure. The whole app is started with this main (singleton) object called shreds.

Read more

read.shreds

I’ve been putting up some courage to actually write about this thing. Started working on this roughly 1 and a half years ago, I believe it was not long after Google initially announced that they’ll closing Google Reader.

named shreds because naming is hard

As I realized that I never build any barely-usable so-called-product, also for the fact that my related skills on this were sound more like a joke, I kept the repository private for some months. It was really hard when feedbin announced, since we both built based on the same stack (We both based on ruby on rails, and using feedzira (later feedjira) as our core feed fetcher). I think I was supposed to drop the project and use feedbin instead, considering it’s waaay more superior in addition of its massive community.

Read more

imgpop is Picto Now

This one is late for about… 24 days?
I re-made the image viewer almost from scratch also renamed it to picto.

At the last post I showed the snippet on how imgpop html template looks like. And while I said it was neat, it is not. The new template actually looks like this: in a straight one line.

<a href="<%= image %>" id="image-<%= id %>" rel="pict" w="<%= full_width %>" h="<%= full_height %>"><img src="<%= scaled_image %>" alt="<%= title %>" class="<%= klass %>"/></a>

So let say I call the imgpop like this


% center Tagline for The Pict.

From the tag above the rendered html will looks like this

<a href="/a/20120327-stony_cat/Screenshot-2012-03-27_22.22.41.png" id="image-1" rel="pict" w="1920" h="1080"><img src="/a/20120327-stony_cat/resized_Screenshot-2012-03-27_22.22.41.png" alt="Tagline for The Pict." class="center"/></a>

Far more simple, and better, no script tag pollution.

The backend magic were performed by MiniMagick (pun intended). As you may see above, I put the resized image rather than the original one inside the post. Just when the image clicked, the original image showed inside a popup, plus tagline at the bottom, and nice resize button feature hidden at the right-top corner. Try hover your mouse to the right top corner of the image and click the resize button. Of course nothing will happen if the image were not resized by MiniMagick, or smaller than your browser portview size.

At the frontend, I ditch jQuery all the way and use ender-based libraries. The source code can be forked at https://bitbucket.org/fudanchii/picto.

So, here is to summarize, what’s picto (hopefully) features:

  • Shadowbox inspired.
  • Resizable image, also draggable.
  • Lightweight.
  • Easy to integrate to another platform.

Sample image after the break.

Read more

imgpop

Now I will going into technical details inside imgpop.

Like I said in the previous post. I extends Brian’s imgpopup and do some makeup to things. At the backend, I use mini_magick to actually save the resized image, and use that as preview/thumbnail. Here’s the snippet.

#...#
# Open the source image, and scale it accordingly.
image = MiniMagick::Image.open(image_path)
vars['full_width'] = image[:width]
vars['full_height'] = image[:height]
image.resize "#{@percent}%"

rpath = source+ resized_image
if not File.exists? rpath
# Actually save the image
  image.format "jpg"
  image.quality "92"
  image.write rpath

  # This is the tricky part
  # we should register the new created file
  # since Jekyll already indexed all files before
  context.registers[:site].static_files << StaticFile.new(
          context.registers[:site], source, File.dirname(@path.sub(%r{^/}, '')),
          "resized_#{File.basename(@path)}")
  print "image saved to #{rpath}\n"
end
#...#
Read more

Image viewer is up!

% center My current desktop with cinnamon: 2nd monitor % center My current desktop with cinnamon: 1st monitor Yay, it’s up. You can click images above to try it out. a pop-up will appear with full sized image, and it’s draggable! You can also try hover the upper area of the popup to see the tagline/title and download link for the image. Credits to Brian Clapper.
Read more

More Layout Update

I apologize for the inconvenience to refreshing your browser cache. For I randomly changing the site’s layout. Now I made the whole page a bit smaller, including the fonts. Also fixed mobile view for navigation bar. Which is hacky.

So it appears that this theme support mobile view (duh). That navigation bar above will shrink and turn into drop down menu if browsed from mobile device. And it happened that I broke this feature when I moved the search box to the sidebar.

Here be the aforementioned feature in javascript.

function getNav() {
  var mobileNav = $('nav[role=navigation] fieldset[role=search]').after('<fieldset class="mobile-nav"></fieldset>').next().append('<select></select>');
  mobileNav.children('select').append('<option value="">Navigate&hellip;</option>');
  $('ul[role=main-navigation]').addClass('main-navigation');
  $('ul.main-navigation a').each(function(link) {
    mobileNav.children('select').append('<option value="'+link.href+'">&raquo; '+link.text+'</option>');
  });
  $('ul.subscription a').each(function(link) {
    mobileNav.children('select').append('<option value="'+link.href+'">&raquo; '+link.text+'</option>');
  });
  mobileNav.children('select').bind('change', function(event) {
    if (event.target.value) { window.location.href = event.target.value; }
  });
}
Read more

Conway's Game of Life

My javascript demo.
Naive implementation of Conway’s life game.



You can try click the black screen to toggle cell’s life, create some patterns and then click play.

Game of Life maybe is, as far as I know, the most simple cellular automaton. The cell life is ruled by its neighbors. The cell will not survive if there is more than 3 or less than 2 adjacent cells alive. And a new cell will born if there is exactly 3 adjacent cells alive.

The original concept for game of life mentioned that the field is infinite, so we can always check how the n-th generation’s doing. I implement finite field above since it’s way more simple.

Now let’s see the source.

function und(a) {
    return (typeof a === "undefined");
}

Since I used finite field for this implementation, we should check for unbounded cell, from function above we can check the cell whether it is actually defined or not.

Next, we calculate the cell’s neighbour. Game of life using cartessian lookalike field in which the coordinate system is orthogonal. Naturally, I use 2 dimensions array for this. To calculate the neighbours number, we can traverse through all adjacent cells and check if that cell is dead or alive.

function count_neighbour(f, x, y) {
    var num = 0;
    if (!und(f[x - 1])) {
        if (!und(f[x - 1][y - 1]) && f[x - 1][y - 1] === 1) num += 1;
        if (!und(f[x - 1][y]) && f[x - 1][y] === 1) num += 1;
        if (!und(f[x - 1][y + 1]) && f[x - 1][y + 1] === 1) num += 1;
    }
    if (!und(f[x])) {
        if (!und(f[x][y - 1]) && f[x][y - 1] === 1) num += 1;
        if (!und(f[x][y + 1]) && f[x][y + 1] === 1) num += 1;
    }
    if (!und(f[x + 1])) {
        if (!und(f[x + 1][y - 1]) && f[x + 1][y - 1] === 1) num += 1;
        if (!und(f[x + 1][y]) && f[x + 1][y] === 1) num += 1;
        if (!und(f[x + 1][y + 1]) && f[x + 1][y + 1] === 1) num += 1;
    }
    return num;
}

That is the most simple algorithm I can think of, not really clever I know… ^_^;

Of course we should initiate our field first. Here I’m using typed array for a slight performance boost.

function init_field(field, h, w) {
    for (j = 0; j < h; j++) {
        field[j] = new Uint8Array(w);
    }
}

Uint8Array will generate array of 8bit unsigned integer, which we can access like ordinary array later.

Now let’s initiate the DOM


function init_field_dom(h, w) {
    for (j = 0; j < h; j++) {
        for (i = 0; i < w; i++) {
            cell = $("<div id =\"cell_"+ i +"_"+ j +"\"></div>").addClass("cell");
            cell.addClass("clickable");
            cell.appendTo("#life_field");
        }
    }
}

function toggleOnOff(field, x, y) {
    if (field[x][y] === 0) {
        field[x][y] = 1;
    }
    else {
        field[x][y] = 0;
    }
}

Those functions will generate all the small cells. The toggleOnOff function will just alternate the cell’s state.

And here is the life rule.

var dead_cell_fn = function (field, n_field, x, y) {
    n = count_neighbour(field, x, y);
    if (n == 3) {
        n_field[x][y] = 1;
    }
    else {
        n_field[x][y] = 0;
    }
}

var alive_cell_fn = function (field, n_field, x, y) {
    n = count_neighbour(field, x, y);
    if (n <= 1 || n >= 4) {
        n_field[x][y] = 0;
    }
    else {
        n_field[x][y] = 1;
    }
}

function next_gen(field, n_field, h, w) {
    for (y = 0; y < h; y++) {
        for (x = 0; x < w; x++) {
            if (field[x][y] === 0) {
                dead_cell_fn(field, n_field, x, y);
            }
            else {
                alive_cell_fn(field, n_field, x, y);
            }
        }
    }
}

You see I’m cheating above. I use 2 fields to calculate the next generation, so we can maintain the current field state as we create our next generation, but this also mean we have to alternate between this 2 fields while playing. And that nasty nested for-loop made the algorithm grow in exponential.

For the rule itself. You can change the rule as you like. For example you may want a new cell to born if there is 5 adjacent cells alive, etc…

function play_this_life(field, temp, h, w) {
    var swap = true;
    play = function() {
        if (swap) {
            next_gen(field, temp, h, w);
            update_field(temp, h, w);
            swap = false;
        }
        else {
            next_gen(temp, field, h, w);
            update_field(field, h, w);
            swap = true;
        }
    };
    return play;
}

You can say the overall game is controlled by this function above. I made closure to do some currying with all of those parameters. Closure is sort of like an object constructor, but work with function. Above, we check for the swap value since we should alternate between field and tmp.

The last is our main entry.

$(function() {
    var _field = [];
    var temp   = [];
    var rgx    = /cell_(\d+)_(\d+)$/;
    var dw = 64 ,dh = 64;

    init_field(_field, dw, dh);
    init_field(temp, dw, dh);
    init_field_dom(dw, dh);

    $(".cell").click(function(){
        getto = rgx.exec(this.id);
        x = parseInt(getto[1]);
        y = parseInt(getto[2]);
        toggleOnOff(_field, x, y);
        toggleOnOff(temp, x, y);
        $("#cell_" + x + "_" + y).toggleClass("cell_on");
    });

    update_field(_field, dw, dh);
    lets_play = play_this_life(_field, temp, dw, dh);

    var intId = null;
    var play  = false;
    $("#play").click(function() {
        if (!play) {
            intId = setInterval(lets_play, 85);
            play  = true;
        }
    });
    $("#stop").click(function() {
        if (play) {
            clearInterval(intId);
            play = false;
        }
    });
});

We bind the click event to our cell. To turn the cell alive or dead I should find which cell actually get clicked. I implement this by using regular expression to catch current cell index.

After calling play_this_life, we get our closure and we just have to call it over and over to run the game. I use setInterval to do this.

And that’s it.
I omit the Gosper Gun Glider function, but you can always see the full source code from right click ;)

Read more

CLI to do list

I stumbled upon this project last night. todo - Todos in the CLI like what. And that’s cute. So I decide to give it a spin and a bit inspired to extend its potential. The first thing that bugged me is that todo store its data locally under its installation folder. It might not convenient since that means it can’t be used by multiple user, except each user install its own.
Read more