javascript - How to shift pixel value to the next mousemove position in canvas? -


i creating smudging tool html5 canvas. have shift pixel color @ point of mouse pointer next position mouse pointer moves. possible javascript?

<canvas id="canvas"><canvas> 
var canvas = document.getelementbyid("canvas"); var context = canvas.getcontext('2d'); var url = 'download.jpg'; var imgobj = new image(); imgobj.src = url; imgobj.onload = function(e) {   context.drawimage(imgobj, 0, 0); }  function findpos(obj) {   var curleft = 0,     curtop = 0;   if (obj.offsetparent) {     {       curleft += obj.offsetleft;       curtop += obj.offsettop;     } while (obj = obj.offsetparent);     return {       x: curleft,       y: curtop     };   }   return undefined; }  function rgbtohex(r, g, b) {   if (r > 255 || g > 255 || b > 255)     throw "invalid color component";   return ((r << 16) | (g << 8) | b).tostring(16); }  $('#canvas').mousemove(function(e) {   var pos = findpos(this);   var x = e.pagex - pos.x;   var y = e.pagey - pos.y;   console.log(x, y);   var c = this.getcontext('2d');   var p = c.getimagedata(x, y, 1, 1).data;   var hex = "#" + ("000000" + rgbtohex(p[0], p[1], p[2])).slice(-6);   console.log(hex) }); 

i short on time atm code only.

uses offscreen canvas brush copy of background canvas background mouse last frame. use radial gradient feather brush using ctx.globalcompositeoperation = "destination-in". draw updated brush @ next mouse position.

the main canvas use display, canvas being smeared called background can put whatever content want on canvas (eg image) , can size, , can zoom, pan, rotate background though have convert mouse coordinates match background coordinates

click drag mouse smear colours.

const ctx = canvas.getcontext("2d");  const background = createcanvas(canvas.width,canvas.height);  const brushsize = 64;  const bs = brushsize;  const bsh = bs / 2;  const smudgeamount = 0.25; // values 0 none 1 full     // helpers  const dofor = (count, cb) => { var = 0; while (i < count && cb(i++) !== true); }; // ; after while loop important don't remove  const randi = (min, max = min + (min = 0)) => (math.random() * (max - min) + min) | 0;      // simple mouse  const mouse  = {x : 0, y : 0, button : false}  function mouseevents(e){  	mouse.x = e.pagex;  	mouse.y = e.pagey;  	mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;  }  ["down","up","move"].foreach(name => document.addeventlistener("mouse"+name,mouseevents));      // brush gradient feather  const grad = ctx.createradialgradient(bsh,bsh,0,bsh,bsh,bsh);  grad.addcolorstop(0,"black");  grad.addcolorstop(1,"rgba(0,0,0,0)");  const brush = createcanvas(brushsize)    // creates offscreen canvas  function createcanvas(w,h = w){    var c = document.createelement("canvas");    c.width = w;    c.height = h;    c.ctx = c.getcontext("2d");    return c;  }    // brush source ctx @ x,y  function brushfrom(ctx,x,y){    brush.ctx.globalcompositeoperation = "source-over";    brush.ctx.globalalpha = 1;    brush.ctx.drawimage(ctx.canvas,-(x - bsh),-(y - bsh));    brush.ctx.globalcompositeoperation = "destination-in";    brush.ctx.globalalpha = 1;    brush.ctx.fillstyle = grad;    brush.ctx.fillrect(0,0,bs,bs);  }                				  // short cut vars   var w = canvas.width;  var h = canvas.height;  var cw = w / 2;  // center   var ch = h / 2;  var globaltime;  var lastx;  var lasty;    // update background size changed  function createbackground(){    background.width = w;    background.height = h;    background.ctx.fillstyle = "white";    background.ctx.fillrect(0,0,w,h);    dofor(64,()=>{      background.ctx.fillstyle = `rgb(${randi(255)},${randi(255)},${randi(255)}`;      background.ctx.fillrect(randi(w),randi(h),randi(10,100),randi(10,100));    });  }        // main update function  function update(timer){      globaltime = timer;      ctx.settransform(1,0,0,1,0,0); // reset transform      ctx.globalalpha = 1;           // reset alpha  	if(w !== innerwidth || h !== innerheight){  		cw = (w = canvas.width = innerwidth) / 2;  		ch = (h = canvas.height = innerheight) / 2;      createbackground();  	}else{  		ctx.clearrect(0,0,w,h);  	}    ctx.drawimage(background,0,0);        // if mouse down smudge pixels between last mouse , mouse    if(mouse.button){      brush.ctx.globalalpha = smudgeamount;      var dx = mouse.x - lastx;      var dy = mouse.y - lasty;      var dist = math.sqrt(dx*dx+dy*dy);      for(var = 0;i < dist; += 1){        var ni = / dist;        brushfrom(background.ctx,lastx + dx * ni,lasty + dy * ni);        ni = (i+1) / dist;        background.ctx.drawimage(brush,lastx + dx * ni - bsh,lasty + dy * ni - bsh);      }          }else{       brush.ctx.clearrect(0,0,bs,bs); /// clear brush if not used    }  	  	lastx = mouse.x;  	lasty = mouse.y;  	      requestanimationframe(update);  }  requestanimationframe(update);
canvas { position : absolute; top : 0px; left : 0px; }
<canvas id="canvas"></canvas>


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -