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

Popular posts from this blog

c# - How to get the current UAC mode -

postgresql - Lazarus + Postgres: incomplete startup packet -

javascript - Ajax jqXHR.status==0 fix error -