2013-05-12 12 views
8

지난밤에 무슨 일이 있었는지 실제로 알지 못합니다. 어쨌든 html5 및 javascript로 그리기 응용 프로그램을 만들려고합니다. 내가 JS를 제대로보고 처음으로 그걸로 무언가를 만들었 기 때문에 다양한 튜토리얼에서 코드를 얻었고 다른 친구들의 도움을 받았다. a.k.a 나는 n00b이다. 나는 다음과 같은 사용 :잡히지 않은 TypeError : null의 'width'속성을 읽을 수 없습니다.

  1. github.com/jaseemkp/paint-app-with-save-facility을
  2. codetheory.in/different-tools-for-our-sketching-application/
  3. HTML5 캔버스 요리 책 - 제 6 장 : 캔버스와 상호 작용하기 : 그림 및 그림 영역에 이벤트 리스너 부착 - 그림 그리기 응용 프로그램 만들기.

나는 내가

var b_width = canvas.width, b_height = canvas.height; 
내 스크립트 파일의 4 라인을 참조하는 오류

"Uncaught TypeError: Cannot read property 'width' of null"

을 얻을 크롬에서 내 작품을 테스트 (나는이에서 저장 기능을 가지고)

텍스트 기능을 추가하기 위해 주변을 둘러 보려고했지만 작동하지 않아 모든 것을 취소 했으므로 이제이 오류가 발생합니다.

전체 스크립트를

var canvas = document.getElementById("realCanvas"); 
var tmp_board = document.getElementById("tempCanvas"); 
var b_width = canvas.width, b_height = canvas.height; 
var ctx = canvas.getContext("2d"); 
var tmp_ctx = tmp_board.getContext("2d"); 
var x, y; 
var saved = false, hold = false, fill = false, stroke = true, tool = 'rectangle'; 

var data = {"rectangle": [], "circle": [], "line": []}; 


function curr_tool(selected){tool = selected;} 

function attributes(){ 
    if (document.getElementById("fill").checked) 
     fill = true; 
    else 
     fill = false; 
    if (document.getElementById("outline").checked) 
     stroke = true; 
    else 
     stroke = false; 
} 


function clears(){ 
    ctx.clearRect(0, 0, b_width, b_height); 
    tmp_ctx.clearRect(0, 0, b_width, b_height); 
    data = {"rectangle": [], "circle": [], "line": []}; 
} 

//colour function 
function color(scolor){ 
    tmp_ctx.strokeStyle = scolor; 
    if (document.getElementById("fill").checked) 
     tmp_ctx.fillStyle = scolor; 
} 



//line 

tmp_board.onmousedown = function(e) { 
    attributes(); 
    hold = true; 
    x = e.pageX - this.offsetLeft; 
    y = e.pageY -this.offsetTop; 
    begin_x = x; 
    begin_y = y; 
    tmp_ctx.beginPath(); 
    tmp_ctx.moveTo(begin_x, begin_y);  
} 


tmp_board.onmousemove = function(e) { 
    if (x == null || y == null) { 
     return; 
    } 
    if(hold){ 
     x = e.pageX - this.offsetLeft; 
     y = e.pageY - this.offsetTop; 
     Draw(); 
    } 
} 

tmp_board.onmouseup = function(e) { 
    ctx.drawImage(tmp_board,0, 0); 
    tmp_ctx.clearRect(0, 0, tmp_board.width, tmp_board.height); 
    end_x = x; 
    end_y = y; 
    x = null; 
    y = null; 
    Draw(); 
    hold = false; 
} 



