javascript画布绘制的形状看起来像它们重叠,即使x和y说它们是并排的

时间:2016-10-22 15:03:09

标签: javascript html5-canvas

这里我试图并排绘制具有相同不透明度的正方形。

尽管每个正方形x的位置恰好是一个正方形的宽度,但它们看起来好像在它们上面绘制了更多的半透明正方形。第一个正方形具有较高的不透明度,而在最后一个正方形较少,这会产生这种正方形效果的渐变效果。

Result

我有控制台注销了正在渲染的方块数,它符合预期。所以我不相信在它们上面有额外的正方形。 我还检查了x位置,看是否有任何重叠,但没有。那么什么可能导致广场有不同的透明度?

const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
const canvas = document.getElementById("app-canvas");
canvas.width = windowWidth;
canvas.height = windowHeight;
canvas.style.position = "absolute";
canvas.style.backgroundColor = "grey";
canvas.style.zIndex = 1;
document.body.appendChild(canvas);

class Scene {
    constructor() {
        this.orbs = [];
        this.squares = [];
        this.context = canvas.getContext("2d");
    }

    addOrb(orb) {
        this.orbs.push(orb);
    }

    addSquare(square) {
        this.squares.push(square);
    }

    render() {
        this.context.clearRect(0, 0, windowWidth, windowHeight);
            this.squares.forEach(square => {
                square.draw(this.context);
            });

    }
}

class Square {
    constructor(options) {
        this.options = options;
    }

    draw(ctx) {
        let x = this.options.x;
        let y = this.options.y;
        let width = this.options.width;
        let height = this.options.height;
        ctx.moveTo(x,y);
        ctx.rect(x, y, width, height);
        ctx.fillStyle = "rgba(255,255,255,.1)";
        ctx.fill();
    }
};

let squares = [];
let squareWidth = 200;
let squareHeight = 200;

let x = 0;
let y = 0;
for (let i = 0; i < windowWidth; i+=squareWidth) {
    x += squareWidth;
    let square = new Square({
        x, y: 0, width: squareWidth, height: squareHeight
    });
    console.log(square)
    squares.push(square);
}
console.log(squares.length);

let scene = new Scene();
squares.forEach(square => scene.addSquare(square));

scene.render();

1 个答案:

答案 0 :(得分:2)

您需要在每个矩形之前调用ctx.beginPath()。否则,对.rect()的调用只会添加到路径中,而fill()会填充整个内容。

draw(ctx) {
    let x = this.options.x;
    let y = this.options.y;
    let width = this.options.width;
    let height = this.options.height;
    ctx.beginPath(); // <========= this
    ctx.moveTo(x,y);
    ctx.rect(x, y, width, height);
    ctx.fillStyle = "rgba(255,255,255,.1)";
    ctx.fill();
}

您也可以考虑使用.fillRect()