2012-03-16 173 views
3

我想要一个包含客户签名框的HTML5页面。这在大多数情况下会用在平板电脑上。这是通过Canvas元素和鼠标上的JavaScript事件完成的。HTML5画布和鼠标事件问题

问题1:Y部分完美地工作,但X部分只会在我将画布设置为300时工作。如果宽度为500,那么X部分在x坐标0处正确。当用户绘制到x-coord 300,屏幕上的线条现在位于画布上的500px标记处。在我的代码中,无论什么都设置为300px,所以我只是不知道发生了什么。

问题2:我有停止在平板电脑上滚动并允许用户登录画布的代码(请参阅“阻止JavaScript中的var”)。这根本不起作用。

HTML:

<div id="canvasDiv"> 
    <canvas id="canvasSignature"></canvas> 
</div> 

CSS:(使得宽度100%最高至500像素,始终150像素高)

#canvasDiv 
{ 
    float: left; 
    width: 100%; 
    height: 150px; 
    max-width: 500px; 
} 

#canvasSignature 
{ 
    width: 100%; 
    height: 100%; 
    background-color: #F0F0F0; 
    border: 1px solid Black; 
    cursor: crosshair; 
} 

JavaScript的:

<script type="text/javascript"> 
    $(document).ready(function() { 
     initialize(); 
    }); 

    var prevent = false; 

    // works out the X, Y position of the click INSIDE the canvas from the X, Y position on the page 
    function getPosition(mouseEvent, element) { 
     var x, y; 
     if (mouseEvent.pageX != undefined && mouseEvent.pageY != undefined) { 
     x = mouseEvent.pageX; 
     y = mouseEvent.pageY; 
     } else { 
     x = mouseEvent.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; 
     y = mouseEvent.clientY + document.body.scrollTop + document.documentElement.scrollTop; 
     } 

     x = x - element.offsetLeft; 
     return { X: x, Y: y - element.offsetTop }; 
    } 

    function initialize() { 
     // get references to the canvas element as well as the 2D drawing context 
     var element = document.getElementById("canvasSignature"); 
     var context = element.getContext("2d"); 

     // start drawing when the mousedown event fires, and attach handlers to 
     // draw a line to wherever the mouse moves to 
     $("#canvasSignature").mousedown(function (mouseEvent) { 
     var position = getPosition(mouseEvent, element); 

     context.moveTo(position.X, position.Y); 
     context.beginPath(); 
     prevent = true; 

     // attach event handlers 
     $(this).mousemove(function (mouseEvent) { 
      drawLine(mouseEvent, element, context); 
     }).mouseup(function (mouseEvent) { 
      finishDrawing(mouseEvent, element, context); 
     }).mouseout(function (mouseEvent) { 
      finishDrawing(mouseEvent, element, context); 
     }); 
     }); 

     document.addEventListener('touchmove', function (event) { 
     if (prevent) { 
      event.preventDefault(); 
     } 

     return event; 
     }, false); 
    } 

    // draws a line to the x and y coordinates of the mouse event inside 
    // the specified element using the specified context 
    function drawLine(mouseEvent, element, context) { 

     var position = getPosition(mouseEvent, element); 

     context.lineTo(position.X, position.Y); 
     context.stroke(); 
    } 

    // draws a line from the last coordiantes in the path to the finishing 
    // coordinates and unbind any event handlers which need to be preceded 
    // by the mouse down event 
    function finishDrawing(mouseEvent, element, context) { 
     // draw the line to the finishing coordinates 
     drawLine(mouseEvent, element, context); 

     context.closePath(); 

     // unbind any events which could draw 
     $(element).unbind("mousemove") 
       .unbind("mouseup") 
       .unbind("mouseout"); 
     prevent = false; 
    } 
</script> 
+0

如果你真的把jsfiddle.net中的一个小例子放在一起来说明问题,那会很好。 – Strelok 2012-03-16 17:04:42

+1

为你创建一个:http://jsfiddle.net/begCd/5/ – Atif 2012-03-16 17:11:36

回答

2
#canvasSignature 
{ 
    width: 100%; 
    height: 100%; 
    background-color: #F0F0F0; 
    border: 1px solid Black; 
    cursor: crosshair; 
} 

这不好!作为一个经验法则,你永远不想改变画布的CSS宽度/高度。

你的字面意思是伸展一个尺寸为300x150的画布以歪斜整个屏幕。这可能是您的鼠标问题的99%的来源。

原因是似乎y方向精细纯属巧合:画布是默认300x150,你有一个div是150高,所以没有歪斜由CSS。但是如果你想要div高到200你也会在那里看到问题!

您需要设置画布的高度和宽度属性和为CSS属性:

<canvas id="canvasSignature" width="500" height="150"></canvas> 
在JavaScript

要不然:

var can = document.getElementById('canvasSignature'); 
can.width = 500; 
can.height = 150; 

它看起来像你想拥有画布宽度动态变化。这是好的,但你必须做一些事情。一种方法是使用窗口的onresize事件,并在每次发生此情况时(如果clientWidth已更改)将画布宽度设置为div的clientWidth。另一种做法是做一个简单的普通计时器,每半秒钟检查一次相同的事情。


请注意,我没有检查getPosition函数的有效性。那里可能有其他的错误,可能是一个单独的问题,但它可能确定。

+0

在http://jsfiddle.net/begCd/7/上测试它。这解决了问题#1 – Atif 2012-03-16 17:13:41

+0

谢谢!我从Atif的更新#7修正了“宽度”上的拼写,并将大小调整事件添加为http://jsfiddle.net/begCd/13/。问题#1解决了。 – Paul 2012-03-16 18:07:46

+0

对于没有得到“不使用CSS的宽度/高度”的人,这里有一些更多的信息。宽度/高度为300px和150px时生成画布。您可以在标记中覆盖此项。 CSS所做的是将现有的画布调整为新的大小。当一个典型的HTML组件被调整大小时,浏览器可以处理这个问题。但画布是像素的集合。所以这些像素会伸展出来,画布上的图像会被拉伸。 (同样,空白画布也拉伸,因此无法按预期工作)。 – Paul 2012-03-29 19:21:51