gpt4 book ai didi

javascript - 如何计算点击可拖动 Canvas 元素的位置?

转载 作者:行者123 更新时间:2023-11-30 13:47:29 25 4
gpt4 key购买 nike

我需要帮助解决一个非常困难的问题。我目前正在使用 React 和 Redux 制作游戏。在这个游戏中,我使用 Canvas 从我的 redux 商店创建 map 数据。目前 map 只是一个黑白方 block 矩阵。假设我想在单击正方形时更改其颜色,同时保持拖动元素的能力。问题是很难精确定位鼠标点击的位置,因为元素可以拖动到页面上的任何位置。据我所知,似乎没有任何 mouseclick 事件对象属性能够告诉我。我以为 offsetX 和 offsetY 会告诉我,但当 Canvas 对象出于某种原因移动时,它们似乎不会保持不变。

我在这个项目中使用 React 和 Redux,并且 CanvasMap 元素包装在这个库中的 Draggable 中:https://www.npmjs.com/package/react-draggable#draggablecore

import React from 'react'
import { connect } from 'react-redux'
import './CanvasMap.css'

class CanvasMap extends React.Component{

componentDidMount() {
const map = this.props.map //Data representing the map
const canvas = this.refs.canvas
const context = canvas.getContext('2d')

//Building the map on the canvas
for(let i = 0; i < map.length; i++){
for(let j = 0; j < map[i].length; j++){
const x=i*100
const y=j*100
const isBlackSquare= map[i][j] === 'black' ? true : false
if(isBlackSquare) context.fillRect(x, y, 100, 100)
else context.strokeRect(x, y, 100, 100)
}
}

function handleClick(e){
//None of the event properties seem to stay the same when the canvas is moved
console.log(e)
}


canvas.addEventListener('click', handleClick)
}

render(){
return (
<div className='Map'>
<canvas ref='canvas' width={8000} height={8000} />
</div>
)
}
}

function mapStateToProps(state){
return {
map: [...state.map]
}
}

const connectedComponent = connect(mapStateToProps)(CanvasMap)
export { connectedComponent as CanvasMap }

最佳答案

在大多数情况下,当您单击 HTML 元素时,您可以使用 rectangleBounding Box 并从中获取协调器,例如

domRect = element.getBoundingClientRect();

在 Canvas 点击位置有点困难

这是我前一段时间在 Canvas 上拖动鼠标时绘制的脚本。也许你可以应用这个方法

<html>
<head>
<style>

* { margin:0; padding:0; } /* to remove the top and left whitespace */

html, body { width:100%; height:100%; } /* just to be sure these are full screen*/

canvas { display:block; } /* To remove the scrollbars */



</style>
</head>

<body>
<canvas id="canvas" ></canvas>
<script>



////////////////////////////////////////


(function() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

var elemLeft = canvas.offsetLeft;
var elemTop = canvas.offsetTop;
var BB=canvas.getBoundingClientRect();
var offsetX=BB.left;
var offsetY=BB.top;

// resize the canvas to fill browser window dynamically
window.addEventListener('resize', resizeCanvas, false);

function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

/**
* Your drawings need to be inside this function otherwise they will be reset when
* you resize the browser window and the canvas goes will be cleared.
*/
drawStuff();
}
resizeCanvas();

