UNPKG

rpd

Version:

RPD is a minimal framework for building Node-Based User Interfaces, powered by Reactive Programming

176 lines (157 loc) 7.4 kB
(function() { var SHAPES = [ 'circle', 'rect', 'cross', 'diamond' ]; var DEFAULT_COLOR = { r: 0xED, g: 0x22, b: 0x5D }; var SVG_XMLNS = "http://www.w3.org/2000/svg"; // ============= Register p5/color channel type ============= function numberToHex(num) { return (num > 15) ? num.toString(16) : '0' + num.toString(16); } function toHexColor(color) { return '#' + numberToHex(color.r || 0) + numberToHex(color.g || 0) + numberToHex(color.b || 0); } Rpd.channeltype('p5/color', { show: toHexColor }); // ============= Register p5/color node type and renderer ============= Rpd.nodetype('p5/color', { inlets: { 'r': { type: 'util/number', default: DEFAULT_COLOR.r, name: 'red' }, 'g': { type: 'util/number', default: DEFAULT_COLOR.g, name: 'green' }, 'b': { type: 'util/number', default: DEFAULT_COLOR.b, name: 'blue' } }, outlets: { 'color': { type: 'p5/color' } }, process: function(inlets) { return { color: inlets }; } }); Rpd.noderenderer('p5/color', 'svg', function() { var colorElm, textElm; return { size: { width: 90, height: 40 }, first: function(bodyElm) { var group = document.createElementNS(SVG_XMLNS, 'g'); group.setAttributeNS(null, 'transform', 'translate(-30, 0)'); colorElm = document.createElementNS(SVG_XMLNS, 'rect'); colorElm.setAttributeNS(null, 'y', -10); colorElm.setAttributeNS(null, 'width', 20); colorElm.setAttributeNS(null, 'height', 20); colorElm.setAttributeNS(null, 'rx', 2); colorElm.setAttributeNS(null, 'ry', 2); group.appendChild(colorElm); textElm = document.createElementNS(SVG_XMLNS, 'text'); textElm.style.alignmentBaseline = 'middle'; textElm.setAttributeNS(null, 'x', 25); textElm.setAttributeNS(null, 'y', 1); textElm.innerText = textElm.textContent = '<None>'; group.appendChild(textElm); bodyElm.appendChild(group); }, always: function(bodyElm, inlets, outlets) { var color = outlets.color; colorElm.style.fill = 'rgb(' + color.r + ',' + color.g + ',' + color.b + ')'; textElm.innerText = textElm.textContent = toHexColor(color); } }; }); // ============= Register p5/shape channel type ============= Rpd.channeltype('p5/shape', {}); // ============= Register p5/shape node type and renderer ============= Rpd.nodetype('p5/shape', { inlets: { 'shape': { type: 'p5/shape', default: 'circle', hidden: true } }, outlets: { 'shape': { type: 'p5/shape' } }, process: function(inlets) { return { shape: inlets.shape } } }); Rpd.noderenderer('p5/shape', 'svg', function() { var curShape = 'circle'; var variants = {}; var symbolSide = 10; var symbols = { 'circle': function() { var circle = document.createElementNS(SVG_XMLNS, 'circle'); circle.setAttributeNS(null, 'r', Math.floor(symbolSide / 2)); return circle; }, 'rect': function() { var rect = document.createElementNS(SVG_XMLNS, 'rect'); rect.setAttributeNS(null, 'width', symbolSide); rect.setAttributeNS(null, 'height', symbolSide); rect.setAttributeNS(null, 'x', -1 * Math.floor(symbolSide / 2)); rect.setAttributeNS(null, 'y', -1 * Math.floor(symbolSide / 2)); return rect; }, 'cross': function() { var group = document.createElementNS(SVG_XMLNS, 'g'); group.setAttributeNS(null, 'transform', 'translate(' + (-1 * Math.floor(symbolSide / 2)) + ', ' + (-1 * Math.floor(symbolSide / 2)) + ')'); var line1 = document.createElementNS(SVG_XMLNS, 'line'); line1.setAttributeNS(null, 'x1', 0); line1.setAttributeNS(null, 'y1', 0); line1.setAttributeNS(null, 'x2', Math.floor(symbolSide)); line1.setAttributeNS(null, 'y2', Math.floor(symbolSide)); group.appendChild(line1); var line2 = document.createElementNS(SVG_XMLNS, 'line'); line2.setAttributeNS(null, 'x1', Math.floor(symbolSide)); line2.setAttributeNS(null, 'y1', 0); line2.setAttributeNS(null, 'x2', 0); line2.setAttributeNS(null, 'y2', Math.floor(symbolSide)); group.appendChild(line2); return group; }, 'diamond': function() { var rect = document.createElementNS(SVG_XMLNS, 'rect'); rect.setAttributeNS(null, 'transform', 'rotate(45)'); rect.setAttributeNS(null, 'width', symbolSide); rect.setAttributeNS(null, 'height', symbolSide); rect.setAttributeNS(null, 'x', -1 * Math.floor(symbolSide / 2)); rect.setAttributeNS(null, 'y', -1 * Math.floor(symbolSide / 2)); return rect; } }; return { size: { width: 80, height: 40 }, pivot: { x: 0, y: 0.5 }, first: function(bodyElm) { var shapeChange = Kefir.emitter(); var allShapesGroup = document.createElementNS(SVG_XMLNS, 'g'); SHAPES.forEach(function(shape, i) { var shapeGroup = document.createElementNS(SVG_XMLNS, 'g'); shapeGroup.appendChild(symbols[SHAPES[i]]()); shapeGroup.setAttributeNS(null, 'transform', 'translate(' + ((i * symbolSide * 2) + 10) + ', 0)'); shapeGroup.setAttributeNS(null, 'class', 'rpd-p5-shape-variant'); shapeGroup.addEventListener('click', (function(shape) { return function() { variants[curShape].setAttributeNS(null, 'class', 'rpd-p5-shape-variant'); curShape = shape; variants[curShape].setAttributeNS(null, 'class', 'rpd-p5-shape-variant rpd-p5-active-variant'); shapeChange.emit(curShape); } })(shape)); variants[shape] = shapeGroup; allShapesGroup.appendChild(shapeGroup); }); variants[curShape].setAttributeNS(null, 'class', 'rpd-p5-shape-variant rpd-p5-active-variant'); bodyElm.appendChild(allShapesGroup); return { 'shape': { valueOut: shapeChange } }; } } }); // ============= Monkey-patch util/random renderer ============= var curSvgRandomRendererFunc = Rpd.allNodeRenderers['util/random'].svg; var newSvgRandomRendererFunc = function(node) { var returnObj = curSvgRandomRendererFunc.apply(this, arguments); if (returnObj.size) { returnObj.size.width = 80; } else { returnObj.size = { width: 80 }; } var textElm; returnObj.first = function(bodyElm) { textElm = document.createElementNS(SVG_XMLNS, 'text'); textElm.innerText = textElm.textContent = '?'; bodyElm.appendChild(textElm); }; returnObj.always = function(bodyElm, inlets, outlets) { textElm.innerText = textElm.textContent = 'from ' + inlets.min + ' to ' + inlets.max; }; return returnObj; }; Rpd.allNodeRenderers['util/random'].svg = newSvgRandomRendererFunc; })();