javascript - How to make an eraser with kineticjs 5.1.0 acting on multi-layer? -
i want make eraser kineticjs, have problem.
the eraser need efficient on multiple layer (layera, layerb in code) , simple button or check box can choose if eraser work on first or second layer, , why not on of them. need keep them draggable.
her jsfiddle show i've explained:
http://jsfiddle.net/junkees/ja2v8/2/
var stage = new kinetic.stage({ container: 'container', width: 400, height: 500 }); var layera = new kinetic.layer(); var imageobj = new image(); imageobj.onload = function() { var x = new kinetic.image({ x: 0, y: 0, image: imageobj, draggable:false }); // add shape layer layera.setlistening(false); layera.add(x); // add layer stage stage.add(layera); layera.setzindex(10); //layera.draw(); }; imageobj.src="https://imagizer.imageshack.us/v2/595x397q90/707/u8q3.jpg" var layerb = new kinetic.layer(); var imagj = new image(); imagj.onload = function() { var x = new kinetic.image({ x: 0, y: 0, image: imagj, }); // add shape layer layerb.setdraggable(true); layerb.setlistening(true); layerb.add(x); // add layer stage stage.add(layerb); layerb.setzindex(100); layerb.draw(); }; imagj.src = 'http://jsfiddle.net/img/initializing.png';
i whant able erase frog (or other of layer) , erase part of cup of coffee(second layer) mouse, circle (the radius doesn't matter, i'll make jquery slider define it's size ;) )
i'm using latest version of kineticjs, 5.1.0
sorry previous post question, i've read them them didn't work me because of version. i've search everywhere google let me search , didn't found can me ask question
here i've found partially works:
http://jsfiddle.net/junkees/ja2v8/3/
in 1 i've created new shape , attach layer, because shape , image both in same layer , layer draggable it'll drag both of them can see it's micro part of want :/
i've edited code , can little little i'll success it! new jsfiddle: http://jsfiddle.net/junkees/ja2v8/5/ , problem:
- even if i've set destination out can't erase, juste write
- i don't see how proceed when whant stop "erase"
am in right way finish this?
globalcompositeoperation
used "erase" existing canvas pixels using new drawings (like circle-dragged-with-mouse).
kineticjs not yet suited creating "eraser" tool. that's because doesn't yet support globalcompositeoperation
.
a workaround create kinetic.shape object lets draw native canvas commands.
then reference native canvas context while using kinetic.shape this:
var ctx=yourlayer.getcontext()._context;
with native canvas context can use globalcompositeoperation
turn custom shape eraser.
ctx.globalcompositeoperation='destination-out'; // new drawings erase existing pixels
you need have kinetic.shape "eraser" on every layer want penetrate erasings.
here demo: http://jsfiddle.net/m1erickson/tf7m3/
- the left 25% of image bottom layer (showing original image)
- the next 25% shows middle layer (a red rect @ 50% opacity)
- the next 25% shows both middle layer & top layer (top=a blue rect @ 50% opacity)
- the last 25% shows top layer (again, blue rect @ 50% opacity)
the circles show kinetic.shape erasers on both middle , top layers in action. use 'destination-out' compositing erase red , blue rectangles on middle & top layers. result bottom layer shows through "erased" circles.
example code:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>prototype</title> <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.1.min.js"></script> <style> body{padding:20px;} #container{ border:solid 1px #ccc; margin-top: 10px; width:350px; height:219px; } </style> <script> $(function(){ var stage = new kinetic.stage({ container: 'container', width: 350, height: 219 }); var bottomlayer = new kinetic.layer(); stage.add(bottomlayer); var middlelayer = new kinetic.layer(); stage.add(middlelayer); var toplayer = new kinetic.layer(); stage.add(toplayer); var sw=stage.width(); var sh=stage.height(); var cutouts=[]; var pi2=math.pi*2; var img=new image(); img.onload=start; img.src="https://dl.dropboxusercontent.com/u/139992952/stack1/landscape1.jpg"; function start(){ var kimage=new kinetic.image({ image:img, }); bottomlayer.add(kimage); bottomlayer.draw(); middlelayer.draw(); toplayer.draw(); }; var midred=new kinetic.rect({ x:sw/4,y:0,width:stage.width()/2,height:stage.height(), fill:"red", opacity:0.50 }); middlelayer.add(midred); var middleeraser=new kinetic.shape({ x:0,y:0, fill:"blue", drawfunc: function(context) { var ctx=middlelayer.getcontext()._context; ctx.save(); ctx.globalcompositeoperation="destination-out"; ctx.beginpath(); for(var i=0;i<cutouts.length;i++){ var cut=cutouts[i]; ctx.arc(cut.x,cut.y,15,0,pi2); ctx.closepath(); } ctx.fill(); ctx.restore(); } }); middlelayer.add(middleeraser); var topblue=new kinetic.rect({ x:stage.width()/2,y:0,width:stage.width()/2,height:stage.height(), fill:"blue", opacity:0.50 }); toplayer.add(topblue); toplayer.draw(); var toperaser=new kinetic.shape({ x:0,y:0, fill:"blue", drawfunc: function(context) { var ctx=toplayer.getcontext()._context; ctx.save(); ctx.globalcompositeoperation="destination-out"; ctx.beginpath(); for(var i=0;i<cutouts.length;i++){ var cut=cutouts[i]; ctx.arc(cut.x,cut.y,15,0,pi2); ctx.closepath(); } ctx.fill(); ctx.restore(); } }); toplayer.add(toperaser); stage.on('contentclick',function(){ var pos=stage.getpointerposition(); var mousex=parseint(pos.x); var mousey=parseint(pos.y); cutouts.push({x:mousex,y:mousey}); middlelayer.draw(); toplayer.draw(); }); }); // end $(function(){}); </script> </head> <body> <h4>click "erase" top 2 layers & reveal bottom image</h4> <div id="container"></div> </body> </html>
Comments
Post a Comment