0

キャンバスを使用してスライド ショーを作成しました。クリップを使用して、その中の画像の端を丸めています。クリップはフェードアウトしないため、clip() を呼び出す前にクリップ パスをストロークして外側のエッジを滑らかにし、画像を描画した後にもう一度ストロークして内側のエッジを滑らかにします。これは Chrome では問題なく動作しましたが、Safari または Internet Explorer でテストすると、ここに示す問題が発生しました。左の画像がクローム、右の画像がサファリです。線と画像の端の間のギャップに注目してください。

私がストロークしたパスはクリップ パスとまったく同じパスであり、lineWidth は 5 ですが、サファリがクリップの境界でピクセルを埋めていないように見えます。アウトラインでオーバーレイ画像を作成せずにこれを修正する方法はありますか?

編集 2:restore() でクリップを削除し、アウトラインを描画し、再クリップしてみました。これは Internet Explorer で機能し、サファリでも機能しますが、サファリでは、この方法を使用すると、ストロークが画像データとブレンドするのではなく、画像データを上書きします。

var canvas;
var ctx;

function loadSlideshow() {
    canvas = document.getElementById("slideshow"); //Width=960, Height=540
    ctx = canvas.getContext("2d");

    ctx.strokeStyle="#0d0d0d";
    ctx.beginPath();
    ctx.moveTo(0, 54);
    ctx.quadraticCurveTo(480, -27, 960, 54);
    ctx.lineTo(960, 540 - 54);
    ctx.quadraticCurveTo(480, 540 + 27, 0, 540 - 54);
    ctx.closePath();
    ctx.stroke(); //Stroke clip path before clipping to outer clip transition
    ctx.save();
    ctx.clip(); //Set clip to make images curved at the top and bottom
    ctx.lineWidth = 5;
    var imagesToLoad = [
        "images/slideshow/img1.png",
        "images/slideshow/img2.png",
        "images/slideshow/img3.png",
        "images/slideshow/img4.png",
    ]
    for(var i = 0; i < imagesToLoad.length; i++) {
        var img = new Image();
        img.src = imagesToLoad[i];
        images.push(img);
    }
    images[0].onload = function() {
        requestAnimFrame(animate);
    }
}

var images = [];
var curImage = -1;
var lastImageSwitch = 0;

function animate() {
    requestAnimFrame(animate);
    var time = new Date().getTime();

    //Switch to next slide after 5 seconds
    if(time - lastImageSwitch >= 5000) {
        curImage++;
        curImage%=images.length;
        ctx.drawImage(images[curImage], 0, 0, canvas.width, canvas.height);
        ctx.stroke(); //Stroke outline to smooth the clipping.
        lastImageSwitch = time;
    //Animated transition between slides
    } else if(time - lastImageSwitch >= 4500) {
        //Calculate alpha of next image in slideshow based on time until next image
        var alpha = 1 - ((5000 - time + lastImageSwitch) / 500);

        //Draw current image, then overlay next image with semi-transparency
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(images[curImage], 0, 0, canvas.width, canvas.height);
        ctx.globalAlpha = alpha;
        ctx.drawImage(images[(curImage + 1) % images.length], 0, 0, canvas.width, canvas.height);
        ctx.globalAlpha = 1;
        ctx.stroke(); //Stroke outline to smooth the clipping.
    }
}

window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

EDIT:私が忘れていたコードを添付しました
EDIT 2:さらに調査した後、投稿を修正しました

4

0 に答える 0