function drawStuff() {
// do your drawing stuff here
var img = new Image();

img.src = 'images/3PkBe.gif';
img.onload = function()
{
//var canvas = document.getElementById('canvas');
// create pattern
var ptrn = ctx.createPattern(img, 'repeat'); // Create a pattern with this image, and set it to "repeat".
ctx.fillStyle = ptrn;
ctx.fillRect(0, 0, canvas.width, canvas.height); // context.fillRect(x, y, width, height);
ctx.shadowBlur=20;
//ctx.shadowColor="black";
//ctx.fillStyle="green";
//ctx.fillRect(20,160,100,80);


ctx.strokeStyle = "lightgray";

//var canvasOffset = canvas.offset();
//var offsetX = canvasOffset.left;
//var offsetY = canvasOffset.top;

var mouseIsDown = false;
var lastX = 0;
var lastY = 0;
var elements = [];

makeShip( 30 , 30,120, 120, '#119' , "romea");
makeShip( 30, 160,120, 120, '#393', "fomar");
makeShip( 30, 290,120, 120, '#955', "ojab");
makeShip( 30, 420,120, 120, '#6ff', "eliot");
// Add event listener for `click` events.

canvas.addEventListener('click', function(event) {

var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
console.info(x, y);
elements.forEach(function(element) {

if (y > element.y && y < element.y + element.height && x > element.x && x < element.x + element.width) {
console.log(element.name);
}
});





}, false);

canvas.addEventListener('mousedown', function(event) {

var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
console.info(x, y);
elements.forEach(function(element) {

if (y > element.y && y < element.y + element.height && x > element.x && x < element.x + element.width) {
console.info(element.name);
handleMouseDown(element);
}
});



}, false);

canvas.addEventListener('mousemove', function(event) {


var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
console.info(x, y);
elements.forEach(function(element) {

if (y > element.y && y < element.y + element.height && x > element.x && x < element.x + element.width) {
console.info(element.name);
handleMouseMove(element,x,y);
}
});

}, false);

canvas.addEventListener('mouseup', function(event) {


var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
//console.info(x, y);

elements.forEach(function(element) {

//if (y > element.y && y < element.y + element.height && x > element.x && x < element.x + element.width) {
console.info(element.name + "mouse up evenr=========");
handleMouseUp(element);
//}
});

}, false);




function makeShip(x, y, width, height, colour,ShipName) {
var ship = {
name: ShipName,
colour: colour,
width: width,
height: height,
x: x,
y: y
}
elements.push(ship);
return (ship);
}
function drawShip(ship) {

//ctx.fillStyle = ship.colour;
//ctx.fillRect(ship.x, ship.y, ship.width, ship.height);
//ctx.fillRect(element.x, element.y, element.width, element.height);
}

function drawAllShips() {
// ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < elements.length; i++) {
var ship = elements[i]
//drawShip(ship);
ctx.fillStyle = ship.colour;
ctx.fillRect(ship.x , ship.y, ship.width, ship.height);
// ctx.fillStyle = ship.fill;
// ctx.fill();
// ctx.stroke();
}
}




// Add element.
//elements.push({
//colour: '#05EFFF',
//width: 150,
//height: 100,
//x: 20,
//y: 15
//});

// Render elements.
// elements.forEach(function(element) {
// ctx.fillStyle = element.colour;
// ctx.fillRect(element.x, element.y, element.width, element.height);
// });

drawAllShips();


function handleMouseDown(e) {
mouseX = e.x ;
mouseY = e.y ;

//mouseX = parseInt(e.x - offsetX);
//mouseY = parseInt(e.y - offsetY);
console.log("===========Problem "+mouseX);
// mousedown stuff here
lastX = mouseX;
lastY = mouseY;
mouseIsDown = true;
//alert("mouse Handle");

}

function handleMouseUp(e) {
//mouseX = parseInt(e.clientX - offsetX);
//mouseY = parseInt(e.clientY - offsetY);

ctx.onmousemove = null;
// mouseup stuff here
mouseIsDown = false;
return
}

function handleMouseMove(e,x,y) {
if (mouseIsDown) {



//console.log(' no fuck');
mouseX = e.x ;
mouseY = e.y ;
console.log(e.name+"is truing to drag");

// mousemove stuff here
//for (var i = 0; i < elements.length; i++) {

//if (ctx.isPointInPath(mouseX, mouseY)) {
//console.log('============== no fuck');
var ship =e;// elements[i];
ship.x = x-15;//(mouseX - lastX);
ship.y = y-20;//(mouseY -lastY);
// ship.right = ship.x + ship.width;
// ship.bottom = ship.y + ship.height;

//drawShip(ship);
//}

//}
lastX = mouseX;
lastY = mouseY;
drawAllShips();
}
}

<!-- ctx.mousedown(function (e) { -->
<!-- handleMouseDown(e); -->
<!-- }); -->
<!-- ctx.mousemove(function (e) { -->
<!-- handleMouseMove(e); -->
<!-- }); -->
<!-- ctx.mouseup(function (e) { -->
<!-- handleMouseUp(e); -->
<!-- }); -->

}



}
})();
</script>
</body>
</html>

关于javascript - 如何计算点击可拖动 Canvas 元素的位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58986251/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com