2012-03-16 176 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