之前在逛cssdesignawards时发现了一个把图片内容分割的效果(网址:https://weareludwig.com),大家可以点进去看看,感觉挺炫酷的,于是自己试着实现了一下,效果还不错。效果查看https://codepen.io/geeknoble/pen/OQaOVG
分析
首先我们可以发现图片的内容被分成了一个个小矩形,并对每个矩形进行了随机平移。Canvas的drawImage函数可以对图片内容进行裁剪并绘制到Canvas画布中,所以该效果主要实现原理就是使用drawImage。主要效果有两个,一个是图片内容的打乱和复原,一个是和下张图片的切换,这两个效果都可以使用drawImage,只是移动的距离不一样。总体思路有了那么就可以去着手实现一下。
初始工作
首先我们要初始化一些变量,比如图片的宽高,矩形的个数,剪切的尺寸等,然后再计算每个矩形的坐标,使用一个二重循环将矩形坐标保存在data中。每个矩形有个随机位移,这个位移也需要保存起来,存在randoms中。其中x,y表示canvas画布的坐标,x1,y1表示图片裁剪的坐标。
init: function (context, width, height, area, img) {
this.context = context;
this.img = img;
this.imgWidth = img[0].width; //图片宽高
this.imgHeight = img[0].height;
this.index = 0; //当前图片序号
this.width = width; //画布宽高
this.height = height;
this.area = height/12; //小矩形长度
this.countX = width / this.area; //水平和垂直方向小矩形个数
this.countY = height / this.area;
this.wx = this.imgWidth / this.countX; //图片在小矩形中的宽高
this.wy = this.imgHeight / this.countY;
this.state = true; //图片状态,true表示未拆分
this.dataFlag = true; //小矩形坐标状态,true表示未加上随机值
this.duration = 1000; //动画时间
this.duration2 = 1500;
this.startTime = 0;
this.data = []; //小矩形坐标信息
this.randoms = []; //位置随机值
//初始化矩形坐标
var x1 = 0, y1 = 0, x = 0, y = 0;
for (var i = 0; i < this.countY; i++) {
for (var j = 0; j < this.countX; j++) {
context.drawImage(this.img[this.index], x1, y1, this.wx, this.wy, x, y, this.area, this.area);
//储存矩形坐标
this.data.push({
x1: x1,
y1: y1,
x: x,
y: y
});
//添加随机值
this.randoms.push(random(-this.area, this.area));
x1 += this.wx;
x += this.area; }
x1 = 0;
y1 += this.wy;
x = 0;
y += this.area;
}
this.checkMargin();
}
检测边缘
在给矩形添加位移之前我们需要判断一下位移后的坐标是否超过图片界限,比如在顶部的矩形如果是y轴移动,那么只能够向上移,判断的条件为当前坐标加上位移值是否小于0或大于图片的宽高。如果更新后的坐标小于0,那么这个随机值一定是负数,需要把随机值改为正数,如果大于图片高度,那么改成负数即可。由于每个矩形的移动都是在一个方向上移动,所以我这里写成偶数位移动x轴,奇数位移动y轴。









