javascript - 如何将像素值移动到 Canvas 中的下一个鼠标移动位置?

标签 javascript jquery canvas html5-canvas

我正在使用 HTML5 Canvas 创建一个涂抹工具。现在我必须将鼠标指针点的像素颜色移动到鼠标指针移动的下一个位置。是否可以使用 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) {
    do {
      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)
});

最佳答案

我的 ATM 时间很紧,所以只用代码。

使用屏幕外 Canvas brush 获取鼠标最后一帧所在的背景 Canvas background 的副本。然后使用 ctx.globalCompositeOperation = "destination-in" 使用径向渐变羽化画笔。然后在下一个鼠标位置绘制更新的画笔。

主 Canvas 仅用于显示,被涂抹的 Canvas 称为背景 你可以在 Canvas 上放置任何你想要的内容(例如图像),它可以是任何大小,你可以缩放、平移、旋转背景,但您必须转换鼠标坐标以匹配背景坐标

点击拖动鼠标涂抹颜色。

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 from 0 none to 1 full

 // helpers
const doFor = (count, cb) => { var i = 0; while (i < count && cb(i++) !== true); }; // the ; after while loop is 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 for 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 an 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;
}

// get the brush from source ctx at 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 is 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 then do the smudge for all pixels between last mouse and mouse now
  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 i = 0;i < dist; i += 1){
      var ni = i / 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>

关于javascript - 如何将像素值移动到 Canvas 中的下一个鼠标移动位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45752589/

相关文章:

javascript - 渐进增强是当前的问题吗?

选择器的 jQuery 设计模式可以提高代码可维护性?

javascript - 使用 CocoonJS idtkscale 缩放 KineticJS Canvas

javascript - 需要帮助使用此函数来使用 javascript 销毁 Canvas 上的项目

javascript - 使用 MongoDB 和 Nodejs 创建嵌套子文档/子元素

javascript - 如果还有其他故障排除

php - 从数据库中删除行之前添加警报窗口

JQuery 点击事件只起作用一次

javascript - 在 Firefox 中使用 jQuery(用户脚本)添加表单链接

java - 按 CTRL + 鼠标滚轮将缩放