$30 off During Our Annual Pro Sale. View Details »

Killing Characters while Making Art

Killing Characters while Making Art

Dwitter (https://www.dwitter.net) is a collaborative community where members create animated visuals called "dweets" on an HTML canvas element with just 140 or less characters of JavaScript. The boundaries of what can be done within 140 characters is constantly pushed with a mix of algorithm know-how, code sorcery, and creativity. It's one of those cases where constraints can be liberating.

I'll showcase some exemplary dweets and then talk about JavaScript minification techniques and canvas rendering techniques.

Ates Goral

July 25, 2018
Tweet

More Decks by Ates Goral

Other Decks in Programming

Transcript

  1. Kil g C ac s
    w i m i g

    View Slide

  2. Kil g C ac s
    w i m i g
    CreateInTO July 25, 2018
    Ateş Göral aka magna
    @atesgoral magnetiq.ca

    View Slide

  3. Par s o Ch e

    View Slide

  4. When sky is the limit - “build a structure”

    View Slide

  5. Con r s a Cr i t

    View Slide

  6. You can only use sand

    View Slide

  7. You can only use 140 280 characters
    https://twitter.com/googlearts/status/913334566710112256

    View Slide

  8. You can only use 140 characters of JavaScript
    https://twitter.com/justecorruptio/status/950339502567911424

    View Slide

  9. dwitter.net/d/5747 by corruptio
    for(i=h=432;i--;x.fillRect(h+(h/i-1)**.5*S(t-
    i)*i,i,9,44))x.fillStyle=R(v='㓀职뿽흟�巶涷溲疗
    恋 ㆇന䁓 㒄␅ 先р蠂
    '.charCodeAt(i/16)>>i%16&1,v*h,99,C(t-i))
    140

    View Slide

  10. Dwi r - d i t .ne

    View Slide

  11. Dwi r
    d i t .ne
    Dwitter is a social network for
    building and sharing visual
    JavaScript demos limited to 140
    characters.
    Created by Andreas Løve Selvik
    aka lionleaf.
    Inspired by a concept by Sigve
    Sebastian Farstad aka sigveseb.
    Its first official launch was at the
    Solskogen Demoparty in 2016
    where it won the wild compo.

    View Slide

  12. The t Ru t

    View Slide

  13. Dwitter runtime
    // Called 60 times per second
    function u(t) {
    }
    t // Elapsed time in seconds
    S // Shorthand for Math.sin
    C // Shorthand for Math.cos
    T // Shorthand for Math.tan
    R // Generates rgba strings e.g. R(255,255,255,.5)
    c // 1920x1080 canvas
    x // 2D context for that canvas

    View Slide

  14. Sho s !

    View Slide

  15. View Slide

  16. dwitter.net/d/7702 by jylikangas
    for(c.width=i=714;i--;F(t+i/714+(i>>7)/9,-9))
    (F=(a,o)=>x.strokeRect(357+S(a)*290-o/(Z=C(a)
    +1+(t%6<3)),99+C(a*(t/6%4|0))*99/Z,o/=Z/2,o))
    (i,4)
    140

    View Slide

  17. View Slide

  18. dwitter.net/d/4671 by joeytwiddle
    t?c.width=W=200:P=Z=0;for(i=36;i--;j==Z&&(X-9
    9)**2<60?Z=9:Z?onclick=e=>Z--:P++)j=i>>2,x.fi
    llText(j?' ':' ',j?X=j%5*t/i*P/23%W:99,9*(j|
    |Z))
    140

    View Slide

  19. View Slide

  20. dwitter.net/d/915 by sigveseb
    for(n=c.width=i=1e3,s=S(t),k=C(t);i--;x.lineT
    o(n*X/Z,n*Y/Z))F=S(i),U=C(i),V=(i&7)-3,_=V*s+
    F*k,Z=V*k-F*s+15,X=_*k-U*s+7,Y=_*s+U*k+3;x.fi
    ll()
    140

    View Slide

  21. A lot more great examples at:
    https://www.dwitter.net/top

    View Slide

  22. Def Dwe

    View Slide

  23. 112

    View Slide

  24. Default dweet
    c.width=1920 // clear the canvas
    for(i=0;i<9;i++)
    x.fillRect(400+i*100+S(t)*300,400,50,200) // draw 50x200 rects
    112

    View Slide

  25. If I were coding at work
    c.width = 1920; // clear the canvas
    for (i = 0; i < 9; i++) {
    // draw 50x200 rects
    x.fillRect(400 + i * 100 + S(t) * 300, 400, 50, 200);
    }
    +31
    143

    View Slide

  26. Reg Cha t T im g

    View Slide

  27. Remove comments
    c.width = 1920;
    for (i = 0; i < 9; i++) {
    x.fillRect(400 + i * 100 + S(t) * 300, 400, 50, 200);
    }
    -43
    100

    View Slide

  28. Remove white space
    c.width=1920;
    for(i=0;i<9;i++){
    x.fillRect(400+i*100+S(t)*300,400,50,200);
    }
    -24
    76

    View Slide

  29. Remove semicolons and curlies
    c.width=1920
    for(i=0;i<9;i++)x.fillRect(400+i*100+S(t)*300,400,50,200)
    -6
    70

    View Slide

  30. Let’s Go !

    View Slide

  31. Reverse loop
    c.width=1920
    for(i=9;i--;)x.fillRect(400+i*100+S(t)*300,400,50,200)
    // before : for(i=0;i<9;i++)
    // after : for(i=9;i--;)
    -3
    67

    View Slide

  32. Identity operation
    c.width|=0
    for(i=9;i--;)x.fillRect(400+i*100+S(t)*300,400,50,200)
    // before : c.width=1920
    // after : c.width|=0
    // c.width^=0
    // c.width+=0
    // c.width*=1
    -2
    65

    View Slide

  33. Compromise
    // 1920 or 1929. Who cares?
    for(c.width|=i=9;i--;)x.fillRect(400+i*100+S(t)*300,400,50,200)
    // before : c.width|=0⏎
    // after : c.width|=
    -2
    63

    View Slide

  34. 63

    View Slide

  35. Failed attempt at avoiding repetition
    // before
    for(c.width|=i=9;i--;)x.fillRect(400+i*100+S(t)*300,400,50,200)
    // after
    for(c.width|=i=9,w=400;i--;)x.fillRect(w+i*100+S(t)*300,w,50,200)
    // need at least 4 repetitions to save characters
    +2
    65

    View Slide

  36. Pro : fo l

    View Slide

  37. fork loop
    c.width|=0
    fork(i=;i--;)x.fillRect(400+i*100+S(t)*300,400,50,200)
    // Prevent accidental infinite loops while live-editing code
    // by first changing the “for” loop to a “fork” loop.
    // Can’t infinite-loop with a syntax error.

    View Slide

  38. “Jav p i g ”

    View Slide

  39. Depends on who’s using it, how
    ● Can write beautiful code by using the good parts
    ● Can write ugly code
    ● Can write FUGLY code

    View Slide

  40. Fug d o K l g C a c s

    View Slide

  41. Tagged template literals
    // before
    s.split('')
    // after
    s.split``

    View Slide

  42. Cringy math
    // before
    x.arc(a,b,r,0,Math.PI*2)
    // after
    x.arc(a,b,r,0,7)

    View Slide

  43. valueOf
    // before
    r=Math.random;x.arc(r(),r(),r(),r(),r(),r())
    // after
    T.valueOf=Math.random;x.arc(T,T,T,T,T,T)

    View Slide

  44. Browser resiliency
    // before
    x.filter='sepia(100%)'
    // after
    x.filter='sepia('

    View Slide

  45. Som er T c iq

    View Slide

  46. Canvas primitives
    x.fillRect(X,Y,W,H)
    x.arc(X,Y,r,0,7)
    https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D

    View Slide

  47. Direct pixel manipulation
    d=x.getImageData(X,Y,w,h)
    x.putImageData(d,X,Y,w,h)

    View Slide

  48. Text/emoji
    x.fillText(' ',0,16)

    View Slide

  49. Glitching
    c.style.background=`url(${c.toDataURL().replace('c','f')})
    0/100%`

    View Slide

  50. A plethora of know-how
    ● https://github.com/lionleaf/dwitter/wiki
    ● https://github.com/jed/140bytes/wiki/Byte-saving-techniques
    Talk to people:
    ● http://register.jsgolf.club
    ● https://discord.gg/emHe6cP

    View Slide

  51. Som y uf

    View Slide

  52. dwitter.net/u/magna
    ● dwitter.net/d/6494
    ● dwitter.net/d/2516
    ● dwitter.net/d/8740
    ● dwitter.net/d/2385
    ● dwitter.net/d/3271
    ● dwitter.net/d/5716
    ● dwitter.net/d/2177
    ● dwitter.net/d/2378

    View Slide

  53. Tha s!
    @at ra
    I’ll attempt to do some live coding to
    create some new dweets. If you’re
    up for it, do some of your own and
    I’ll be around to help!

    View Slide

  54. Bon : d e p er.ne

    View Slide