当前位置: 首页 > 知识库问答 >
问题:

如何使用onmousedown在画布上夹一个洞,同时遵循鼠标路径

缪征
2023-03-14

目标:

  1. 显示全部在div内部的画布遮蔽的背景图像
  2. onmousedown和onmousemove:解除背景图像以鼠标指针为中心圆形部分的蒙版。
  3. 返回一个完整的掩码onmouseup

这是我目前所掌握的--任何帮助都将不胜感激。它似乎可以工作,但它留下的痕迹,鼠标曾经去过。我希望它只显示周围的圆形区域,鼠标立即在任何给定的点。

功能JSfiddle:https://jsfidle.net/shaedmorgan/4325d8pg/19/

我尝试过更改globalCompositeOperation,并使用clip(),但似乎无法正确处理。我认为主要问题在于“重绘”功能。谢谢你来看看。

null

let canvas = document.getElementById('canvas');

window.onload = function () {
canvas.width = 200;
canvas.height = 200;
let centerx = canvas.width/2;
let centery = canvas.height/2;
let radius = 100;

let ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(centerx, centery, radius, 0, 2 * Math.PI);
ctx.fill();
}

function getMouse(e, canvas) {
  var rect = canvas.getBoundingClientRect();
  return {
    x: (e.clientX - rect.left) / (rect.right - rect.left) * canvas.width,
    y: (e.clientY - rect.top) / (rect.bottom - rect.top) * canvas.height
  };
}

function redraw (canvas, mouse) {
  var ctx = canvas.getContext('2d');
  ctx.globalCompositeOperation = 'destination-in'
  ctx.beginPath();
  ctx.arc((canvas.width) / 2, (canvas.height) / 2, (canvas.width) / 2, 0, 2 * Math.PI)
  ctx.arc(mouse.x, mouse.y, (canvas.width) / 4, 0, 2 * Math.PI)
  ctx.fill('evenodd'); 
}

function moveOnMouseDown (canvas, moveFunction) {
  var endMove = function () {
    canvas.width = 200;
    canvas.height = 200;
    let centerx = canvas.width/2;
    let centery = canvas.height/2;
    let radius = 100;

    let ctx = canvas.getContext('2d');
    ctx.beginPath();
    ctx.arc(centerx, centery, radius, 0, 2 * Math.PI);
    ctx.fill();
    window.removeEventListener('mousemove', moveFunction);
    window.removeEventListener('mouseup', endMove);
  };

  canvas.addEventListener('mousedown', function (event) {
    event.stopPropagation();
    var canvas = document.getElementById('canvas')
    var mouse = getMouse(event,canvas)
    redraw(canvas,mouse)
    window.addEventListener('mousemove', moveFunction);
    window.addEventListener('mouseup', endMove);
  });
}

moveOnMouseDown(document.getElementById('canvas'), function (e) {
  var mouse = getMouse(e, document.getElementById('canvas'));
  //console.log(mouse) <--confirmed mouse position is good.
  redraw(document.getElementById('canvas'), mouse);
})
#TML_div {
  position: absolute;
  overflow: hidden;
  width: 200px;
  height: 200px;
  border-radius: 50%;
}
html prettyprint-override"><div id='TML_div'>
  <canvas id='canvas'></canvas>
</div>

null

#TML_div {
  position: absolute;
  overflow: hidden;
  width: 200px;
  height: 200px;
  border-radius: 50%;
}
<div id='TML_div'>
  <canvas id='canvas'></canvas>
</div>

共有1个答案

皇甫学海
2023-03-14

重绘功能中重置画布:

null

let canvas = document.getElementById('canvas');

window.onload = function() {
  drawCircle();
}

function clearCanvas() {
  const ctx = canvas.getContext('2d');
  ctx.clearRect(0, 0, canvas.width, canvas.height);
}

function drawCircle() {
  canvas.width = 200;
  canvas.height = 200;
  let centerx = canvas.width / 2;
  let centery = canvas.height / 2;
  let radius = 100;

  let ctx = canvas.getContext('2d');
  ctx.beginPath();
  ctx.arc(centerx, centery, radius, 0, 2 * Math.PI);
  ctx.fill();
}

function getMouse(e, canvas) {
  var rect = canvas.getBoundingClientRect();
  return {
    x: (e.clientX - rect.left) / (rect.right - rect.left) * canvas.width,
    y: (e.clientY - rect.top) / (rect.bottom - rect.top) * canvas.height
  };
}

