原生js通过canvas和cssRules实现图片分割与重组

  将一张照片分割成几段然后重新组合,按照常理来讲使用h5的canvas标签很容易就实现了,长话短说,直入正题:

 html :

  首先创建一个img标签:

  <img id="img" style="width: 100px;height: 100px" src="img/3.jpg" />

  创建一个按钮,目的是做将图片剪切操作:

  <input type="button" value="剪切" onclick="clickCropImage()"/>

   然后创建一个画布,目的是获取到我们之前创建的img标签上的图片,并将该图片进行分割操作(如果不想让该画布展示出来可以添加 display:none):

   <canvas id="imageC" width="200" height="200" ></canvas>

  js :

  html我们创建好之后,然后做将图片平铺到画布上的操作:

            var canvas = document.getElementById('imageC');
            var ctx = canvas.getContext('2d');
            var img = document.getElementById('img');        
            ctx.drawImage(img, 0, 0, 200, 200);

然后我们需要确认分割成多少个,假设说我们划分36个,那么也就是6行6列:

          var numberX = numberY = 6;

然后我们去实现以下创建的input:type = button的clickCropImage()方法:

function clickCropImage() {
            var canvas = document.getElementById('imageC');
            //  获取画布大小,判断画布大小
            var canvasH = canvas.clientHeight;
            var canvasW = canvas.clientWidth;
            //  将图片等分
            for (var x = 0; x < numberX; x++) {
                for (var y = 0; y < numberY; y++) {
                    var location = {
                        'x' : x * canvasW / numberX -splaceX,
                        'y' : y * canvasH / numberY -splaceY,
                        'Dx' : x * canvasW / numberX + canvasW / numberX,
                        'Dy' : y * canvasH / numberY + canvasH / numberY,
                        'locationOption' : (x + 1).toString() + (y + 1).toString(),
                    };
                    locationArr.push(location);
                    cropImage(canvas, (x * canvasW / numberX) -splaceX, (y * canvasH / numberY)-splaceY, canvasW / numberX, canvasH / numberY);
                };
            };
            canvasComimgCreated = false;
            divComimgCreated = false;
        }

//    重头戏: 实现剪切图片方法:(其中getImageData浏览器解析千差万别,具体我们也没弄懂这个方法实现方法,抱歉)

      function cropImage(targetCanvas, x, y, width, height) {
            var targetctx = targetCanvas.getContext('2d');
            var targetctxImageData = targetctx.getImageData(x, y, width, height);
            // sx, sy, sWidth, sHeight
            var c = document.createElement('canvas');
            var ctx = c.getContext('2d');
            c.width = width;
            c.height = height;
            ctx.rect(0, 0, width, height);
            ctx.fillStyle = 'white';
            ctx.fill();
            ctx.putImageData(targetctxImageData, 0, 0);
            // imageData, dx, dy
            // 创建img 块
            var img = document.createElement('img');
            img.src = c.toDataURL('image/jpeg', 0.92);
             document.body.appendChild(img);
        }

走到这,你会发现图片已经剪切好了:


但是排列并不是我们需要的,因为我们还需要对这个图片进行组合一下,实现以下组合方法:

        function combinationImg(img, x, y, width, height) {
            if (canvasComimgCreated == false) {
                if ( typeof (canvasComimgCtx) != 'undefined') {
                    canvasComimgCtx.clearRect(0, 0, width * numberX, height * numberY);
                    document.body.removeChild(canvasComimg);
                }
                canvasComimg = document.createElement('canvas');
                canvasComimgCtx = canvasComimg.getContext('2d');
                canvasComimg.width = width * numberX;
                canvasComimg.height = height * numberY;
                canvasComimgCtx.rect(0, 0, width * numberX, height * numberY);
                canvasComimgCtx.fillStyle = 'red';
                canvasComimgCtx.fill();
                document.body.appendChild(canvasComimg);
                canvasComimgCreated = true;
            };
            imgArr.push(img);
            canvasComimgCtx.drawImage(img, x, y);
        }

    然后我们在运行以下看看:

   


看,舒服多了,我们还可以为每一个图片对象添加点击时间:

var canvasOffseTop = canvasComimg.offsetTop;
                var canvasOffsetLeft = canvasComimg.offsetLeft;
                canvasComimg.addEventListener("mouseup", function(Event) {
                    var x = Event.clientX - canvasOffsetLeft;
                    var y = Event.clientY - canvasOffseTop;
                    var locationOption = Math.ceil(x / width).toString() + Math.ceil(y / height).toString();
                    for (var i in locationArr) {
                        if (locationArr[i].locationOption == locationOption) {
                            canvasComimgCtx.strokeStyle = 'blue';
                            canvasComimgCtx.moveTo(locationArr[i].x, locationArr[i].y);
                            canvasComimgCtx.strokeRect(locationArr[i].x, locationArr[i].y, width, height);
                        }
                    }
                }, false);