//draw function 
function Draw(){ 

//rectangle 
if (tool == 'rectangle'){ 

    if(!x && !y){ 
    data.rectangle.push({"x": begin_x, "y": begin_y, "width": end_x-begin_x, "height": end_y-begin_y, "stroke": stroke, "strk_clr": tmp_ctx.strokeStyle, "fill": fill, "fill_clr": tmp_ctx.fillStyle }); 
     return; 
    } 
    tmp_ctx.clearRect(0, 0, b_width, b_height); 
    tmp_ctx.beginPath(); 

    if(stroke) 
     tmp_ctx.strokeRect(begin_x, begin_y, x-begin_x, y-begin_y); 
     tmp_ctx.lineWidth = $('#selWidth').val(); 
    if(fill) 
     tmp_ctx.fillRect(begin_x, begin_y, x-begin_x, y-begin_y); 
     tmp_ctx.closePath(); 

    } 

//line 

if (tool == 'line'){ 
    if(!x && !y){ 
     data.line.push({"x": begin_x, "y": begin_y, "width": end_x-begin_x, "height": end_y-begin_y, "stroke": stroke, "strk_clr": tmp_ctx.strokeStyle,}); 
     return; 
    } 
    tmp_ctx.beginPath(); 
    if(stroke) 
    tmp_ctx.strokeRect(begin_x, begin_y, x-begin_x, y-begin_y); 
    tmp_ctx.clearRect(0, 0, tmp_board.width, tmp_board.height); 
    tmp_ctx.beginPath(); 
    tmp_ctx.moveTo(begin_x, begin_y); 
    tmp_ctx.lineTo(x, y); 
    tmp_ctx.lineWidth = $('#selWidth').val(); 
    tmp_ctx.stroke(); 
    tmp_ctx.closePath(); 

    } 

//circle 

else if (tool == 'circle'){ 
    if(!x && !y){ 
     data.circle.push({"x": begin_x, "y": begin_y, "radius": end_x-begin_x, "stroke": stroke, "strk_clr": tmp_ctx.strokeStyle, "fill": fill, "fill_clr": tmp_ctx.fillStyle }); 
     return; 
    } 
    tmp_ctx.clearRect(0, 0, b_width, b_height); 
    tmp_ctx.beginPath(); 
    tmp_ctx.arc(begin_x, begin_y, Math.abs(x-begin_x), 0 , 2 * Math.PI, false); 

    if(stroke) 
    tmp_ctx.stroke(); 
    tmp_ctx.lineWidth = $('#selWidth').val(); 
    if(fill) 
    tmp_ctx.fill(); 
    tmp_ctx.closePath(); 

    } 

} 

//save function 
//set up image of canvas 
function getCanvasImg(canvas){ 
    var img = new Image(); 
    img.src = canvas.toDataURL(); 
    return img; 
} 
//get image of canvas 
window.onload = function(){ 
    var events = new Events("tempCanvas"); 
    var canvas = events.getCanvas(); 
    var context = events.getContext(); 
} 
//open image of canvas in new window in click of button 
document.getElementById("saveButton").addEventListener("click", function(evt){ 
    //open new window with saved image, right click and save 
    window.open(canvas.toDataURL()); 
}, false); 

전체 HTML

<!doctype html> 
<html> 
<head> 
    <title>LogoMakr</title> 
    <link rel="stylesheet" href="style.css" type="text/css"> 
    <script src="jquery.min.js"></script> 
    <script src="script.js"> </script> 
</style> 
</head> 
<body> 
    <div class="tools"> 
     <button type="button" id="saveButton" value="Save">Save</button> 
     <button type="button" onclick="clears()">CLEAR</button> 
     <button type="button" onclick="curr_tool('rectangle')">Rectangle</button> 
     <button type="button" onclick="curr_tool('circle')">Circle</button> 
     <button type="button" onclick="curr_tool('line')">Line</button> 

    </div> 

    <table id="table1" > 
     <tr> 
     <tr> 
      <td><button onclick="color('black')" style="background-color: black; height: 20px; width: 20px;"></button></td> 
      <td><button onclick="color('white')" style="background-color: white; height: 20px; width: 20px;"></button></td> 
      <td><button onclick="color('green')" style="background-color: green; height: 20px; width: 20px;"></button></td> 
      <td><button onclick="color('blue')" style="background-color: blue; height: 20px; width: 20px;"></button></td> 
      <td><button onclick="color('yellow')" style="background-color: yellow; height: 20px; width: 20px;"></button></td> 
      <td><button onclick="color('red')" style="background-color: red; height: 20px; width: 20px;"></button></td> 
      <td><button onclick="color('#ff6600')" style="background-color: #ff6600; height: 20px; width: 20px;"></button></td> 
      <td><button onclick="color('#663300')" style="background-color: #663300; height: 20px; width: 20px;"></button></td> 
      <td><button onclick="color('grey')" style="background-color: grey; height: 20px; width: 20px;"></button></td> 
      <td><button onclick="color('#FF6699')" style="background-color: #FF6699; height: 20px; width: 20px;"></button></td> 
      <td><button onclick="color('#8b00ff')" style="background-color: #8b00ff; height: 20px; width: 20px;"></button></td> 
      <td><input type="checkbox" id="fill"/>Fill</td> 
      <td><input type="checkbox" id="outline" checked="checked"/>Outline</td> 

      <td>Line Width:</td> 
      <td><select id="selWidth"> 
        <option value="1">1</option> 
        <option value="3">3</option> 
        <option value="5" selected="selected">5 </option> 
        <option value="7">7</option> 
        <option value="9" >9</option> 
        <option value="11">11</option> 
        </select> 
      </td> 
     </tr> 
    </table> 


    <div> 
     <canvas id="realCanvas" width="680" height="460" style=" background-color: #ffffff; z-index: 0" ></canvas> 
     <canvas id="tempCanvas" width="680" height="460" style="z-index: 1"></canvas> 
    </div> 



