2013-05-12 14 views
8

In realtà non so cosa sia successo perché funzionava la scorsa notte. Ad ogni modo, sto cercando di creare un'applicazione di disegno con html5 e javascript. Questa è la prima volta che ho guardato correttamente JS e ho creato qualcosa con esso, così ho ottenuto il mio codice da vari tutorial e aiuto da altri amici a.k.a Sono un n00b. Ho usato il seguente:Unchaught TypeError: Impossibile leggere la 'larghezza' di null

  1. github.com/jaseemkp/paint-app-with-save-facility
  2. codetheory.in/different-tools-for-our-sketching-application/
  3. HTML5 Canvas Ricettario - Capitolo 6: Interazione con la tela: Collegamento di listener di eventi a forme e aree - Creazione di un'applicazione . (Ho avuto la funzione di salvataggio da questo)

quando verifico il mio lavoro in cromo ottengo l'errore

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

che si riferisce alla linea 4 del mio file di script che è

var b_width = canvas.width, b_height = canvas.height; 

Stavo provando a giocherellare con esso per aggiungere una funzione di testo, ma non riuscivo a farlo funzionare, quindi ho solo annullato tutto e ora sta producendo questo errore.

script completo:

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); 

completa 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> 

CSS

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



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

Quando ho caricato ad un free server, ho diversi errori però. Oh sono così confuso, spero che ci sia qualcuno là fuori che possa dare un senso a tutto questo:/

Grazie in anticipo!

risposta

5

Stai importando il tuo script prima del il browser ha avuto la possibilità di analizzare il corpo del documento. In quanto tale, l'elemento <canvas> non esiste nel punto in cui lo si cerca con il suo valore "id".

Dato che si importa jQuery in ogni caso, è possibile utilizzare un gestore "pronto", ma in tal caso si avranno problemi con il modo in cui si collegano i gestori di eventi. I gestori di eventi basati sugli attributi si basano su quelle funzioni di gestione che sono globali, che non saranno se le mettete in un gestore "pronto".

Molto più semplice, tuttavia, sarebbe semplicemente spostare il tag <script> (o entrambi) alla fine dello <body>. In questo modo il pars verrà analizzato e le tue chiamate getElementById() dovrebbero funzionare. Un sacco di persone consigliano che mettere gli script alla fine del <body> dovrebbe essere considerato comunque una buona pratica.

In mancanza di questo, suppongo che quello che si potrebbe fare è qualcosa di simile, cambiando le dichiarazioni nella parte superiore dello script:

$(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": []} 
    }); 
}); 

che sarebbe meglio a uno adozione jQuery completamente e utilizzarlo per assegnare gestori di eventi, o semplicemente non preoccuparti di importarlo.

+0

Grazie mille, questo è quello che ho fatto cambiare, ho spostato le sceneggiature in testa. Grazie ancora! (Sono rimasto sveglio fino a tardi, quindi non potevo ricordare pienamente quello che avevo fatto haha) – swaistle

+0

OK, e il tuo commento mi ha fatto realizzare una soluzione molto più semplice :-) – Pointy

+0

Ahhh sì, stavo giocando con jquery per svilupparmi come un modulo digita cosa in cui l'utente può inserire del testo nel modulo e lo visualizza sulla tela ovunque scelga. quindi il primo passo era creare il modulo in modo che potesse essere mostrato e nascosto da un clic di un pulsante. :) – swaistle

Problemi correlati