原生js通過canvas和cssRules實現圖片分割與重組

  將一張照片分割成幾段然後重新組合,按照常理來講使用h5的canvas標籤很容易就實現了,長話短說,直入正題:

 html :

  首先創建一個img標籤:

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

  創建一個按鈕,目的是做將圖片剪切操作:

  <input type="button" value="剪切" οnclick="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,寫的需要不好的地方還請各位大神多多指點一下。









   







 




  
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章