Thursday, February 16, 2012

Simple Image Gallery in Dart

‹prev | My Chain | next›

Adam Smith has a very nice canvas-based image gallery written in Dart (may take a while to load) up on the githubs. I am still undecided about including SVG / canvas stuff in Dart for Hipsters, but I do think a chapter on animation is in order. I have already experimented with simple animations in Dart, this seems like a good chance to do something a little more interesting.

I start with a list of images:
var images = """
01-4_failures_to_go.png
01-add_comix_form.png
01-add_from_event.png
01-anumation.png
01-asdf_comic.png
01-back_to_funky.png
01-calendar_full_o_appointments.png
// ...
01-whoopsies.png
01-working_in_firefox.png
""";
In my main entry point, I split that string list into an array and create a queue:
main() {
  var q = new Queue.from(images.split("\n"));

  showNext(q);
}
The showNext() function can then pop the first element off the stack, wait for a period of time, and then repeat:
showNext(queue, [last_el]) {
  if (last_el != null) {
    last_el.remove();
  }

  var el = new Element.html("""<img src="images/${queue.removeFirst()}"/>""");
  document.query('#gallery').nodes.add(el);

  if (!queue.isEmpty()) {
    window.setTimeout(() {showNext(queue, last_el: el);}, 1500);
  }
}
And that is enough to get started:


Update: I had a heck of a time getting an animation transition working with this. I factored adding and removing the element out into functions that add/remove with animation:
showNext(queue, [last_el]) {
  removeEl(last_el);

  var el = new Element.html("""<img src="images/${queue.removeFirst()}"/>""");
  addEl(el);

  if (!queue.isEmpty()) {
    window.setTimeout(() {showNext(queue, last_el: el);}, 5*1000);
  }
}
The remove effect worked fine:
removeEl(el) {
  if (el == null) return;

  el.style.transition = 'opacity 1s ease-in-out';
  el.style.opacity = "0";
  window.setTimeout(() {el.remove();}, 1000);
}
I am just doing a simple "ease-in-out" (start and end slow) animation. The problem is the addEl() animation:
addEl(el) {
  el.style.position = 'absolute';
  el.style.opacity = "0";
  document.query('#gallery').nodes.add(el);

  el.style.transition = 'opacity 1s ease-in';
  el.style.opacity = "1";
}
The problem? There is no animation. Instead the element displays immediately. Since it is the newly added element, it immediately covers up the old element. After way too much fiddling, I find that a timeout, even of only a couple of milliseconds allows the transition to work:
addEl(el) {
  el.style.position = 'absolute';
  el.style.opacity = "0";
  document.query('#gallery').nodes.add(el);

  window.setTimeout(() {
    el.style.transition = 'opacity 1s ease-in';
    el.style.opacity = "1";
  }, 2);
}
I lack a good explanation for this. Perhaps it has something to do with adding nodes, but setting the style on elements.



Day #298

2 comments:

  1. Wow this image gallery is great! I need to update mine to be a bit more dynamic and friendly. Maybe something with some NoSQL store. Prob thinking of using the http.dart to run a dart http server and then have it communicate with couchdb but for storing images. The server side shouldn't be to hard to piece together http://goo.gl/vDpSH

    ReplyDelete
    Replies
    1. Ooh! I'll be eager to see how that works. I don't anticipate playing much with server side Dart, but maybe I will if your stuff goes well :D

      Delete