diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2019-09-21 13:34:39 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2019-09-21 13:34:39 +0000 |
| commit | fcff21bb78214790041cfc189c5c0c18a88b6d9e (patch) | |
| tree | c63304302792b3a290b034ce3a0ca3b4902efeb0 | |
| parent | fix code font (diff) | |
| download | mmm-fcff21bb78214790041cfc189c5c0c18a88b6d9e.tar.gz mmm-fcff21bb78214790041cfc189c5c0c18a88b6d9e.zip | |
add btrktrl, parallax_panels
33 files changed, 142 insertions, 244 deletions
diff --git a/mmm/dom/init.server.moon b/mmm/dom/init.server.moon index fedd109..2ddce33 100644 --- a/mmm/dom/init.server.moon +++ b/mmm/dom/init.server.moon @@ -27,6 +27,12 @@ element = (element) -> (...) -> if #children == 0 children = attributes + for i,v in ipairs children + if 'string' != type v + print v + error "wrong type: #{type v}" + children[i] = '' unless v + if void_tags[element] assert #children == 0, "void tag #{element} cannot have children!" b .. ">" diff --git a/mmm/mmmfs/browser.moon b/mmm/mmmfs/browser.moon deleted file mode 100644 index 379537e..0000000 --- a/mmm/mmmfs/browser.moon +++ /dev/null @@ -1,241 +0,0 @@ -require = relative ..., 1 -import Key from require '.fileder' -import converts, get_conversions, apply_conversions from require '.conversion' -import ReactiveVar, get_or_create, text, elements from require 'mmm.component' -import pre, div, nav, span, button, a, select, option from elements -import languages from require 'mmm.highlighting' - -keep = (var) -> - last = var\get! - var\map (val) -> - last = val or last - last - -code_cast = (lang) -> - { - inp: "text/#{lang}.*", - out: 'mmm/dom', - transform: (val) -> languages[lang] val - } - -casts = { - code_cast 'javascript', - code_cast 'moonscript', - code_cast 'lua', - code_cast 'markdown', - code_cast 'html', - { - inp: 'text/plain' - out: 'mmm/dom' - transform: (val) -> text val - } -} - -for convert in *converts - table.insert casts, convert - -class Browser - new: (@root, path='', rehydrate=false) => - -- root fileder - assert @root, 'root fileder is nil' - - -- active path - @path = ReactiveVar path - - -- update URL bar - if MODE == 'CLIENT' - logo = document\querySelector 'header h1 > svg' - spin = -> - logo.classList\add 'spin' - logo.parentElement.offsetWidth - logo.classList\remove 'spin' - @path\subscribe (path) -> - document.body.classList\add 'loading' - spin! - - return if @skip - vis_path = path .. (if '/' == path\sub -1 then '' else '/') - window.history\pushState path, '', vis_path - - window.onpopstate = (_, event) -> - if event.state - @skip = true - @path\set event.state - @skip = nil - - -- active fileder - -- (re)set every time @path changes - @active = @path\map @root\walk - - -- currently active facet - -- (re)set to default when @active changes - @facet = @active\map (fileder) -> - return unless fileder - last = @facet and @facet\get! - Key if last then last.type else 'mmm/dom' - - -- whether inspect tab is active - @inspect = ReactiveVar (MODE == 'CLIENT' and window.location.search\match '[?&]inspect') - - -- retrieve or create the wrapper and main elements - main = get_or_create 'div', 'browser-root', class: 'main view' - - -- prepend the navbar - if MODE == 'SERVER' - main\append nav { id: 'browser-navbar', span 'please stand by... interactivity loading :)' } - else - main\prepend with get_or_create 'nav', 'browser-navbar' - .node.innerHTML = '' - \append span 'path: ', @path\map (path) -> with div class: 'path', style: { display: 'inline-block' } - path_segment = (name, href) -> - a name, :href, onclick: (_, e) -> - e\preventDefault! - @navigate href - - href = '' - path = path\match '^/(.*)' - - \append path_segment 'root', '' - - while path - name, rest = path\match '^([%w%-_%.]+)/(.*)' - if not name - name = path - - path = rest - href = "#{href}/#{name}" - - \append '/' - \append path_segment name, href - - \append span 'view facet:', style: { 'margin-right': '0' } - \append @active\map (fileder) -> - onchange = (_, e) -> - { :type } = @facet\get! - @facet\set Key name: e.target.value, :type - - current = @facet\get! - current = current and current.name - with select :onchange, disabled: not fileder - has_main = fileder and fileder\find current.name, '.*' - \append option '(main)', value: '', disabled: not has_main, selected: current == '' - if fileder - for i, value in ipairs fileder\get_facets! - continue if value == '' - \append option value, :value, selected: value == current - \append @inspect\map (enabled) -> - if not enabled - button 'inspect', onclick: (_, e) -> @inspect\set true - - @error = ReactiveVar! - main\append with get_or_create 'div', 'browser-error', class: @error\map (e) -> if e then 'error-wrap' else 'error-wrap empty' - \append (span "an error occured while rendering this view:"), (rehydrate and .node.firstChild) - \append @error - - -- append or patch #browser-content - main\append with get_or_create 'div', 'browser-content', class: 'content' - content = ReactiveVar if rehydrate then .node.lastChild else @get_content @facet\get! - \append keep content - if MODE == 'CLIENT' - @facet\subscribe (p) -> - window\setTimeout (-> content\set @get_content p), 150 - - if rehydrate - -- force one rerender to set onclick handlers etc - @facet\set @facet\get! - - inspector = @inspect\map (enabled) -> if enabled then @get_inspector! - - -- export mmm/component interface - wrapper = get_or_create 'div', 'browser-wrapper', main, inspector, class: 'browser' - @node = wrapper.node - @render = wrapper\render - - err_and_trace = (err) -> err, debug.traceback! - default_convert = (key) => @get key.name, 'mmm/dom' - - -- render #browser-content - get_content: (prop, err=@error, convert=default_convert) => - clear_error = -> - err\set! if MODE == 'CLIENT' - disp_error = (msg) -> - if MODE == 'CLIENT' - err\set pre msg - warn "ERROR rendering content: #{msg}" - nil - - active = @active\get! - - return disp_error "fileder not found!" unless active - return disp_error "facet not found!" unless prop - - ok, res, trace = xpcall convert, err_and_trace, active, prop - - document.body.classList\remove 'loading' if MODE == 'CLIENT' - - if ok and res - clear_error! - res - elseif ok - div "[no conversion path to #{prop.type}]" - elseif res and res.match and res\match '%[nossr%]$' - div "[this page could not be pre-rendered on the server]" - else - if trace - res = "#{res}\n#{trace}" - disp_error res - - get_inspector: => - -- active facet in inspect tab - -- (re)set to match when @facet changes - @inspect_prop = @facet\map (prop) -> - active = @active\get! - key = active and active\find prop - key = key.original if key and key.original - key - - @inspect_err = ReactiveVar! - - with div class: 'view inspector' - \append nav { - span 'inspector' - @inspect_prop\map (current) -> - current = current and current\tostring! - fileder = @active\get! - - onchange = (_, e) -> - return if e.target.value == '' - { :name } = @facet\get! - @inspect_prop\set Key e.target.value - - with select :onchange - \append option '(none)', value: '', disabled: true, selected: not value - if fileder - for key, _ in pairs fileder.facets - value = key\tostring! - \append option value, :value, selected: value == current - @inspect\map (enabled) -> - if enabled - button 'close', onclick: (_, e) -> @inspect\set false - } - \append with div class: @inspect_err\map (e) -> if e then 'error-wrap' else 'error-wrap empty' - \append span "an error occured while rendering this view:" - \append @inspect_err - \append with pre class: 'content' - \append keep @inspect_prop\map (prop, old) -> - @get_content prop, @inspect_err, (prop) => - value, key = @get prop - assert key, "couldn't @get #{prop}" - - conversions = get_conversions 'mmm/dom', key.type, casts - assert conversions, "cannot cast '#{key.type}'" - apply_conversions conversions, value, @, prop - - default_convert = (key) => @get key.name, 'mmm/dom' - - navigate: (new) => - @path\set new - -{ - :Browser -} diff --git a/mmm/mmmfs/conversion.moon b/mmm/mmmfs/conversion.moon index a37ee0b..dc301eb 100644 --- a/mmm/mmmfs/conversion.moon +++ b/mmm/mmmfs/conversion.moon @@ -1,5 +1,5 @@ import div, code, img, video, blockquote, a, span, source, iframe from require 'mmm.dom' -import find_fileder, embed from (require 'mmm.mmmfs.util') require 'mmm.dom' +import find_fileder, link_to, embed from (require 'mmm.mmmfs.util') require 'mmm.dom' import tohtml from require 'mmm.component' -- fix JS null values @@ -42,7 +42,24 @@ converts = { out: 'mmm/dom', transform: if MODE == 'SERVER' (html, fileder) -> - html\gsub '<mmm%-embed%s+(.-)></mmm%-embed>', (attrs) -> + html = html\gsub '<mmm%-link%s+(.-)>(.-)</mmm%-link>', (attrs, text) -> + text = nil if #text == 0 + path = '' + while attrs and attrs != '' + key, val, _attrs = attrs\match '^(%w+)="([^"]-)"%s*(.*)' + if not key + key, _attrs = attrs\match '^(%w+)%s*(.*)$' + val = true + + attrs = _attrs + + switch key + when 'path' then path = val + else warn "unkown attribute '#{key}=\"#{val}\"' in <mmm-link>" + + link_to path, text, fileder + + html = html\gsub '<mmm%-embed%s+(.-)></mmm%-embed>', (attrs) -> path, facet = '', '' opts = {} while attrs and attrs != '' @@ -60,6 +77,8 @@ converts = { else warn "unkown attribute '#{key}=\"#{val}\"' in <mmm-embed>" embed path, facet, fileder, opts + + html else (html, fileder) -> parent = with document\createElement 'div' @@ -75,6 +94,14 @@ converts = { element\replaceWith embed path or '', facet or '', fileder, { :nolink } + embeds = \getElementsByTagName 'mmm-link' + embeds = [embeds[i] for i=0, embeds.length - 1] + for element in *embeds + text = js_fix element.innerText + path = js_fix element\getAttribute 'path' + + element\replaceWith link_to path or '', text, fileder + assert 1 == parent.childElementCount, "text/html with more than one child!" parent.firstElementChild }, diff --git a/root/experiments/parallax_panels/description: text$plain b/root/experiments/parallax_panels/description: text$plain new file mode 100644 index 0000000..0eed9db --- /dev/null +++ b/root/experiments/parallax_panels/description: text$plain @@ -0,0 +1 @@ +A Parallax SVG Viewer, for Prototyping (Eurorack) Panels diff --git a/root/experiments/parallax_panels/picture/URL -> twitter$tweet b/root/experiments/parallax_panels/picture/URL -> twitter$tweet new file mode 100644 index 0000000..8d5bce2 --- /dev/null +++ b/root/experiments/parallax_panels/picture/URL -> twitter$tweet @@ -0,0 +1 @@ +https://twitter.com/S0lll0s/status/1141006444793405440 diff --git a/root/experiments/parallax_panels/text$markdown.md b/root/experiments/parallax_panels/text$markdown.md new file mode 100644 index 0000000..7453762 --- /dev/null +++ b/root/experiments/parallax_panels/text$markdown.md @@ -0,0 +1,16 @@ +parallax-panels +=============== + +I'm prototyping an aesthetic for (eurorack) panels that relies on multiple layers of parallax visuals for dramatic effect. + +<mmm-embed path="picture" nolink></mmm-embed> + +parallax-viewer +=============== + +I built a little SVG viewer that stacks the layers and lets you view them in parallax. +You can find it <mmm-link path="viewer">here</mmm-link>. + +And here's a little demonstration: + +<mmm-embed path="viewer/demo" nolink></mmm-embed> diff --git a/root/experiments/parallax_panels/viewer/demo/video$mp4.mp4 b/root/experiments/parallax_panels/viewer/demo/video$mp4.mp4 Binary files differnew file mode 100755 index 0000000..f3600cc --- /dev/null +++ b/root/experiments/parallax_panels/viewer/demo/video$mp4.mp4 diff --git a/root/experiments/parallax_panels/viewer/link: URL b/root/experiments/parallax_panels/viewer/link: URL new file mode 100644 index 0000000..f1bc92e --- /dev/null +++ b/root/experiments/parallax_panels/viewer/link: URL @@ -0,0 +1 @@ +https://codepen.io/s-ol/full/rExrey diff --git a/root/projects/btrktrl/$order b/root/projects/btrktrl/$order new file mode 100644 index 0000000..0520d1b --- /dev/null +++ b/root/projects/btrktrl/$order @@ -0,0 +1,13 @@ +proto_rgb +proto_encoder +proto_spi +knobs_all +knobs_testing +pcb_glamour_close +pcb_glamour_far +pcb_glamour_top +pcb_glamour +pcb_glamour_connector +pcb_dev_configuration +pcb_dev_encoder +pcb_osc diff --git a/root/projects/btrktrl/description: text$plain b/root/projects/btrktrl/description: text$plain new file mode 100644 index 0000000..d7e3402 --- /dev/null +++ b/root/projects/btrktrl/description: text$plain @@ -0,0 +1 @@ +a FPGA-based modular MIDI/OSC control surface diff --git a/root/projects/btrktrl/knobs_all/description: text$plain b/root/projects/btrktrl/knobs_all/description: text$plain new file mode 100644 index 0000000..1a43de0 --- /dev/null +++ b/root/projects/btrktrl/knobs_all/description: text$plain @@ -0,0 +1 @@ +sampling machined aluminum knobs from chinese supplier diff --git a/root/projects/btrktrl/knobs_all/image$jpeg.jpg b/root/projects/btrktrl/knobs_all/image$jpeg.jpg Binary files differnew file mode 100644 index 0000000..c523f8f --- /dev/null +++ b/root/projects/btrktrl/knobs_all/image$jpeg.jpg diff --git a/root/projects/btrktrl/knobs_testing/description: text$plain b/root/projects/btrktrl/knobs_testing/description: text$plain new file mode 100644 index 0000000..9588122 --- /dev/null +++ b/root/projects/btrktrl/knobs_testing/description: text$plain @@ -0,0 +1 @@ +testing different knob spacings diff --git a/root/projects/btrktrl/knobs_testing/image$jpeg.jpg b/root/projects/btrktrl/knobs_testing/image$jpeg.jpg Binary files differnew file mode 100644 index 0000000..09ea47d --- /dev/null +++ b/root/projects/btrktrl/knobs_testing/image$jpeg.jpg diff --git a/root/projects/btrktrl/pcb_dev_configuration/description: text$plain b/root/projects/btrktrl/pcb_dev_configuration/description: text$plain new file mode 100644 index 0000000..b15f4f0 --- /dev/null +++ b/root/projects/btrktrl/pcb_dev_configuration/description: text$plain @@ -0,0 +1 @@ +configuring the FPGA on the custom PCB via an arduino for the first time diff --git a/root/projects/btrktrl/pcb_dev_configuration/video$mp4.mp4 b/root/projects/btrktrl/pcb_dev_configuration/video$mp4.mp4 Binary files differnew file mode 100644 index 0000000..c8113cd --- /dev/null +++ b/root/projects/btrktrl/pcb_dev_configuration/video$mp4.mp4 diff --git a/root/projects/btrktrl/pcb_dev_encoder/description: text$plain b/root/projects/btrktrl/pcb_dev_encoder/description: text$plain new file mode 100644 index 0000000..530be5a --- /dev/null +++ b/root/projects/btrktrl/pcb_dev_encoder/description: text$plain @@ -0,0 +1 @@ +encoder & capacitive sensing working on the custom PCB diff --git a/root/projects/btrktrl/pcb_dev_encoder/video$mp4.mp4 b/root/projects/btrktrl/pcb_dev_encoder/video$mp4.mp4 Binary files differnew file mode 100644 index 0000000..fa41799 --- /dev/null +++ b/root/projects/btrktrl/pcb_dev_encoder/video$mp4.mp4 diff --git a/root/projects/btrktrl/pcb_glamour/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour/image$jpeg.jpg Binary files differnew file mode 100644 index 0000000..5864822 --- /dev/null +++ b/root/projects/btrktrl/pcb_glamour/image$jpeg.jpg diff --git a/root/projects/btrktrl/pcb_glamour_close/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour_close/image$jpeg.jpg Binary files differnew file mode 100644 index 0000000..5d572aa --- /dev/null +++ b/root/projects/btrktrl/pcb_glamour_close/image$jpeg.jpg diff --git a/root/projects/btrktrl/pcb_glamour_connector/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour_connector/image$jpeg.jpg Binary files differnew file mode 100644 index 0000000..6503f84 --- /dev/null +++ b/root/projects/btrktrl/pcb_glamour_connector/image$jpeg.jpg diff --git a/root/projects/btrktrl/pcb_glamour_far/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour_far/image$jpeg.jpg Binary files differnew file mode 100644 index 0000000..661f4fe --- /dev/null +++ b/root/projects/btrktrl/pcb_glamour_far/image$jpeg.jpg diff --git a/root/projects/btrktrl/pcb_glamour_top/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour_top/image$jpeg.jpg Binary files differnew file mode 100644 index 0000000..bbefc13 --- /dev/null +++ b/root/projects/btrktrl/pcb_glamour_top/image$jpeg.jpg diff --git a/root/projects/btrktrl/pcb_osc/description: text$plain b/root/projects/btrktrl/pcb_osc/description: text$plain new file mode 100644 index 0000000..2f0df00 --- /dev/null +++ b/root/projects/btrktrl/pcb_osc/description: text$plain @@ -0,0 +1 @@ +a browser application talking to the encoders through a websocket/serial OSC bridge (nodejs) diff --git a/root/projects/btrktrl/pcb_osc/video$mp4.mp4 b/root/projects/btrktrl/pcb_osc/video$mp4.mp4 Binary files differnew file mode 100644 index 0000000..3562d43 --- /dev/null +++ b/root/projects/btrktrl/pcb_osc/video$mp4.mp4 diff --git a/root/projects/btrktrl/proto_encoder/description: text$plain b/root/projects/btrktrl/proto_encoder/description: text$plain new file mode 100644 index 0000000..e0f620b --- /dev/null +++ b/root/projects/btrktrl/proto_encoder/description: text$plain @@ -0,0 +1 @@ +getting the encoder and capacitive sensing working on the prototype diff --git a/root/projects/btrktrl/proto_encoder/video$mp4.mp4 b/root/projects/btrktrl/proto_encoder/video$mp4.mp4 Binary files differnew file mode 100644 index 0000000..acb32c8 --- /dev/null +++ b/root/projects/btrktrl/proto_encoder/video$mp4.mp4 diff --git a/root/projects/btrktrl/proto_rgb/description: text$plain b/root/projects/btrktrl/proto_rgb/description: text$plain new file mode 100644 index 0000000..43b7f69 --- /dev/null +++ b/root/projects/btrktrl/proto_rgb/description: text$plain @@ -0,0 +1 @@ +driving WS2812 RGB LEDs on the prototype board diff --git a/root/projects/btrktrl/proto_rgb/video$mp4.mp4 b/root/projects/btrktrl/proto_rgb/video$mp4.mp4 Binary files differnew file mode 100644 index 0000000..8e06fcc --- /dev/null +++ b/root/projects/btrktrl/proto_rgb/video$mp4.mp4 diff --git a/root/projects/btrktrl/proto_spi/description: text$plain b/root/projects/btrktrl/proto_spi/description: text$plain new file mode 100644 index 0000000..c38b56e --- /dev/null +++ b/root/projects/btrktrl/proto_spi/description: text$plain @@ -0,0 +1 @@ +developing and debugging the SPI protocol diff --git a/root/projects/btrktrl/proto_spi/image$jpeg.jpg b/root/projects/btrktrl/proto_spi/image$jpeg.jpg Binary files differnew file mode 100644 index 0000000..c89341c --- /dev/null +++ b/root/projects/btrktrl/proto_spi/image$jpeg.jpg diff --git a/root/projects/btrktrl/text$moonscript -> fn -> mmm$dom.moon b/root/projects/btrktrl/text$moonscript -> fn -> mmm$dom.moon new file mode 100644 index 0000000..f7d8f9c --- /dev/null +++ b/root/projects/btrktrl/text$moonscript -> fn -> mmm$dom.moon @@ -0,0 +1,62 @@ +import div, h3, p, a from require 'mmm.dom' +import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom' + +=> + text = (...) -> + div with for text in *{...} + p text + .style = { 'max-width': '900px' } + + filtered_block = (pattern) -> + div with for child in *@children + continue unless (child\gett 'name: alpha')\match pattern + + div { + style: { + display: 'inline-block' + width: '500px' + margin: '0.5em' + padding: '0.4em 1em' + background: 'var(--gray-bright)' + } + div (link_to child), style: { 'margin-bottom': '0.2em' } + child\gett 'mmm/dom' + (child\get 'description: mmm/dom') + } + + .style = { + display: 'flex' + 'flex-wrap': 'wrap' + 'align-items': 'flex-start' + margin: '-0.5em' + } + + div { + h3 @gett 'name: alpha' + text "For this project I am builiding a modular, FPGA powered MIDI/OSC Control Surface.", + "The setup consists of an arduino MCU as a master controller, that communicates to the PC over + SLIP-encoded Serial OSC messages. The controller talks to daughterboards over SPI. + Each daugherboard contains a rotary encoder, 8 RGB LEDs and does capacitive sensing on the knob.", + "This was the first time I worked with an FPGA, and the first time I designed my own PCBs as well. + The FPGA I used is an ICE40UP5k, it was targeted using the icestorm open toolchain and Verilog. + I started by prototyping using an UPduino v2 Prototyping board (orange), and my failed rev1 PCBs (green). + On the FPGAs I implemented capacitive sensing, the SPI slave and control logic before moving on." + + filtered_block '^proto_' + + text "Once I got everything working there I designed my custom boards with the FPGA integrated directly, + including power conditioning and configuration. + There is also a busboard that manages SPI addressing / multiplexing as well as latching the power state + for each daughterboard, so that they can be started and configured individually." + + filtered_block '^pcb_glamour' + filtered_block '^pcb_dev' + + text "The daughterboards and controller communicate over a custom SPI protocol I designed. + The controller configures the daughterboards on boot or request from the PC. + It sends and receives OSC messages over SLIP-encoded Serial. + On the PC a small nodejs application relays the OSC messages over UDP or WebSocket, + so that native and web applications can consume them and interact with the control surface." + + filtered_block '^pcb_osc' + } diff --git a/scss/_content.scss b/scss/_content.scss index e4345ef..0bfc1e8 100644 --- a/scss/_content.scss +++ b/scss/_content.scss @@ -4,7 +4,10 @@ height: inherit; } - .markdown, .markdown > p, .markdown > p > a { + .markdown, + .markdown > p, + .markdown > p > a, + .markdown > a { > img, > video { display: block; max-width: 100%; |
