Javascript Canvas刷新闪烁

时间:2013-12-01 02:06:50

标签: javascript html5 canvas

我正在用html5 / javascript写一个基本的国际象棋gui,我有一个关于如何在重绘画布控件时避免闪烁的问题。基本上我是从2D数组中绘制棋子,每次重绘数组时,我都会清除画布,这会产生轻微的闪烁。什么是避免这种情况的最佳方法?提前谢谢你,戴夫。

//Array of chess pieces
var PieceArray = ["Null", "WhiteKing", "WhiteQueen", "WhiteKnight", "WhiteBishop", "WhiteRook", "WhitePawn", "BlackKing", "BlackQueen", "BlackKnight", "BlackBishop", "BlackRook", "BlackPawn"]

//Current state of the chess pieces on the board
var BoardArray = [[11, 9, 10, 8, 7, 10, 9, 11],
                  [12, 12, 12, 12, 12, 12, 12, 12],
                  [0, 0, 0, 0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0, 0, 0, 0],
                  [6, 6, 6, 6, 6, 6, 6, 6],
                  [5, 3, 4, 2, 1, 4, 3, 5]];

//Param1: Image Url
//Param2: X position
//Param3: Y position
function Draw(image, x, y) {
    var can = document.getElementById('ChessBoard');
    var context = can.getContext('2d');
    context.clearRect(0, 0, can.width, can.height);
    var imageObj = new Image();
    imageObj.src = 'Sprites/' + image + ".png";
    imageObj.onload = function () {
        context.drawImage(imageObj, x, y);
    };
}

//Function that draws the chess pieces to the canvas
function DrawPieces() {
    var array2;
    for (var i = 0; i < BoardArray.length; i++) {
        array2 = BoardArray[i];
        for (var x = 0; x < array2.length; x++) {
            if (array2[x] != "Null") {
                Draw(PieceArray[array2[x]], x * 70, i * 70);
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

您正在进行不必要的重新加载和DOM查找。在这种情况下,图像的重新加载将是原因,因为在您绘制图像之前图像可能无法解码并准备好。

将那些东西缓存在draw方法之外,它应该可以工作:

var can = document.getElementById('ChessBoard');
var context = can.getContext('2d');
var imageObj = new Image();

imageObj.onload = function () {
    /// start you loop/logic here instead...
    DrawPieces()
};
imageObj.src = 'Sprites/' + image + ".png";

function Draw(image, x, y) {
    context.drawImage(imageObj, x, y);
}

//Function that draws the chess pieces to the canvas
function DrawPieces() {

    /// also move clear here or none of the pieces but
    /// the last will show
    context.clearRect(0, 0, can.width, can.height);

    var array2;
    for (var i = 0; i < BoardArray.length; i++) {
        array2 = BoardArray[i];
        for (var x = 0; x < array2.length; x++) {
            if (array2[x] != "Null") {
                Draw(PieceArray[array2[x]], x * 70, i * 70);
            }
        }
    }
}

请注意,当图像已加载然后时,您将转到下一步(循环或输入逻辑等)。

答案 1 :(得分:0)

这样的事情可能有用吗? (未经测试)

//Array of chess pieces
var PieceArray = ["Null", "WhiteKing", "WhiteQueen", "WhiteKnight", "WhiteBishop", "WhiteRook", "WhitePawn", "BlackKing", "BlackQueen", "BlackKnight", "BlackBishop", "BlackRook", "BlackPawn"]

var PieceImages = {};

//Current state of the chess pieces on the board
var BoardArray = [[11, 9, 10, 8, 7, 10, 9, 11],
                  [12, 12, 12, 12, 12, 12, 12, 12],
                  [0, 0, 0, 0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0, 0, 0, 0],
                  [6, 6, 6, 6, 6, 6, 6, 6],
                  [5, 3, 4, 2, 1, 4, 3, 5]];

//Param1: Image Url
//Param2: X position
//Param3: Y position
function Draw(image, x, y) {
    var can = document.getElementById('ChessBoard');
    var context = can.getContext('2d');
    context.clearRect(0, 0, can.width, can.height);

    if (PieceImages[image]) {
        if (PieceImages[image].complete) {
            context.drawImage(PieceImages[image], x, y);
        }
    }
    else {
        PieceImages[image] = new Image();
        PieceImages[image].src = 'Sprites/' + image + ".png";
    }
}

//Function that draws the chess pieces to the canvas
function DrawPieces() {
    var array2;
    for (var i = 0; i < BoardArray.length; i++) {
        array2 = BoardArray[i];
        for (var x = 0; x < array2.length; x++) {
            if (array2[x] != "Null") {
                Draw(PieceArray[array2[x]], x * 70, i * 70);
            }
        }
    }
}