奇怪的画布剪辑行为

时间:2016-07-10 23:29:17

标签: html5-canvas

我在这里要做的是在Canvas中绘制一个ListBox。我正在尝试使用clip()隐藏不在ListBox“视口”中的列表项。问题是除了最后一个列表项之外,所有不在ListBox“视口”中的列表项都被正确隐藏。我注意到如果我只调用requestAnimationFrame一次,那么最后一个列表项将被正确剪裁。或者,如果我在绘制列表项后调用beginPath,则会正确剪切最后一个列表项。

<canvas id="myCanvas" width="200" height="300" style="border:1px solid #000000;"></canvas> 

<script type="text/javascript">

    window.addEventListener("load", function () {
        var c = document.getElementById("myCanvas");
        var ctx = c.getContext("2d");

        var colors = ["green", "yellow", "blue", "red"];

        var gameLoopCallbackWrapper = function () {
            //Comment this line out to fix clipping anomaly
            window.requestAnimationFrame(gameLoopCallbackWrapper);

            if (ctx) { ctx.clearRect(0, 0, 200, 300); }

            ctx.save();

            ctx.transform(1, 0, 0, 1, 100, 100);

            //draw list box
            ctx.lineWidth = 1;
            ctx.strokeStyle = "white";
            ctx.rect(-26, -15, 52, 30);
            ctx.stroke();

            ctx.clip();

            //draw list items
            for (var key in colors) {
                var color = colors[key];

                ctx.save();

                ctx.transform(1, 0, 0, 1, 0, 14 * key - 8);

                ctx.fillStyle = color;

                ctx.strokeStyle = "black";

                ctx.beginPath();
                ctx.rect(-25, -7, 50, 14);
                ctx.stroke();
                ctx.fill();

                ctx.restore();

                //uncomment this line to see clipping anomally fixed
                //ctx.beginPath();
            }

            ctx.restore();
        };

        window.requestAnimationFrame(gameLoopCallbackWrapper);
    });
</script>

上面的代码是我的代码的简化版本,仅用于演示裁剪异常。它的当前形式不是交互式的,因此无法上下拖动列表项。

1 个答案:

答案 0 :(得分:0)

&#34;你必须在函数开始时调用beginPath,否则你的rect将只累积到最后绘制的路径(即使被clearRect清除)&#34; - 凯都

&#34;好的电话;谢谢你。我在开始绘制列表框之前放置了ctx.beginPath,现在正确剪裁了最后一个列表项。你能说我是Canvas的新手吗? ; - )&#34; - Meadock