【问题标题】:Mouse pointer coordinates and canvas coordinates not matching鼠标指针坐标和画布坐标不匹配
【发布时间】:2017-02-08 14:19:48
【问题描述】:

我正在尝试使用画布绘制一条线。画线时,我的鼠标指针坐标和画布坐标不匹配。如果我在画布顶部拖动鼠标,它会在底部画一条线。谁能确定我在这里做错了什么。我尝试了以下示例。

小提琴:https://jsfiddle.net/Shathiran/bpunb9dn/5/

var canvas, ctx, flag = false, prevX = 0, currX = 0, prevY = 0, currY = 0, dot_flag = false;
	
	    var x = "black", y = 2;
	    
	    function init() {
	        canvas = document.getElementById('drawCanvas');
	        ctx = canvas.getContext("2d");
	        w = ctx.clientWidth;
	        h = ctx.clientHeight;
          
	        canvas.addEventListener("mousemove", function (e) {
	            findxy('move', e)
	        }, false);
	        canvas.addEventListener("mousedown", function (e) {
	            findxy('down', e)
	        }, false);
	        canvas.addEventListener("mouseup", function (e) {
	            findxy('up', e)
	        }, false);
	        canvas.addEventListener("mouseout", function (e) {
	            findxy('out', e)
	        }, false);
	    }

	    function draw() {
	        ctx.beginPath();
	        ctx.moveTo(prevX, prevY);
	        ctx.lineTo(currX, currY);
	        ctx.strokeStyle = x;
	        ctx.lineWidth = y;
	        ctx.stroke();
	        ctx.closePath();
	    }
	    
	    function findxy(res, e) {
	        if (res == 'down') {
	            prevX = currX;
	            prevY = currY;
	            currX = e.clientX - canvas.offsetLeft;
	            currY = e.clientY - canvas.offsetTop;
	    
	            flag = true;
	            dot_flag = true;
	            if (dot_flag) {
	                ctx.beginPath();
	                ctx.fillStyle = x;
	                ctx.fillRect(currX, currY, 2, 2);
	                ctx.closePath();
	                dot_flag = false;
	            }
	        }
	        if (res == 'up' || res == "out") {
	            flag = false;
	        }
	        if (res == 'move') {
	            if (flag) {
	                prevX = currX;
	                prevY = currY;
	                currX = e.clientX - canvas.offsetLeft;
	                currY = e.clientY - canvas.offsetTop;
	                draw();
	            }
	        }
	    }
	    init();
<div class="paper">
    <canvas id="drawCanvas" style="width:100%; height:100%;border: 1px solid #000">     </canvas>
</div>

【问题讨论】:

    标签: javascript html canvas html5-canvas


    【解决方案1】:

    你的鼠标位置很好。这里的问题是您如何分配画布的widthheight,主要是因为您通过CSS 将其设置为除widthheight 属性之外的样式(“拉伸”画布) (有关更多信息,请参阅this question)。要解决此问题,请将您的 width/height 设置为画布的 HTML 属性。

    例如:

    var canvas, ctx, flag = false, prevX = 0, currX = 0, prevY = 0, currY = 0, dot_flag = false;
    	
    	    var x = "black", y = 2;
    	    
    	    function init() {
    	        canvas = document.getElementById('drawCanvas');
                canvas.setAttribute('width', canvas.parentNode.offsetWidth);
                canvas.setAttribute('height', canvas.parentNode.offsetHeight);
    	        ctx = canvas.getContext("2d");
    	        w = ctx.clientWidth;
    	        h = ctx.clientHeight;
              
    	        canvas.addEventListener("mousemove", function (e) {
    	            findxy('move', e)
    	        }, false);
    	        canvas.addEventListener("mousedown", function (e) {
    	            findxy('down', e)
    	        }, false);
    	        canvas.addEventListener("mouseup", function (e) {
    	            findxy('up', e)
    	        }, false);
    	        canvas.addEventListener("mouseout", function (e) {
    	            findxy('out', e)
    	        }, false);
    	    }
    
    	    function draw() {
    	        ctx.beginPath();
    	        ctx.moveTo(prevX, prevY);
    	        ctx.lineTo(currX, currY);
    	        ctx.strokeStyle = x;
    	        ctx.lineWidth = y;
    	        ctx.stroke();
    	        ctx.closePath();
    	    }
    	    
    	    function findxy(res, e) {
    	        if (res == 'down') {
    	            prevX = currX;
    	            prevY = currY;
                    var cRect = canvas.getBoundingClientRect();
    	            currX = e.clientX - cRect.offsetLeft;
    	            currY = e.clientY - cRect.offsetTop;
    	    
    	            flag = true;
    	            dot_flag = true;
    	            if (dot_flag) {
    	                ctx.beginPath();
    	                ctx.fillStyle = x;
    	                ctx.fillRect(currX, currY, 2, 2);
    	                ctx.closePath();
    	                dot_flag = false;
    	            }
    	        }
    	        if (res == 'up' || res == "out") {
    	            flag = false;
    	        }
    	        if (res == 'move') {
    	            if (flag) {
    	                prevX = currX;
    	                prevY = currY;
    	                currX = e.clientX - canvas.offsetLeft;
    	                currY = e.clientY - canvas.offsetTop;
    	                draw();
    	            }
    	        }
    	    }
    	    init();
    <div class="paper" width="400">
        <canvas id="drawCanvas" width="200" height="200" style="border: 1px solid #000">     </canvas>
    </div>

    注意您可以使用window.innerWidthwindow.innerHeight 将画布高度和宽度设置为100%。尽管如果您希望它动态更改,则需要在调整大小时对其进行更新:

    canvas.setAttribute('width', window.innerWidth);
    canvas.setAttribute('height', window.innerHeight);
    

    【讨论】:

    • 是的,这很好,但我需要将 的宽度和高度固定在
      之上
    • 有什么方法可以设置画布宽度高度响应父
      标签。
    • @SharanDeSilva 是的,您可以通过执行以下操作将宽度/高度设置为父级的宽度/高度:canvas.setAttribute('width', canvas.parentNode.offsetWidth)。我在编辑中添加了它。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签