diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2018-10-19 03:12:28 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2018-10-19 03:12:28 +0000 |
| commit | c002284371f076997cae8b36dead35ae12da02ec (patch) | |
| tree | 82033a9a0987012f928c11534b5fe0ea2d7db082 | |
| parent | towards self-compiling (diff) | |
| download | mmm-c002284371f076997cae8b36dead35ae12da02ec.tar.gz mmm-c002284371f076997cae8b36dead35ae12da02ec.zip | |
fix all pages
| -rw-r--r-- | Tupfile | 2 | ||||
| -rw-r--r-- | app/center_of_mass.moon | 324 | ||||
| -rw-r--r-- | app/index.moon | 23 | ||||
| -rw-r--r-- | app/test_component.moon | 411 | ||||
| -rw-r--r-- | app/todo.moon | 59 | ||||
| -rw-r--r-- | app/twisted.moon | 68 | ||||
| -rw-r--r-- | client.moon | 1 |
7 files changed, 441 insertions, 447 deletions
@@ -1,4 +1,4 @@ .gitignore -: foreach app/index.moon app/realities.moon |> moon render.moon %B > %o |> dist/%B.html +: foreach app/* |> moon render.moon %B > %o |> dist/%B.html : foreach lib/*.client.moon lib/*.shared.moon |> moonc -o %o %f |> dist/lib/%B.lua diff --git a/app/center_of_mass.moon b/app/center_of_mass.moon index 6e81cd2..845dd97 100644 --- a/app/center_of_mass.moon +++ b/app/center_of_mass.moon @@ -1,167 +1,165 @@ -window = js.global -document = window.document - -import CanvasApp from require 'lib.canvasapp' -import rgb from require 'lib.color' -import h1, p, div, span, input, button from require 'lib.html' - -fast = true -center = true -center_char = do - canvas = document\createElement 'canvas' - ctx = canvas\getContext '2d' - - cache = {} - - (char, font, height) -> - name = "#{char} #{height} #{font}" - return table.unpack cache[name] if cache[name] - - ctx\resetTransform! - ctx.font = "#{height}px #{font}" - width = (ctx\measureText char).width - canvas.width, canvas.height = width, height * 1.2 - - ctx.font = "#{height}px #{font}" - ctx.textBaseline = 'top' - ctx.fillStyle = rgb 0, 0, 0 - ctx\fillText char, 0, 0 - - data = ctx\getImageData 0, 0, width, height * 1.2 - - local xx, yy - if fast - loop = window\eval '(function(data) { - var xx = 0, yy = 0, n = 0; - for (var x = 0; x < data.width - 1; x++) { - for (var y = 0; y < data.height - 1; y++) { - var i = y * (data.width * 4) + x * 4; - var alpha = data.data[i + 3] / 255; - xx += x * alpha; - yy += y * alpha; - n += alpha; +on_client -> + import CanvasApp from require 'lib.canvasapp' + import rgb from require 'lib.color' + import h1, p, div, span, input, button from require 'lib.html' + + fast = true + center = true + center_char = do + canvas = document\createElement 'canvas' + ctx = canvas\getContext '2d' + + cache = {} + + (char, font, height) -> + name = "#{char} #{height} #{font}" + return table.unpack cache[name] if cache[name] + + ctx\resetTransform! + ctx.font = "#{height}px #{font}" + width = (ctx\measureText char).width + canvas.width, canvas.height = width, height * 1.2 + + ctx.font = "#{height}px #{font}" + ctx.textBaseline = 'top' + ctx.fillStyle = rgb 0, 0, 0 + ctx\fillText char, 0, 0 + + data = ctx\getImageData 0, 0, width, height * 1.2 + + local xx, yy + if fast + loop = window\eval '(function(data) { + var xx = 0, yy = 0, n = 0; + for (var x = 0; x < data.width - 1; x++) { + for (var y = 0; y < data.height - 1; y++) { + var i = y * (data.width * 4) + x * 4; + var alpha = data.data[i + 3] / 255; + xx += x * alpha; + yy += y * alpha; + n += alpha; + } } - } - - xx /= n; - yy /= n; - return [xx, yy]; - })' - res = loop nil, data - xx, yy = res[0], res[1] - else - xx, yy, n = 0, 0, 0 - for x = 0, data.width - 1 - for y = 0, data.height - 1 - i = y * (data.width * 4) + x * 4 - alpha = data.data[i + 3] / 255 - xx += x * alpha - yy += y * alpha - n += alpha - - xx /= n - yy /= n - cache[name] = { xx, yy, width } - xx, yy, width - -class CenterOfMass extends CanvasApp - width: window.innerWidth - 20 - height: 300 - new: (text, @font, @size) => - super! - @text = {} - for i = 1,#text - @add text\sub i, i - - add: (char) => - rcx, rcy, w = center_char char, @font, @size - cx, cy = w/2, @size/2 - vx, vy = 0, 0 - table.insert @text, { - :char, :rcx, :rcy, :w - :cx, :cy, :vx, :vy + + xx /= n; + yy /= n; + return [xx, yy]; + })' + res = loop nil, data + xx, yy = res[0], res[1] + else + xx, yy, n = 0, 0, 0 + for x = 0, data.width - 1 + for y = 0, data.height - 1 + i = y * (data.width * 4) + x * 4 + alpha = data.data[i + 3] / 255 + xx += x * alpha + yy += y * alpha + n += alpha + + xx /= n + yy /= n + cache[name] = { xx, yy, width } + xx, yy, width + + class CenterOfMass extends CanvasApp + width: window.innerWidth - 20 + height: 300 + new: (text, @font, @size) => + super! + @text = {} + for i = 1,#text + @add text\sub i, i + + add: (char) => + rcx, rcy, w = center_char char, @font, @size + cx, cy = w/2, @size/2 + vx, vy = 0, 0 + table.insert @text, { + :char, :rcx, :rcy, :w + :cx, :cy, :vx, :vy + } + + refresh: => + for char in *@text + char.rcx, char.rcy, char.w = center_char char.char, @font, @size + + keydown: (key) => + if key == "Backspace" or key == "Delete" + table.remove @text + elseif string.len(key) == 1 + @add key + + update: (dt) => + super dt + + ACCEL = 4 * dt + DAMPING = 8 * dt + + for char in *@text + { :rcx, :rcy, :cx, :cy, :w } = char + if not center + rcx, rcy = w/2, @size/2 + dx, dy = rcx - cx, rcy - cy + char.vx += dx * ACCEL + char.vy += dy * ACCEL + char.cx += char.vx + char.cy += char.vy + char.vx *= DAMPING + char.vy *= DAMPING + + draw: => + @ctx\clearRect 0, 0, @width, @height + + @ctx.font = "#{@size}px #{@font}" + @ctx.textBaseline = 'top' + + x, y = @size * .1, @size + for { :char, :cx, :cy, :w } in *@text + if x + w > @width + x = 0 + y += @size * 1.2 + + @ctx\fillText char, x + w/2 - cx, y - cy + x += w + + append h1 'Fonts aligned by Center-of-Mass' + app = CenterOfMass "Click here and type Away!", "Times New Roman", 40 + append app.canvas + app.canvas.style.backgroundColor = '#eee' + + add = => + append div { + span 'font: ', + with @font_input = input! + .type = 'text' + .value = 'Times New Roman' + with button 'set' + .onclick = (_, e) -> + app.font = @font_input.value + app\refresh! } - refresh: => - for char in *@text - char.rcx, char.rcy, char.w = center_char char.char, @font, @size - - keydown: (key) => - if key == "Backspace" or key == "Delete" - table.remove @text - elseif string.len(key) == 1 - @add key - - update: (dt) => - super dt - - ACCEL = 4 * dt - DAMPING = 8 * dt - - for char in *@text - { :rcx, :rcy, :cx, :cy, :w } = char - if not center - rcx, rcy = w/2, @size/2 - dx, dy = rcx - cx, rcy - cy - char.vx += dx * ACCEL - char.vy += dy * ACCEL - char.cx += char.vx - char.cy += char.vy - char.vx *= DAMPING - char.vy *= DAMPING - - draw: => - @ctx\clearRect 0, 0, @width, @height - - @ctx.font = "#{@size}px #{@font}" - @ctx.textBaseline = 'top' - - x, y = @size * .1, @size - for { :char, :cx, :cy, :w } in *@text - if x + w > @width - x = 0 - y += @size * 1.2 - - @ctx\fillText char, x + w/2 - cx, y - cy - x += w - -append h1 'Fonts aligned by Center-of-Mass' -app = CenterOfMass "Click here and type Away!", "Times New Roman", 40 -append app.canvas -app.canvas.style.backgroundColor = '#eee' - -add = => - append div { - span 'font: ', - with @font_input = input! - .type = 'text' - .value = 'Times New Roman' - with button 'set' - .onclick = (_, e) -> - app.font = @font_input.value + append div { + span 'size: ', + input type: 'range', min: 2, max: 120, value: 40, onchange: (_, e) -> + size = e.target.value + @size_label.innerText = size + app.size = size app\refresh! - } - - append div { - span 'size: ', - input type: 'range', min: 2, max: 120, value: 40, onchange: (_, e) -> - size = e.target.value - @size_label.innerText = size - app.size = size - app\refresh! - with @size_label = span '40' - '' - } - - append div { - span 'center characters by weight: ', - input type: 'checkbox', checked: center, onchange: (_, e) -> - center = e.target.checked - } - - append div { - span 'optimize inner loop: ', - input type: 'checkbox', checked: fast, onchange: (_, e) -> - fast = e.target.checked - } -add {} + with @size_label = span '40' + '' + } + + append div { + span 'center characters by weight: ', + input type: 'checkbox', checked: center, onchange: (_, e) -> + center = e.target.checked + } + + append div { + span 'optimize inner loop: ', + input type: 'checkbox', checked: fast, onchange: (_, e) -> + fast = e.target.checked + } + add {} diff --git a/app/index.moon b/app/index.moon index 3f4e80c..3e79c60 100644 --- a/app/index.moon +++ b/app/index.moon @@ -1,5 +1,3 @@ -require = relative ... - on_client -> import h1, p, a, br, ul, tt, li from require 'lib.html' @@ -8,22 +6,21 @@ on_client -> 'twisted': 'canvas animation', 'todo': 'Todo demo of a simple reactive UI framework', 'realities': 'draft of a paper on virtual and other realities', - 'center-of-mass': 'aligning characters by their centers of mass', - 'test-component': 'Test suite for the UI framework', - 'play-tags': 'Playground for Functional Tags', + 'center_of_mass': 'aligning characters by their centers of mass', + 'test_component': 'Test suite for the UI framework', + 'tags': 'Playground for Functional Tags', + + redirs = + 'center-of-mass': 'center_of_mass', + 'test-component': 'test_component', + 'play-tags': 'tags', back_button = -> append p a { '< back', href: '/' } if window.location.search and #window.location.search > 1 name = window.location.search\sub 2 - if demos[name] - back_button! - filename = name\gsub '-', '_' - require "app.#{filename}" - else - append h1 'are you lost?' - append p a { '(go home)', href: '/' } + window.location.href = "#{redirs[name] or name}.html" else append h1 'mmm' append p { @@ -40,7 +37,7 @@ on_client -> } append p 'current demos:' append ul for name, desc in pairs demos - li (a name, href: "/?#{name}"), ': ', desc + li (a name, href: "/#{name}.html"), ': ', desc append p { "made with #{moon} by " diff --git a/app/test_component.moon b/app/test_component.moon index 78556a2..dba511b 100644 --- a/app/test_component.moon +++ b/app/test_component.moon @@ -1,205 +1,206 @@ -import div, h1, ul, li, pre from require 'lib.html' - -last = nil -test_group = (name) -> - if last - append div (h1 name), ul last - - last = {} - (name, test) -> - ok, err = pcall test - table.insert last, li if ok - "passed '#{name}'" - else - "failed '#{name}'", pre err - -expect = (expected, note, ...) -> - ok, msg = pcall ... - print ok, msg\find expected - if ok or not msg\find expected - error note - -run_test = test_group 'component.moon' - -local ReactiveVar, ReactiveElement -run_test "exports ReactiveVar, ReactiveElement", -> - import ReactiveVar, ReactiveElement from require 'app.component' - assert ReactiveVar, "ReactiveVar not exported" - assert ReactiveElement, "ReactiveElement not exported" - -run_test "exports tohtml helper", -> - import tohtml from require 'app.component' - assert 'function' == (type tohtml), "tohtml not exported" - -run_test "exports append helper", -> - import append from require 'app.component' - assert 'function' == (type append), "append not exported" - -run_test "exports text helper", -> - import text from require 'app.component' - assert 'function' == (type text), "text not exported" - - node = text 'a test string' - assert (js.instanceof node, js.global.Node), "expected text to generate a Node" - assert node.data == 'a test string', "expected text to store the string" - -run_test "text joins multiple arguments", -> - import text from require 'app.component' - - node = text 'a', 'test', 'string' - assert node.data == 'a test string', "expected text to join arguments with spaces" - -run_test = test_group 'ReactiveVar' - -run_test "stores a value", -> - reactive = ReactiveVar 'test' - assert 'test' == reactive\get!, "expected x to be 'test'" - -run_test "propagates updates", -> - local done - - reactive = ReactiveVar 'test' - reactive\subscribe coroutine.wrap (next) -> - assert next == 'toast', "expected next to be 'toast'" - assert coroutine.yield! == 'cheese', "expected next to be 'cheese'" - done = true - - reactive\set 'toast' - assert 'toast' == reactive\get!, "expected #get to return 'toast'" - reactive\set 'cheese' - assert done, "expected to reach the end" - -run_test "passed old value as well", -> - local done - - reactive = ReactiveVar 1 - reactive\subscribe coroutine.wrap (next, last) -> - assert last == 1, "expected last:1 to be 1" - next, last = coroutine.yield! - assert last == 2, "expected last:2 to be 2" - done = true - - reactive\set 2 - reactive\set 3 - assert done, "expected to reach the end" - -run_test "provides transform shorthand", -> - local done - - reactive = ReactiveVar 1 - reactive\subscribe coroutine.wrap (next, last) -> - assert last == 1, "expected last:1 to be 1" - next, last = coroutine.yield! - assert last == 2, "expected last:2 to be 2" - done = true - - add_one = (a) -> a + 1 - reactive\transform add_one - reactive\transform add_one - assert done, "expected to reach the end" - -run_test "#subscribe returns function to unsubscribe", -> - calls = 0 - - reactive = ReactiveVar 1 - unsub = reactive\subscribe coroutine.wrap () -> - calls += 1 - coroutine.yield! - calls += 1 - coroutine.yield! - calls += 1 - - assert 'function' == (type unsub), "expected to receive a function" - - reactive\set 2 - reactive\set 3 - assert calls == 2, "wat" - - unsub! - reactive\set 4 - assert calls == 2, "expected to stop receiving updates" - -run_test "tracks multiple subscriptions at once", -> - reactive = ReactiveVar 'test' - unsub = reactive\subscribe coroutine.wrap (next) -> - assert next == 'toast', "expected next to be toast" - next = coroutine.yield! - assert next == 'cheese', "expected next to be cheese" - coroutine.yield! - error "expected not to get here" - - reactive\set 'toast' - - local done - reactive\subscribe coroutine.wrap (next) -> - assert next == 'cheese', "expected next to be cheese" - next = coroutine.yield! - assert next == 'test', "expected next to be test" - done = true - - reactive\set 'cheese' - unsub! - reactive\set 'test' - assert done, "expected to reach the end" - -run_test = test_group 'ReactiveElement' - -run_test "creates a HTML element", -> - elem = ReactiveElement 'span' - assert elem.node and elem.node.localName == 'span', "expected Node to be a <span>" - -run_test "sets attributes from a table arg", -> - elem = ReactiveElement 'span', class: 'never' - assert elem.node.class == 'never', "expected class to be 'never'" - -run_test "appends Nodes from arguments", -> - e_div, e_pre = div!, pre! - elem = ReactiveElement 'span', e_div, e_pre - assert elem.node.firstElementChild == e_div, "expected div to be the first child of elem" - assert elem.node.lastElementChild == e_pre, "expected pre to be the last child of elem" - -run_test "can append ReactiveElements and text", -> - e_div = ReactiveElement 'div' - elem = ReactiveElement 'div', e_div, 'testtext' - assert elem.node.firstElementChild == e_div.node, "expected div to be the first child of elem" - assert elem.node.lastChild.data == 'testtext', "expected last child of elem to be 'testtext'" - -run_test "accepts attributes after children", -> - e_div = div! - elem = ReactiveElement 'div', e_div, class: 'test' - assert elem.node.firstElementChild == e_div, "expected div to be the first child of elem" - assert elem.node.class == 'test', "expected class to be 'test'" - -run_test "allows mixing attributes and children in a single table", -> - e_div, e_pre = div!, pre! - elem = ReactiveElement 'div', { class: 'test', e_div, e_pre } - assert elem.node.firstElementChild == e_div, "expected div to be the first child of elem" - assert elem.node.lastElementChild == e_pre, "expected pre to be the last child of elem" - assert elem.node.class == 'test', "expected class to be 'test'" - -run_test "can unwrap and track attributes from ReactiveVars", -> - klass = ReactiveVar 'test' - elem = ReactiveElement 'div', class: klass - assert elem.node.class == 'test', "expected class to be 'test'" - klass\set 'toast' - assert elem.node.class == 'toast', "expected class to be 'toast'" - -run_test "can unwrap and track children from ReactiveVars", -> - child = ReactiveVar h1 'test' - elem = ReactiveElement 'div', child, pre 'fixed' - assert elem.node.firstElementChild.localName == 'h1', "expected first child to be h1" - assert elem.node.childElementCount == 2, "expected node to have two children" - child\set div 'toast' - assert elem.node.firstElementChild.localName == 'div', "expected first child to be div" - assert elem.node.childElementCount == 2, "expected node to have two children" - -run_test "warns when appending a string from a ReactiveVar", -> - import text from require 'app.component' - - str = ReactiveVar 'test' - elem = ReactiveElement 'div', str - expect 'cannot replace string node', 'expected error', str\set, 'string too' - elem\destroy! - - elem = ReactiveElement 'div', str\map text - str\set 'this is text' +on_client -> + import div, h1, ul, li, pre from require 'lib.html' + + last = nil + test_group = (name) -> + if last + append div (h1 name), ul last + + last = {} + (name, test) -> + ok, err = pcall test + table.insert last, li if ok + "passed '#{name}'" + else + "failed '#{name}'", pre err + + expect = (expected, note, ...) -> + ok, msg = pcall ... + print ok, msg\find expected + if ok or not msg\find expected + error note + + run_test = test_group 'component.moon' + + local ReactiveVar, ReactiveElement + run_test "exports ReactiveVar, ReactiveElement", -> + import ReactiveVar, ReactiveElement from require 'lib.component' + assert ReactiveVar, "ReactiveVar not exported" + assert ReactiveElement, "ReactiveElement not exported" + + run_test "exports tohtml helper", -> + import tohtml from require 'lib.component' + assert 'function' == (type tohtml), "tohtml not exported" + + run_test "exports append helper", -> + import append from require 'lib.component' + assert 'function' == (type append), "append not exported" + + run_test "exports text helper", -> + import text from require 'lib.component' + assert 'function' == (type text), "text not exported" + + node = text 'a test string' + assert (js.instanceof node, js.global.Node), "expected text to generate a Node" + assert node.data == 'a test string', "expected text to store the string" + + run_test "text joins multiple arguments", -> + import text from require 'lib.component' + + node = text 'a', 'test', 'string' + assert node.data == 'a test string', "expected text to join arguments with spaces" + + run_test = test_group 'ReactiveVar' + + run_test "stores a value", -> + reactive = ReactiveVar 'test' + assert 'test' == reactive\get!, "expected x to be 'test'" + + run_test "propagates updates", -> + local done + + reactive = ReactiveVar 'test' + reactive\subscribe coroutine.wrap (next) -> + assert next == 'toast', "expected next to be 'toast'" + assert coroutine.yield! == 'cheese', "expected next to be 'cheese'" + done = true + + reactive\set 'toast' + assert 'toast' == reactive\get!, "expected #get to return 'toast'" + reactive\set 'cheese' + assert done, "expected to reach the end" + + run_test "passed old value as well", -> + local done + + reactive = ReactiveVar 1 + reactive\subscribe coroutine.wrap (next, last) -> + assert last == 1, "expected last:1 to be 1" + next, last = coroutine.yield! + assert last == 2, "expected last:2 to be 2" + done = true + + reactive\set 2 + reactive\set 3 + assert done, "expected to reach the end" + + run_test "provides transform shorthand", -> + local done + + reactive = ReactiveVar 1 + reactive\subscribe coroutine.wrap (next, last) -> + assert last == 1, "expected last:1 to be 1" + next, last = coroutine.yield! + assert last == 2, "expected last:2 to be 2" + done = true + + add_one = (a) -> a + 1 + reactive\transform add_one + reactive\transform add_one + assert done, "expected to reach the end" + + run_test "#subscribe returns function to unsubscribe", -> + calls = 0 + + reactive = ReactiveVar 1 + unsub = reactive\subscribe coroutine.wrap () -> + calls += 1 + coroutine.yield! + calls += 1 + coroutine.yield! + calls += 1 + + assert 'function' == (type unsub), "expected to receive a function" + + reactive\set 2 + reactive\set 3 + assert calls == 2, "wat" + + unsub! + reactive\set 4 + assert calls == 2, "expected to stop receiving updates" + + run_test "tracks multiple subscriptions at once", -> + reactive = ReactiveVar 'test' + unsub = reactive\subscribe coroutine.wrap (next) -> + assert next == 'toast', "expected next to be toast" + next = coroutine.yield! + assert next == 'cheese', "expected next to be cheese" + coroutine.yield! + error "expected not to get here" + + reactive\set 'toast' + + local done + reactive\subscribe coroutine.wrap (next) -> + assert next == 'cheese', "expected next to be cheese" + next = coroutine.yield! + assert next == 'test', "expected next to be test" + done = true + + reactive\set 'cheese' + unsub! + reactive\set 'test' + assert done, "expected to reach the end" + + run_test = test_group 'ReactiveElement' + + run_test "creates a HTML element", -> + elem = ReactiveElement 'span' + assert elem.node and elem.node.localName == 'span', "expected Node to be a <span>" + + run_test "sets attributes from a table arg", -> + elem = ReactiveElement 'span', class: 'never' + assert elem.node.class == 'never', "expected class to be 'never'" + + run_test "appends Nodes from arguments", -> + e_div, e_pre = div!, pre! + elem = ReactiveElement 'span', e_div, e_pre + assert elem.node.firstElementChild == e_div, "expected div to be the first child of elem" + assert elem.node.lastElementChild == e_pre, "expected pre to be the last child of elem" + + run_test "can append ReactiveElements and text", -> + e_div = ReactiveElement 'div' + elem = ReactiveElement 'div', e_div, 'testtext' + assert elem.node.firstElementChild == e_div.node, "expected div to be the first child of elem" + assert elem.node.lastChild.data == 'testtext', "expected last child of elem to be 'testtext'" + + run_test "accepts attributes after children", -> + e_div = div! + elem = ReactiveElement 'div', e_div, class: 'test' + assert elem.node.firstElementChild == e_div, "expected div to be the first child of elem" + assert elem.node.class == 'test', "expected class to be 'test'" + + run_test "allows mixing attributes and children in a single table", -> + e_div, e_pre = div!, pre! + elem = ReactiveElement 'div', { class: 'test', e_div, e_pre } + assert elem.node.firstElementChild == e_div, "expected div to be the first child of elem" + assert elem.node.lastElementChild == e_pre, "expected pre to be the last child of elem" + assert elem.node.class == 'test', "expected class to be 'test'" + + run_test "can unwrap and track attributes from ReactiveVars", -> + klass = ReactiveVar 'test' + elem = ReactiveElement 'div', class: klass + assert elem.node.class == 'test', "expected class to be 'test'" + klass\set 'toast' + assert elem.node.class == 'toast', "expected class to be 'toast'" + + run_test "can unwrap and track children from ReactiveVars", -> + child = ReactiveVar h1 'test' + elem = ReactiveElement 'div', child, pre 'fixed' + assert elem.node.firstElementChild.localName == 'h1', "expected first child to be h1" + assert elem.node.childElementCount == 2, "expected node to have two children" + child\set div 'toast' + assert elem.node.firstElementChild.localName == 'div', "expected first child to be div" + assert elem.node.childElementCount == 2, "expected node to have two children" + + run_test "warns when appending a string from a ReactiveVar", -> + import text from require 'lib.component' + + str = ReactiveVar 'test' + elem = ReactiveElement 'div', str + expect 'cannot replace string node', 'expected error', str\set, 'string too' + elem\destroy! + + elem = ReactiveElement 'div', str\map text + str\set 'this is text' diff --git a/app/todo.moon b/app/todo.moon index 2173087..5a1aa47 100644 --- a/app/todo.moon +++ b/app/todo.moon @@ -1,33 +1,34 @@ -import ReactiveVar, append, text, div, form, span, h3, a, input, textarea, button from require 'lib.component' +on_client -> + import ReactiveVar, append, text, div, form, span, h3, a, input, textarea, button from require 'lib.component' -parent = div! -todoItem = (desc, done) -> - -- convert into reactive data sources - desc, done = (ReactiveVar desc), ReactiveVar done - with me = div style: - margin: '8px' - padding: '8px' - background: '#eeeeee' - \append h3 (desc\map text), style: 'margin: 0;' - \append span done\map (done) -> text if done then 'done' else 'not done yet' - \append input type: 'checkbox', checked: done, onchange: (e) => done\set e.target.checked - \append a (text 'delete'), href: '#', onclick: (e) => parent\remove me + parent = div! + todoItem = (desc, done) -> + -- convert into reactive data sources + desc, done = (ReactiveVar desc), ReactiveVar done + with me = div style: + margin: '8px' + padding: '8px' + background: '#eeeeee' + \append h3 (desc\map text), style: 'margin: 0;' + \append span done\map (done) -> text if done then 'done' else 'not done yet' + \append input type: 'checkbox', checked: done, onchange: (e) => done\set e.target.checked + \append a (text 'delete'), href: '#', onclick: (e) => parent\remove me -parent\append todoItem 'write a Component System' -parent\append todoItem 'eat Lasagna', true + parent\append todoItem 'write a Component System' + parent\append todoItem 'eat Lasagna', true -desc = ReactiveVar 'start' -form = with form { - action: '' - style: - margin: '2px' - onsubmit: (e) => - e\preventDefault! - parent\append todoItem desc\get! - desc\set '' - } - \append input type: 'text', value: desc, onchange: (e) => desc\set e.target.value - \append input type: 'submit', value: 'add' + desc = ReactiveVar 'start' + form = with form { + action: '' + style: + margin: '2px' + onsubmit: (e) => + e\preventDefault! + parent\append todoItem desc\get! + desc\set '' + } + \append input type: 'text', value: desc, onchange: (e) => desc\set e.target.value + \append input type: 'submit', value: 'add' -append parent -append form + append parent + append form diff --git a/app/twisted.moon b/app/twisted.moon index 5c34914..e90eda3 100644 --- a/app/twisted.moon +++ b/app/twisted.moon @@ -1,41 +1,39 @@ -window = js.global -document = window.document +on_client -> + Math = window.Math -Math = window.Math + import CanvasApp from require 'lib.canvasapp' + import hsl from require 'lib.color' -import CanvasApp from require 'lib.canvasapp' -import hsl from require 'lib.color' + class TwistedDemo extends CanvasApp + width: 500 + height: 400 + length: math.pi * 4 + new: => + super! + @background = {Math.random!, Math.random!/3+.2, Math.random!/4} + hue = Math.random! + @shades = setmetatable {}, __index: (key) => + with val = { hue, .7, key * .3 + .1} do rawset @, key, val -class TwistedDemo extends CanvasApp - width: 500 - height: 400 - length: math.pi * 4 - new: => - super! - @background = {Math.random!, Math.random!/3+.2, Math.random!/4} - hue = Math.random! - @shades = setmetatable {}, __index: (key) => - with val = { hue, .7, key * .3 + .1} do rawset @, key, val + draw: => + @ctx.fillStyle = hsl @background + @ctx\fillRect 0, 0, @width, @height + @ctx\translate @width/2, @height/2 + 70 - draw: => - @ctx.fillStyle = hsl @background - @ctx\fillRect 0, 0, @width, @height - @ctx\translate @width/2, @height/2 + 70 + draw = (i) -> + @ctx\save! + @ctx\translate 0, -120*i + s = 1 - 0.1 * math.sin @time + i*2 + s *= 0.8 - i * .4 * math.cos @time + @ctx\scale s, s/2 + @ctx\rotate @time/4 + i * .6 * math.cos @time + @ctx.fillStyle = hsl table.unpack @shades[i] + @ctx\fillRect -80, -80, 160, 160 + @ctx\restore! - draw = (i) -> - @ctx\save! - @ctx\translate 0, -120*i - s = 1 - 0.1 * math.sin @time + i*2 - s *= 0.8 - i * .4 * math.cos @time - @ctx\scale s, s/2 - @ctx\rotate @time/4 + i * .6 * math.cos @time - @ctx.fillStyle = hsl table.unpack @shades[i] - @ctx\fillRect -80, -80, 160, 160 - @ctx\restore! + for i=0,1,1/(20 + 19 * math.sin(@time / 2)) + draw i + draw 1 - for i=0,1,1/(20 + 19 * math.sin(@time / 2)) - draw i - draw 1 - -twisted = TwistedDemo! -document.body\appendChild twisted.canvas + twisted = TwistedDemo! + document.body\appendChild twisted.canvas diff --git a/client.moon b/client.moon index d6fd433..dd2ee12 100644 --- a/client.moon +++ b/client.moon @@ -1,7 +1,6 @@ export MODE, print, warn, relative, append, on_client export window, document - window = js.global document = window.document |
