相机在画布上

时间:2018-08-09 11:27:03

标签: javascript canvas

我们需要的地图总大小为1000x1000,但是VIEW部分只有100x100,该怎么办?我能以某种方式指出VIEW屏幕开始和结束的坐标。 enter image description here

1 个答案:

答案 0 :(得分:0)

类似这样的东西

Math.rad = function(deg) {
  return deg * Math.PI / 180;
};

let tilesTotalX = 200,
    tilesTotalY = 200,
    tilesVisibleX = 10,
    tilesVisibleY = 7,
    tileWidth = 20,
    tileHeight = 20;

let worldSize = {
    w: tilesTotalX * tileWidth,
    h: tilesTotalY * tileHeight
};

let windowSize = {
    w: tilesVisibleX * tileWidth,
    h: tilesVisibleY * tileHeight
};

let tiles = [];
for (let row = 0; row < tilesTotalY; row++) {
    tiles.push([]);
    for (let col = 0; col < tilesTotalX; col++) {
        let r = (Math.floor(0xFF * (row / tilesTotalY))).toString(16),
            g = (Math.floor(0xFF * (col / tilesTotalX))).toString(16),
            b = (Math.floor(0xFF * Math.random())).toString(16);
        tiles[row].push(`#${r}${g}${b}`);
    }
}

let angle = 0,
step = .3;

let circle = {
    x: Math.round((worldSize.w - windowSize.w) / 2),
    y: Math.round((worldSize.h - windowSize.h) / 2),
    r: Math.round(((worldSize.h - windowSize.h) / 2) * .8),
};

let ctx = c.getContext("2d");
ctx.fillStyle = "#f0f0f0";
ctx.fillRect(0, 0, windowSize.w, windowSize.h);

let fps = 16,
    fpsInterval = 1000 / fps,
    then = Date.now();

(function animate(){
    requestAnimationFrame(animate);

    let now = Date.now(),
        elapsed = now - then;
    if (elapsed > fpsInterval) {
        then = now - (elapsed % fpsInterval);

        angle += step;
        angle %= 360;
        //console.log(angle);

        let windowPosition = {
            x: Math.round(circle.x + Math.cos(Math.rad(angle)) * circle.r),
            y: Math.round(circle.y - Math.sin(Math.rad(angle)) * circle.r)
        };

        let firstVisibleRowIndex = Math.floor(windowPosition.y / tileHeight),
            firstVisibleColIndex = Math.floor(windowPosition.x / tileWidth),
            lastVisibleRowIndex = Math.floor((windowPosition.y + windowSize.h) / tileHeight),
            lastVisibleColIndex = Math.floor((windowPosition.x + windowSize.w) / tileWidth);

        let offset = {
            x: windowPosition.x - tileWidth * Math.floor(windowPosition.x / tileWidth),
            y: windowPosition.y - tileHeight * Math.floor(windowPosition.y / tileHeight)
        };

        ctx.save();
        ctx.translate(-offset.x, -offset.y);
        for (let row = firstVisibleRowIndex; row <= lastVisibleRowIndex; row++) {
            for (let col = firstVisibleColIndex; col <= lastVisibleColIndex; col++) {
                ctx.fillStyle = tiles[row][col];
                ctx.fillRect(
                    tileWidth * (col - firstVisibleColIndex),
                    tileHeight * (row - firstVisibleRowIndex),
                    tileWidth,
                    tileHeight
                );
            }
        }
        ctx.restore();
    }
})();
<canvas id=c width=200 height=140></canvas>