Создание изображения с холстом в Javascript - PullRequest
4 голосов
/ 25 февраля 2009

Кажется, я получил сообщение об ошибке, что мне трудно отлаживать. То, что я пытаюсь сделать, это динамически создавать образ, такой как этот (http://www.webreference.com/programming/javascript/mk/column3/creating/cp_mini_gradient_details.png ) с холстом.

Я получаю сообщение об ошибке:

[Exception... "An invalid or illegal string was specified" code: "12" nsresult: "0x8053000c (NS_ERROR_DOM_SYNTAX_ERR)"]

Я погуглил, и, похоже, есть несколько причин для этого сообщения об ошибке, но я не могу найти какие-либо конкретно связанные с canvas.

Вот мой код:

var newCanvas = document.createElement('canvas');
newCanvas.height="30";
newCanvas.width="113";
document.body.appendChild(newCanvas);

var context = newCanvas.getContext('2d');

context.fillStyle = '#FFFFFF';  
context.fillRect(0, 0, 113, 15);
context.fillStyle = '#000000';  
context.fillRect(0, 15, 113, 30);

var numCanH = Number(newCanvas.height);
var numCanW = Number(newCanvas.width);
var imgd;
if (context.createImageData) {
    console.log('context.createImageData');
    imgd = context.createImageData(numCanW, numCanH);
} 
else if (context.getImageData) {
    console.log('context.getImageData');
    imgd = context.getImageData(0, 0, numCanW, numCanH);
} 
else {
    console.log('else');
    imgd = {'width' : numCanW, 'height' : numCanH, 'data' : new Array(numCanW*numCanH*4)};
}  
var pix = imgd.data;
var ndv = numCanW/6;

for (var i = 0; i <= numCanH; i++) {

    var a=1-Math.abs(2*i-numCanH)/numCanH;

    for (var j = 0; j < numCanW; j+=4) {

        var bitUp = Math.ceil((255/130)*j);
        var bitDown = 255-bitUp;

        if(j<(ndv)){    //Red to Yellow - (rgb) 255,0,0 to 255,255,0
            pix[j] = 255; // red channel
            pix[j+1] = bitUp; // green channel
            pix[j+2] = 0; // blue channel 
        }    
        else if(j>(ndv) && j<(ndv)*2){  //Yellow to Green - (rgb) 255,255,0 to 0,255,0
            pix[j] = 255; // red channel
            pix[j+1] = bitDown; // green channel
            pix[j+2] = 0; // blue channel 
        }  
        else if(j>(ndv)*2 && j<(ndv)*3){    //Green to Cyan - (rgb) 0,255,0 to 0,255,255
            pix[j] = 0; // red channel
            pix[j+1] = 255; // green channel
            pix[j+2] = bitUp; // blue channel 
        }  
        else if(j>(ndv)*3 && j<(ndv)*4){    //Cyan to Blue - (rgb) 0,255,255 to 0,0,255
            pix[j] = 0; // red channel
            pix[j+1] = bitDown; // green channel
            pix[j+2] = 255; // blue channel 
        }  
        else if(j>(ndv)*4 && j<(ndv)*5){    //Blue to Magenta - (rgb) 0,0,255 to 255,0,255
            pix[j] = bitUp; // red channel
            pix[j+1] = 0; // green channel
            pix[j+2] = 255; // blue channel 
        }  
        else if(j>(ndv)*5 && j<(ndv)*6){    //Magenta to Red - (rgb) 255,0,255 to 255,0,0
            pix[j] = 255; // red channel
            pix[j+1] = 0; // green channel
            pix[j+2] = bitDown; // blue channel 
        }             

        pix[j+3] = a; // alpha channel+

        console.log('bitUp  '+bitUp);
        console.log(typeof bitUp);
        console.log('bitDown  '+bitDown);
        console.log(typeof bitDown);
        console.log('a  '+j);
        console.log(typeof a);
        console.log('j  '+j);
        console.log(typeof j);
        console.log('i  '+i);
        console.log(typeof i);
        console.log(imgd);
        console.log('before context.putImageData');
        context.putImageData(imgd, j,i);
        console.log('after context.putImageData');      
    }
}

Странно то, что ошибка возникает только во время второй итерации цикла.

1 Ответ

3 голосов
/ 25 февраля 2009

Ваш вызов putImageData пытается нарисовать весь imgd, который вы создали, чтобы быть шириной и высотой холста, в холст с верхним левым углом в (j, i). Это не удается после первой итерации цикла, потому что нижняя / правая часть imgd выходит за нижнюю / правую часть холста.

Возьмите вызов putImageData вне внешнего цикла и сделайте так, чтобы он всегда рисовался в (0,0). Кроме того, при разработке индекса массива пикселя, который вы устанавливаете, не забудьте добавить в i * numCanW * 4; и обратите внимание, что ваш внутренний цикл должен перейти от 0 к iCanW * 4, а не от 0 к iCanW, поскольку вы взаимодействуете с цветными компонентами, а не пикселями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...