MAKEUP BLOG POST
DATAFLOW / NODE GUI
I have been a long time fan of visual programming languages. One of earliest example of graphical user interface for Computer Aided Drafing(CAD) is Sketchpad by Ivan Sutherland in 1963.
https://www.youtube.com/watch?v=57wj8diYpgY
In 1968 Alan Kay(member of PARC and father of GUI) introduced GRaiL(GRaphical Input Language)
https://www.youtube.com/watch?v=QQhVQ1UG6aM
Each geometries in screen represent a block of code that does one thing only similar to methods or functions. The connections between the block of geometries represent variables being passed between various block of codes. This way of programming is helpful in visualizing flow of data and abstracts away writing actual code. It has been very popular with artist community.
Since the initial discoveries of the node based scripting languages, it has been integrated to many computer graphics softwares.
Apple Quartz Composer
Rhinoceros Grasshopper
VVVV
3DX MAX
and lastly there is Noflo for flowbased scripting in javascript.
Goal
My goal in this side project is to use what I've learned in Flatiron school to see if I can build my own node based scripting platform on browser.
Mini tests to see if my idea is even possible
So I wrote my first iteration of test using Javascript to drag a div element in javascript
$(document).ready ->
offY = 0
offX = 0
mouseUp = () ->
window.removeEventListener('mousemove', divMove, true)
return
mouseDown = (event) ->
console.log('loaded')
div = document.getElementById('box')
offY = event.clientY - parseInt(div.offsetTop)
offX = event.clientX - parseInt(div.offsetLeft)
window.addEventListener('mousemove', divMove, true)
return
divMove = (event) ->
div = document.getElementById('box')
div.style.position = 'absolute'
div.style.top = (event.clientY - offY) + 'px'
div.style.left = (event.clientX - offX) + 'px'
return
document.getElementById('box').addEventListener('mousedown', mouseDown, false)
window.addEventListener('mouseup', mouseUp, false)
and found out that Jquery-UI had dragging feature and reduced coffeescript file to only two lines........ :(
$(document).ready ->
$('.box').draggable()
next iteration I tried integrating Jquery-UI Draggable and Selectable to enable dragging in groups
Lastly, to connect each nodes with line representing varibable being passed between methods. For the lines, I decided to use Raphael.js with Jquery-ui droppable. It creates drawing element in html path element. Later on, I plan on using Jquery to destroy lines when needed.
#droppable test
$('.inner-field').droppable({
accept: ".inner-field",
tolerance: "pointer",
hoverClass: 'activated',
activate: (event, ui)->
ui.draggable.addClass('activated')
deactivate: (event, ui)->
ui.draggable.removeClass('activated')
# over: (event, ui)->
# $(event.target).addClass('activated')
drop: (event, ui)->
$(event.target).removeClass('activated')
cLine = paper.connection(ui.draggable, $(event.target))
connection.push([ui.draggable, $(event.target)])
})
Raphael.fn.arrow = (x1, y1, x2, y2, size) ->
angle = Math.atan2(x1-x2,y2-y1);
angle = (angle / (2 * Math.PI)) * 360;
arrowPath = this.path("M" + x2 + " " + y2 + " L" + (x2 - size) + " " + (y2 - size) + " L" + (x2 - size) + " " + (y2 + size) + " L" + x2 + " " + y2 ).attr("fill","black").rotate((90+angle),x2,y2);
linePath = this.path("M" + x1 + " " + y1 + " L" + x2 + " " + y2);
return [linePath,arrowPath];
paper = new Raphael($('#container')[0], 500, 500)
arrow = 0
connection = $([])
Future goals
- Avoid making spaghetti code (Backbone? Require.js?)
- Create blocks with specific functions.
- Write Rails backend to save scripts.
- Inject javascript to another Iframe for interactive 3D scripting (Three.js)
Flatiron ruby adventure time