动画与帆布的剪报面具

时间:2015-10-28 06:04:00

标签: javascript html html5-canvas

enter image description here

请参阅附图。你可以看到第一张带有画布遮罩的幻灯片,就像第二张幻灯片一样动画。

1 个答案:

答案 0 :(得分:2)

嗯,我不知道你想要什么语言,所以Javascript就是这样,但无论你使用什么SDK或语言,原则都是一样的。

容易做到。使用requestAnimationFrame使其流畅。创建一组可以对其进行动画处理的形状,并使用moveTo,lineTo或您想要的任何路径函数将它们正常绘制到画布上下文中。而不是调用填充或描边调用ctx.clip()然后绘制图像,它将只显示在剪切区域。

下面是一个相当简单的示例,但它会为您提供基础知识,您可以根据自己的需要进行改进。



var canvas = document.getElementById("canV");  // get the canvas
var ctx = canvas.getContext("2d");  // get the context
var blobs = [];  // array to hold blobs
var width = canvas.width;
var height = canvas.height;
var blobPCount = 16;  // how bumpy the blobs are
var wobbla = 0;  // adds a bit of a wobble
var growSpeed = 2;  // grow speed 0.1 very slow 10 mega fast
var cludgeFactor = 0.25;  // used to work out when its all done
var cludgeFactorA = 1-cludgeFactor;  // its a bit of a cludge hence the name
// a wiki commons image
var imageURL = "https://upload.wikimedia.org/wikipedia/commons/e/ee/Baby_Cuttlefish2_%285589806913%29.jpg";
var image = new Image(); // create the image
image.src = imageURL; // load it
var done = false;   // flag is true when done


function addBlob(){  // adds a blob
    var b = {};
    b.x = Math.random()*width;   // find a random pos for it
    b.y = Math.random()*height;
    b.points = [];        // create a set of pointy in a circle that will grow outward
    for(var i = 0; i < Math.PI*2;i+= (Math.PI*2)/blobPCount){
        var p = {};
        // mess up the perfection a little
        var dir= (i+((Math.PI*2)/(blobPCount*3))*(Math.random()-0.5))*(1+2/blobPCount);
        p.dx = Math.cos(dir);  // the delta x and y
        p.dy = Math.sin(dir);
        p.x = p.dx * 5;     // the starting size
        p.y = p.dy * 5;
        p.dx *= growSpeed;   // set the speed
        p.dy *= growSpeed;
        b.points.push(p);   // add the point

    }
    blobs.push(b);  // and the blob
}

function growBlobs(){  // grows the blob
    var i;
    for(i = 0; i < blobs.length; i++){  // for each blob
        var b = blobs[i];
        var pc = b.points.length;
        for(var j = 0; j < pc; j++){  // grow the points
            var p = b.points[j];
            p.x += p.dx+p.dx*Math.random()*0.2;  // move the point with a liitle random
            p.y += p.dy+p.dy*Math.random()*0.2;
        }
    }
}

// creates the clipping mask
function createClipMask(){
    var i;
    ctx.beginPath();  // begin a path
    wobbla += 0.2;    // add some wobbla
    var inside = false;  // the flag to test done
 
    for(i = 0; i < blobs.length; i++){  // for each blob
        var b = blobs[i];
        var pc = b.points.length;       // get len
        for(var j = 0; j < pc-1; j++){  // do eacj point
            var p = b.points[j];
            var x = b.x+p.x + Math.sin(wobbla+i+j*0.2)*10; // get a point
            var y = b.y+p.y + Math.cos(wobbla+i+j*0.2)*10;
            if(j === 0){
                ctx.moveTo(x,y); // move to the first point
            }else{
                j ++;  // all other points as a second order bexier
                p = b.points[j];
                var x1 = b.x +p.x*0.75 + Math.sin(wobbla+i+j*0.2)*10; // add the wobble
                var y1 = b.y +p.y*0.75 + Math.cos(wobbla+i+j*0.2)*10;
                ctx.quadraticCurveTo(x,y,x1,y1);  // create tke bezier path
                // test if the points are inside the screen by cludge factor
                if(!inside && x > width*cludgeFactor && x < width*cludgeFactorA &&
                    y > height*cludgeFactor && y < height*cludgeFactorA){
                    inside = true;  

                }
                
            }
        }
        ctx.closePath();  // done with this blob close the path
    }
    // all blobs done so set the clip
    ctx.clip();
    if(!inside){  // if no points inside the cludge area the we are done
        done = true;
    }
   
}

// make a semi random number of blobs
var numberBlobs = Math.ceil(Math.random()^5) +3;
for(var i = 0; i < numberBlobs; i++){
    addBlob();
}
// do the update
function update(){
    if(done){  // if done draw the image
        ctx.drawImage(image,0,0,width,height);
        return;  // return stops the rendering
    }
    ctx.fillStyle = "white";   // draw the white
    ctx.fillRect(0,0,width,height);
    ctx.save();  // save the current ctx state
    if(image.complete){  // has the image loaded
        growBlobs();    // yes so grow blobs
        createClipMask();  // create the clip
        ctx.drawImage(image,0,0,width,height); //draw the clipped image
    }
    ctx.restore();  // dont need the clip anymore so restore the ctx state
    window.requestAnimationFrame (update); //request a new anim frame

}
update();  // start it all going
&#13;
.canC {
  width:500px;
  height:400px;
}
&#13;
<canvas class="canC" id="canV" width=500 height=400></canvas>
&#13;
&#13;
&#13;

此外,我不得不猜测你想要什么,所以希望我猜对了。有任何问题请问。