javascript - RXJS draw line on html5 canvas -
i'm trying achieve same effect i'm posting here using reactive extensions javascript (rx-js). i'm bit puzzled on how it. here page:
<!doctype html> <html> <head> <title>drag , drop</title> </head> <style type="text/css"> canvas { border:1px solid steelblue; background-color: whitesmoke; } </style> <body> <canvas id="canvas" width=300 height=300></canvas> <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.min.js"></script> <script type="text/javascript"> $(function() { var canvas = document.getelementbyid("canvas"); var ctx = canvas.getcontext("2d"); var canvasoffset = $("#canvas").offset(); var offsetx = canvasoffset.left; var offsety = canvasoffset.top; var drawing = false; var mousex = 0; var mousey = 0; function handlemousedown(e) { mousex = parseint(e.clientx - offsetx); mousey = parseint(e.clienty - offsety); drawing= true; } function handlemouseup(e) { drawing = false; } function handlemousemove(e) { if(drawing){ mouseex = parseint(e.clientx - offsetx); mouseey = parseint(e.clienty - offsety); $("#movelog").html("move: " + mousex + " / " + mousey); var ctx = canvas.getcontext("2d"); // cleanup code ctx.save(); ctx.settransform(1, 0, 0, 1, 0, 0); ctx.clearrect(0, 0, canvas.width, canvas.height); ctx.restore(); ctx.beginpath(); ctx.moveto(mousex,mousey); ctx.lineto(mouseex,mouseey); ctx.stroke(); } } $("#canvas").mousedown(function(e) { handlemousedown(e); }); $("#canvas").mousemove(function(e) { handlemousemove(e); }); $("#canvas").mouseup(function(e) { handlemouseup(e); }); }); </script> </body> </html>
i think should create observables mousedown, mousemove , mouseup events.
var mousedown = rx.observable.fromevent(canvas, 'mousedown'); var mousemove = rx.observable.fromevent(canvas, 'mousemove'); var mouseup = rx.observable.fromevent(canvas, 'mouseup');
but don't know how combine them. think should start observing mousedown, collect moves until mouseup raised, , in whil redraw line starting point current point mouse during mousemove. have ideas? lot.
°°°°°°°°°°°°°°°°°°°°°°edit°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
here code after answer brandon:
$(function() { var canvas = document.getelementbyid('canvas'); var ctx = canvas.getcontext("2d"); var canvasoffset = $("#canvas").offset(); var offsetx = canvasoffset.left; var offsety = canvasoffset.top; var mousedown = rx.observable.fromevent($("#canvas"), 'mousedown'); var mousemove = rx.observable.fromevent($("#canvas"), 'mousemove'); var mouseup = rx.observable.fromevent($("#canvas"), 'mouseup'); // keep reference pisition when mouse down fired // flatten stream concatall var tracelinestream = mousedown.map(function(md) { var movesfrommousedown = mousemove.takeuntil(mouseup); var movesfrommousedownandmousedown = movesfrommousedown.map(function(mm) { return { mousedownpoint: md, mousemovepoint: mm } }); return movesfrommousedownandmousedown; }).concatall(); var subscription = tracelinestream.subscribe( function(y) { var mousedown = y.mousedownpoint; var mousemove = y.mousemovepoint; var mousedownx = parseint(mousedown.clientx - offsetx); var mousedowny = parseint(mousedown.clienty - offsety); var mousemovex = parseint(mousemove.clientx - offsetx); var mousemovey = parseint(mousemove.clienty - offsety); ctx.save(); ctx.settransform(1, 0, 0, 1, 0, 0); ctx.clearrect(0, 0, canvas.width, canvas.height); ctx.restore(); ctx.beginpath(); ctx.moveto(mousedownx, mousedowny); ctx.lineto(mousemovex, mousemovey); ctx.stroke(); }, function(e) { console.log('onerror: ' + e.message); }, function() { console.log('oncompleted'); }); });
first, combined streams have stream of events represent single drag.
var drag = mousedown.first().concat(mousemove.takeuntil(mouseup));
next, project stream of events stream of previous,current
tuples.
var moves = drag .scan({}, function(acc, x) { return { previous: acc.current, current: x }; }) .skip(1);
now have stream works first time. when ends, want start listening next drag:
var allmoves = moves.repeat();
finally, subscribe:
allmoves.subscribe(function (move) { var mousex = move.previous.clientx - offsetx, mousey = move.previous.clienty - offsety, mouseex = move.current.clientx - offsetx, mouseey = move.current.clienty - offsety, ... });
putting without of intermediate variables:
mousedown .first() .concat(mousemove.takeuntil(mouseup)) .scan({}, function(acc, x) { return { previous: acc.current, current: x }; }) .skip(1) .repeat() .subscribe(function (move) { var mousex = move.previous.clientx - offsetx, mousey = move.previous.clienty - offsety, mouseex = move.current.clientx - offsetx, mouseey = move.current.clienty - offsety, ... });
Comments
Post a Comment