function redraw(canvas, mouse) {
  clearCanvas();
  drawCircle();

  const ctx = canvas.getContext('2d');
  ctx.globalCompositeOperation = 'destination-in'
  ctx.beginPath();
  ctx.arc((canvas.width) / 2, (canvas.height) / 2, (canvas.width) / 2, 0, 2 * Math.PI)
  ctx.arc(mouse.x, mouse.y, (canvas.width) / 4, 0, 2 * Math.PI)
  ctx.fill('evenodd');

}

function moveOnMouseDown(canvas, moveFunction) {
  var endMove = function() {
    canvas.width = 200;
    canvas.height = 200;
    let centerx = canvas.width / 2;
    let centery = canvas.height / 2;
    let radius = 100;

    let ctx = canvas.getContext('2d');
    ctx.beginPath();
    ctx.arc(centerx, centery, radius, 0, 2 * Math.PI);
    ctx.fill();
    window.removeEventListener('mousemove', moveFunction);
    window.removeEventListener('mouseup', endMove);
  };

  canvas.addEventListener('mousedown', function(event) {
    event.stopPropagation();
    var canvas = document.getElementById('canvas')
    var mouse = getMouse(event, canvas)
    redraw(canvas, mouse)
    window.addEventListener('mousemove', moveFunction);
    window.addEventListener('mouseup', endMove);
  });
}

moveOnMouseDown(document.getElementById('canvas'), function(e) {
  var mouse = getMouse(e, document.getElementById('canvas'));
  //console.log(mouse) <--confirmed mouse position is good.
  redraw(document.getElementById('canvas'), mouse);
})
#TML_div {
  position: absolute;
  overflow: hidden;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background-image: url(https://source.unsplash.com/random);
}
html lang-html prettyprint-override"><div id='TML_div'>
  <canvas id='canvas'></canvas>
</div>
 类似资料:
  • 问题内容: 尝试使用awt canvas上的鼠标来绘制图形(目前为线)。Iam首次尝试Java图形。所以不确定如何去做。这是我的第一次尝试: 问题:1)将窗口最小化并还原后,绘制的线条消失了(由于要重新绘制)2)我要的是该线条应跟随鼠标移动(拖动时)。最后一行应该从按下位置到释放鼠标的位置。现在请礼节,当鼠标移动时,将绘制新的线条。我不确定如何清除画布上的中间线。 有人可以帮我解决这些问题吗? 问

  • 有没有可能用画布在Android中实现下面的图片? 我想有一个洞,而不仅仅是在黄色的红色层上有一个圈。我在-method中使用以下代码进行了尝试(但失败了): 但是当我使用这段代码时,它在两个位图上都开了一个洞。最后,这个应用程序应该是一个带有球、洞和其他东西的迷宫。当球掉进洞里时,它应该出现在红色位图下。有可能实现这一点吗? 答: 如果有人也有同样的问题:使用View而不是SurfaceView

  • 我们体验一下Events类吧!为了使其尽量简单,我们使用Events类的getMousePos()获取鼠标光标的坐标,并在画布的左上角显示出来。getMousePos()方法返回相对于画布的坐标,它会考虑画布相对于页面的偏移,以及页面的滚动位置。 图6-1 画布坐标系 操作步骤 按照以下步骤,在每次鼠标移动时,获取画布上的鼠标坐标,并在画布的左上角显示出来: 1. 链接到Events类: <sc

  • 我在画布上处理鼠标事件时遇到问题。我想用鼠标来绘制它,我已经想出了这些事件处理程序,但当我开始绘制时,它们什么都不做。 你能帮我告诉我遗漏了什么或者如何重写它以便它开始工作吗?

  • 问题内容: 将click事件处理程序添加到canvas元素(将返回click的x和y坐标)(相对于canvas元素)的最简单方法是什么? 不需要旧版浏览器兼容性,Safari,Opera和Firefox都可以。 问题答案: 这个答案很老了,它使用检查不再需要的旧浏览器,因为和属性在所有当前浏览器中都有效。您可能想查看PatriquesAnswer,以获得更简单,最新的解决方案。 最初的答案: 正如

  • 现在我有一个应用程序,可以让用户单击按钮浏览用作画布背景的图片。我想这样做,如果用户单击画布上的某个地方,则在该点放置一个节点。我假设我需要获取鼠标坐标。有没有一个简单的方法可以调用将节点放置在鼠标单击位置,或者我必须在这个链接中选择路线:WPF-使用鼠标事件在画布上绘图?提前谢谢。 编辑:添加了我尝试制作椭圆的代码。不过它不起作用,而且我不确定如何使用鼠标点击椭圆的坐标。我知道对于一行来说,它只