</body> 
</html> 

나는 free server에 업로드 한 CSS

#realCanvas, #tempCanvas { 
    position: absolute; 
    left:280px; 
    top:50px; 
    border: 5px solid; 
    cursor: crosshair; 
} 



#table1{ 
    position: absolute; 
    left:400px; 
    top:5px; 
} 

은, 그래도 난 다른 오류를 가지고있다. 오, 너무 혼란스러워,저기서 누군가를 이해할 수 있기를 바랍니다./

미리 감사드립니다!

답변

5

브라우저 을 가져 오기 전에 전에 브라우저에서 문서 본문을 구문 분석 할 수 있습니다. 따라서 <canvas> 요소는 "id"값으로 검색 할 때 존재하지 않습니다.

어쨌든 jQuery를 가져 오기 때문에 "준비"핸들러를 사용할 수 있지만 이벤트 핸들러를 연결하는 방법에 몇 가지 문제가 있습니다. 애트리뷰트 기반 이벤트 핸들러는 글로벌 인 핸들러 함수에 의존한다. 핸들러 함수를 "ready"핸들러에 넣는다면 그렇지 않을 것이다.

그러나 훨씬 간단하면 <script> 태그 (또는 둘 다)를 <body>의 맨 끝으로 옮기면됩니다. 그렇게하면 DOM이 파싱되고 getElementById() 호출이 작동합니다. 많은 사람들은 <body> 끝에 스크립트를 두는 것이 가장 좋은 방법이라고 생각해야합니다.

$(function() { 
    $.extend(window, { 
    canvas: document.getElementById("realCanvas"), 
    tmp_board: document.getElementById("tempCanvas"), 
    b_width: canvas.width, b_height = canvas.height, 
    ctx: canvas.getContext("2d"), 
    tmp_ctx: tmp_board.getContext("2d"), 
    x: undefined, 
    y: undefined, 
    saved: false, 
    hold: false, 
    fill: false, 
    stroke: true, 
    tool: 'rectangle', 
    data: {"rectangle": [], "circle": [], "line": []} 
    }); 
}); 

완전히 jQuery를 채택하고 할당을 사용하거나 더 나은 것 : 그 실패

, 나는 당신이 할 수있는 것은 스크립트의 상단에있는 선언을 변경,이 같은 것입니다 가정 이벤트 처리기를 사용하거나 아니면 가져 오기를 신경 쓰지 않아도됩니다.

+0

대단히 고맙습니다. 그게 내가 바꾼 것입니다. 스크립트를 머리로 옮겼습니다. 다시 감사합니다! (내가 그렇게 늦게까지 그렇게 내가 완전히 하하했는지 기억할 수 없었다) – swaistle

+0

괜찮아 - 그리고 당신의 의견은 훨씬 간단한 해결책을 깨닫게했다 :-) – Pointy

+0

Ahhh yeah는 양식처럼 발전시키기 위해 jquery로 놀고 있었다. 사용자가 양식에서 텍스트를 입력 할 수 있고 캔버스에 그들이 선택한 곳마다 표시 할 수있는 유형의 항목입니다. 첫 번째 단계는 양식을 작성하여 버튼 클릭만으로 표시하고 숨길 수있게하는 것입니다. :) – swaistle

관련 문제