2015-03-02 16 views
1

說我有一個矩形的畫布。我想拿走那塊帆布並對角分割,並且能夠操縱這些碎片來做我想做的任何事情。如何將畫布對角地或非方形地分割

我的最終目標是對角地分割一個矩形,並將兩部分以相反的方向在屏幕外移動。我正在考慮在動畫循環中完全在畫布中完成此操作,或者將每個片段轉換爲圖像元素並使用CSS3動畫來移動這些片段。我只是想找出最好的方法來做到這一點。

下面的代碼,codepen鏈接和圖像只是爲了說明我希望我的畫布被拆分的位置。你會發現它不是一個完全相同的分裂。

http://codepen.io/FranciscoG/pen/YPjzbQ

<div id="container"> 
    <img id="dog" src="http://i.imgur.com/1GUzYh9.jpg" width="375" 
    height="667"> 
</div> 

<script> 
var container = document.getElementById('container'); 
var dogImg = document.getElementById('dog'); 

function convertImageToCanvas(image) { 
    var canvas = document.createElement("canvas"); 
    canvas.width = image.width; 
    canvas.height = image.height; 
    canvas.getContext("2d").drawImage(image, 0, 0); 
    return canvas; 
} 

function drawLine(canvas) { 
    var context = canvas.getContext('2d'); 
    context.beginPath(); 
    context.moveTo(0,0); 
    context.lineTo(345, 0); 
    context.lineTo(0, 567); 
    context.lineTo(0,0); 
    context.stroke(); 
    context.closePath(); 
    return canvas; 
}; 

var newDog = convertImageToCanvas(dogImg); 
var divided = drawLine(newDog); 
container.innerHTML = ""; 
container.appendChild(divided) 
</script> 

enter image description here

回答

3

你總是可以使用裁剪,但請注意,這將涉及到保存/恢復呼叫這是一個相對緩慢的業務。有人建議在規格中包含resetClip(),但它似乎很難將消息傳遞給組爲什麼需要

在任何情況下,我建議如下方法:

  • 創建的對象或功能,可以再現圖像的半側的一個(即一個單一的掩模(路徑)的對角線與包含框的行)。
  • 對於左半:繪製圖像,設定複合模式destination-in,繪製掩模,提取帆布作爲圖像
  • 對於右半:繪製圖像,設定複合模式destination-out,繪製掩模,提取帆布作爲圖像

現在把圖像放在一個容器內(直接使用畫布元素),使它們堆疊在一起。

使用過渡或動畫類進行動畫製作。

var img = new Image(375, 667); 
 
img.onload = setup; 
 
img.src = "http://i.imgur.com/1GUzYh9.jpg"; 
 

 
function setup() { 
 

 
    var path = [0,0, 345,0, 0, 567]; // last point not needed.. 
 
    var left = createCanvas(this, path, "destination-in"); 
 
    var right = createCanvas(this, path, "destination-out"); 
 
    var cont = document.getElementById("cont"); 
 
    
 
    cont.appendChild(left); 
 
    cont.appendChild(right); 
 
    
 
    // animate here by setting animation/transition class or using JS: 
 
    var x = 0; 
 
    (function loop() { 
 
    left.style.left = x + "px"; // translate is smoother, but need 
 
    right.style.left = -x + "px"; // prefix in some browser. Update as needed.. 
 
    x-=5; if (x < -400) x = 0; 
 
    requestAnimationFrame(loop); 
 
    })(); 
 
    
 
    function createCanvas(img, path, mode) { 
 
    var canvas = document.createElement("canvas"), 
 
     ctx = canvas.getContext("2d"); 
 
    canvas.width = img.width; 
 
    canvas.height = img.height; 
 
    
 
    // draw image 
 
    ctx.drawImage(img, 0, 0); 
 
    
 
    // create mask 
 
    ctx.moveTo(path[0], path[1]); 
 
    for(var i = 2; i < path.length; i += 2) ctx.lineTo(path[i], path[i+1]); 
 
    ctx.closePath(); 
 
    
 
    // composite mode and create half 
 
    ctx.globalCompositeOperation = mode; 
 
    ctx.fill(); 
 
    
 
    return canvas 
 
    } 
 
}
#cont { 
 
    position:relative;width:375px;height:667px;overflow:hidden; 
 
    } 
 
#cont>canvas {position:absolute;left:0;right:0;}
<div id="cont"></div>

+0

給予好評。是的...我更喜歡你的想法。它更簡單快捷。我的大腦偶爾會關注一種方法(裁剪)並忽略另一種更簡單的方法(圖像畫布)。我的頭腦有時會很煩人! :-o – markE 2015-03-03 03:06:06

+1

@markE剪輯是一種好方法,但我們需要從未使用過的resetClip。是的,頭腦是棘手的朋友。有一次,我只是讓我的思緒徘徊,而它從未迴歸。 :-P – K3N 2015-03-03 07:42:19

+0

這是完美的!謝謝你的幫助 – Francisc0 2015-03-03 12:57:49

1

您可以使用context.clip到achieive圖像分割效果

context.clip限制對正在繪製withing指定路徑的圖像。

您可以定義幾個這些剪切區域來將您的圖像分成幾個部分(路徑)。

然後在動畫循環中,您可以清除畫布並使用不斷變化的偏移重新繪製每個裁剪區域。左剪輯區域將在每個循環中向左移動(偏移)。右剪輯區域將在每個循環中向右移動(偏移)。

這裏的示例代碼和演示:

var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 
var cw=canvas.width; 
 
var ch=canvas.height; 
 

 

 
var nextTime=0; 
 
var duration=1000/60*3; 
 

 
var offset=0; 
 
var paths=[]; 
 

 
var img=new Image(); 
 
img.onload=start; 
 
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/Dog-With-Cute-Cat.jpg"; 
 
function start(){ 
 
    cw=canvas.width=img.width; 
 
    ch=canvas.height=img.height; 
 

 
    paths.push({path:[{x:0,y:0},{x:150,y:0},{x:0,y:ch}],direction:-1}); 
 
    paths.push({path:[{x:150,y:0},{x:0,y:ch},{x:cw,y:ch},{x:cw,y:0}],direction:1}); 
 

 
    requestAnimationFrame(animate); 
 
} 
 

 
function draw(){ 
 
    ctx.clearRect(0,0,cw,ch); 
 
    for(var i=0;i<paths.length;i++){ 
 
    var path=paths[i].path; 
 
    var offX=offset*paths[i].direction; 
 
    ctx.save(); 
 
    ctx.beginPath(); 
 
    var pt=path[0]; 
 
    ctx.moveTo(pt.x+offX,pt.y); 
 
    for(var j=1;j<path.length;j++){ 
 
     var pt=path[j]; 
 
     ctx.lineTo(pt.x+offX,pt.y); 
 
    } 
 
    ctx.closePath(); 
 
    ctx.stroke(); 
 
    ctx.clip(); 
 
    ctx.drawImage(img,offX,0); 
 
    ctx.restore(); 
 
    } 
 
} 
 

 
function animate(time){ 
 
    if(offset<cw){requestAnimationFrame(animate);}else{log('done');} 
 
    if(time<nextTime){return;} 
 
    nextTime=time+duration; 
 
    draw(); 
 
    offset++; 
 
}
body{ background-color: ivory; padding:10px; } 
 
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>

相關問題