Mercurial > code > home > repos > light9
view web/paint/paint-elements.coffee @ 2405:69ca2b2fc133
overcomplicated attempt at persisting the pane layout in the rdf graph
this was hard because we have to somehow wait for the graph to load before config'ing the panes
author | drewp@bigasterisk.com |
---|---|
date | Fri, 17 May 2024 16:58:26 -0700 |
parents | 4556eebe5d73 |
children |
line wrap: on
line source
log = debug('paint') debug.enable('paint') class Painting constructor: (@svg) -> @strokes = [] setSize: (@size) -> startStroke: (pos, color) -> stroke = new Stroke(pos, color, @size) stroke.appendElem(@svg) @strokes.push(stroke) return stroke hover: (pos) -> @clear() s = @startStroke(pos, '#ffffff', @size) r = .02 steps = 5 for ang in [0..steps] ang = 6.28 * ang / steps s.move([pos[0] + r * Math.sin(ang), pos[1] + 1.5 * r * Math.cos(ang)]) getDoc: -> {strokes: @strokes} clear: -> s.removeElem() for s in @strokes @strokes = [] class Stroke constructor: (pos, @color, @size) -> @path = document.createElementNS('http://www.w3.org/2000/svg', 'path') @path.setAttributeNS(null, 'd', "M #{pos[0]*@size[0]} #{pos[1]*@size[1]}") @pts = [pos] @lastPos = pos appendElem: (parent) -> parent.appendChild(@path) removeElem: -> @path.remove() move: (pos) -> if Math.hypot(pos[0] - @lastPos[0], pos[1] - @lastPos[1]) < .02 return @path.attributes.d.value += " L #{pos[0]*@size[0]} #{pos[1]*@size[1]}" @pts.push(pos) @lastPos = pos finish: () -> Polymer is: "light9-paint-canvas" behaviors: [ Polymer.IronResizableBehavior ] listeners: 'iron-resize': 'onResize' properties: { bg: { type: String }, tool: { type: String, value: 'hover' }, painting: { type: Object } # output } ready: -> @painting = new Painting(@$.paint) @onResize() @$.paint.addEventListener('mousedown', @onDown.bind(@)) @$.paint.addEventListener('mousemove', @onMove.bind(@)) @$.paint.addEventListener('mouseup', @onUp.bind(@)) @$.paint.addEventListener('touchstart', @onDown.bind(@)) @$.paint.addEventListener('touchmove', @onMove.bind(@)) @$.paint.addEventListener('touchend', @onUp.bind(@)) @hover = _.throttle((ev) => @painting.hover(@evPos(ev)) @scopeSubtree(@$.paint) @fire('paintingChanged', @painting) , 100) evPos: (ev) -> px = (if ev.touches?.length? then [Math.round(ev.touches[0].clientX), Math.round(ev.touches[0].clientY)] else [ev.x, ev.y]) return [px[0] / @size[0], px[1] / @size[1]] onClear: () -> @painting.clear() @fire('paintingChanged', @painting) onDown: (ev) -> switch @tool when "hover" @onMove(ev) when "paint" # if it's on an existing one, do selection @currentStroke = @painting.startStroke(@evPos(ev), '#aaaaaa') @scopeSubtree(@$.paint) onMove: (ev) -> switch @tool when "hover" @hover(ev) when "paint" # ..or move selection return unless @currentStroke @currentStroke.move(@evPos(ev)) onUp: (ev) -> return unless @currentStroke @currentStroke.finish() @currentStroke = null @notifyPath('painting.strokes.length') # not working @fire('paintingChanged', @painting) onResize: (ev) -> @size = [@$.parent.offsetWidth, @$.parent.offsetHeight] @$.paint.attributes.viewBox.value = "0 0 #{@size[0]} #{@size[1]}" @painting.setSize(@size) Polymer is: "light9-simulation" properties: { graph: { type: Object } layers: { type: Object } solution: { type: Object } } listeners: [ "onLayers(layers)" ] ready: -> null onLayers: (layers) -> log('upd', layers) Polymer is: "light9-device-settings", properties: { graph: { type: Object } subj: {type: String, notify: true}, label: {type: String, notify: true}, attrs: {type: Array, notify: true}, }, observers: [ 'onSubj(graph, subj)' ] ready: -> @label = "aura2" @attrs = [ {attr: 'rx', val: .03}, {attr: 'color', val: '#ffe897'}, ] onSubj: (graph, @subj) -> graph.runHandler(@loadAttrs.bind(@), "loadAttrs #{@subj}") loadAttrs: -> U = (x) => @graph.Uri(x) @attrs = [] for s in @graph.objects(U(@subj), U(':setting')) attr = @graph.uriValue(s, U(':deviceAttr')) attrLabel = @graph.stringValue(attr, U('rdfs:label')) @attrs.push({attr: attrLabel, val: @settingValue(s)}) @attrs = _.sortBy(@attrs, 'attr') settingValue: (s) -> U = (x) => @graph.Uri(x) for pred in [U(':value'), U(':scaledValue')] try return @graph.stringValue(s, pred) catch null try return @graph.floatValue(s, pred) catch null throw new Error("no value for #{s}") Polymer is: "light9-paint" properties: { painting: { type: Object } client: { type: Object } graph: { type: Object } } ready: () -> # couldn't make it work to bind to painting's notifyPath events @$.canvas.addEventListener('paintingChanged', @paintingChanged.bind(@)) @$.solve.addEventListener('response', @onSolve.bind(@)) @clientSendThrottled = _.throttle(@client.send.bind(@client), 60) @bestMatchPending = false paintingChanged: (ev) -> U = (x) => @graph.Uri(x) @painting = ev.detail @$.solve.body = JSON.stringify(@painting.getDoc()) #@$.solve.generateRequest() @$.bestMatches.body = JSON.stringify({ painting: @painting.getDoc(), devices: [ U('dev:aura1'), U('dev:aura2'), U('dev:aura3'), U('dev:aura4'), U('dev:aura5'), U('dev:q1'), U('dev:q2'), U('dev:q3'), ]}) send = => @$.bestMatches.generateRequest().completes.then (r) => @clientSendThrottled(r.response.settings) if @bestMatchPending @bestMatchPending = false send() if @$.bestMatches.loading @bestMatchPending = true else send() onSolve: (response) -> U = (x) => @graph.Uri(x) sample = @$.solve.lastResponse.bestMatch.uri settingsList = [] for s in @graph.objects(sample, U(':setting')) try v = @graph.floatValue(s, U(':value')) catch v = @graph.stringValue(s, U(':scaledValue')) row = [@graph.uriValue(s, U(':device')), @graph.uriValue(s, U(':deviceAttr')), v] settingsList.push(row) @client.send(settingsList)