然后我们再看:

    

到这,图片分割组合基本完成了,但是这是用画布canvas实现的,图片使用canvas的drawImage实现的,组合渲染过程我们不好去控制,这怎么办呢? 那我们就舍弃drawImage,渲染我们可以用创建一个div,让img标签逐个排列的方式进行组合,但是组合好组合,添加动画是不是有点麻烦了。动画? css3动画功能那么强大为什么不去试试呢,本着尝试一下的念头,我们先实现一个简单的图片下落的动画:(使用css3 keyframes 规则进行操作)

 

@keyframes mymove
{
from {top:0px;}
to {top:200px;}
}

@-moz-keyframes mymove /* Firefox */
{
from {top:0px;}
to {top:200px;}
}

@-webkit-keyframes mymove /* Safari 和 Chrome */
{
from {top:0px;}
to {top:200px;}
}

@-o-keyframes mymove /* Opera */
{
from {top:0px;}
to {top:200px;}
}
发现这么写确实有搞头,但是我们怎么样去用js更改keyframe的规则呢?很简单,通过cssRuler非常简单的就实现了:

首先我们得明白使用cssRule操作步骤:我们先获取到需要修改的那条规则或者我们创建一条新的规则,让需要组合的img遵循这个规则不就可以了,想好了我们就去实现:

cssRule有四个方法我们可以用的到:addRul(index),deleteRule(index)和findRule(index),insertRule(keyframe,index);这四个方法有一个共同特点,需要传入一个index,这个index为样式规则所在位置,但是我们怎么知道规则何在呢?

通过这四个方法我们可以做添加,删除,寻找,插入操作:

这四个方法都是操作的CSSKeyframesRule对象,我们先看一下这个对象从哪来:我们先通过document.styleSheets查看下文档样式表:

       var ocss = document.styleSheets[1];

      conlose.log(ocss);

     

发现cssRules关键字,点看看一下:


这不就是我们需要的对象吗?而且每一个规则前面的数字就是我们之前提到的index的值,但是怎么操作呢,很简单,以deleteRule为例,直接ocss.deleteRule(3)就好了;

  找到了对象在哪就好办了,那我们就用插入规则的方式实现我们的动画组合效果:

ocss.insertRule("@-webkit-keyframes mymove" + DisXY + " { 0% { margin-top: 200px;margin-left:80px } 50% {margin-top: 0px;margin-left:80px} 100% { margin-top: " + y + "px;margin-left:" + x + "px }}", 2);

插入一个样式规则,然后让img遵循这条规则;

var keyFrameName = 'mymove' + DisXY;

_img.style.webkitAnimation = keyFrameName + ' ' + speed + 's infinite';

看效果:


效果还行,把所有的照片都放上看一下:


完成了,这样一个简单的图片剪切组合效果实现了,使用cssRules完成组合代码:

var divComimgCreated = false, divComimgCtx, divComimg = '';
        //  div 拼接图片
        function combinationImg1(img, x, y, width, height) {
            if (divComimgCreated == false) {
                if ( typeof (divComimg) == 'undefined' || divComimg == '') {
                    divComimg = document.createElement('div');
                    divComimg.style.backgroundColor = "#F00";
                    var divW = width * numberX, divH = height * numberY;
                    divComimg.style.width = divW + 'px';
                    divComimg.style.height = divH + 'px';
                    document.body.append(divComimg);
                    divComimgCreated = true;
                } else {
                    while (divComimg.hasChildNodes())//当div下还存在子节点时 循环继续
                    {
                        divComimg.removeChild(divComimg.firstChild);
                    }
                    divComimgCreated = true;
                }
            }
            var _img = img;
            _img.style.width = width;
            _img.style.height = height;
            _img.style.position = 'absolute';
            _img.id = 'demoImg';
            var DisXY = Math.ceil(x / width).toString() + Math.ceil(y / height).toString();
            var ocss = document.styleSheets[1];
            ocss.insertRule("@-webkit-keyframes mymove" + DisXY + " { 0% { margin-top: 200px;margin-left:80px } 50% {margin-top: 0px;margin-left:80px} 100% { margin-top: " + y + "px;margin-left:" + x + "px }}", 2);
            var speed = Math.random() > 0.5 ? Math.random() * 5 : (Math.random() + 0.4) * 5;
            var keyFrameName = 'mymove' + DisXY;
            _img.style.webkitAnimation = keyFrameName + ' ' + speed + 's infinite';
            _img.style.webkitAnimationIterationCount = 1;
            _img.style.webkitAnimationFillMode = 'forwards';
            divComimg.append(img);
        }

如果想看代码可以q:1192366134我,但是只是一个小demo,写的需要不好的地方还请各位大神多多指点一下。









   







 




  
 

猜你喜欢

转载自blog.csdn.net/ikceo1211/article/details/79034861