2016-08-25 63 views
2

我試圖找到一個wa來做類似的效果o在persona.co上找到類似的搜索術語之後,我找不到任何可能有用的東西。我可以看到很多關於在3D空間中變換圖像,或者拉伸圖像以適應圖像的帖子,而不是實際上像我需要的那樣在數學上扭曲像素。使用JavaScript和Canvas在單個軸上歪曲圖像

enter image description here

我原本看着用細分拉開法師,但這隻適用於同樣拉伸圖像,除非我的軸線上作過成百上千部門,然後這不會讓我可能會垂直鏡像以獲得相同的效果。

我目前的計劃是逐像素地運行圖像,並以增加的量垂直複製它們,並在相反的位置去除,但這無疑會導致問題而不插入相鄰像素。

如果任何人都可以指引我正確的方向或有任何想法來幫助我開始就足夠了。

回答

2

很容易做到的distorsions是你是不是太挑剔什麼是你想要的。

通過一次畫出圖像一行,並改變圖像的位置,您可以使圖像在任意位置伸展。您繪製的每條線也可以進行水平搜索以添加額外的FX

下面的圖像會應用半打的正弦波。一次繪製圖像一行。數學只是隨機的,所以任何FX都可以製作。

你也可以去webGL,它會給你更大的力量。看到這個答案https://stackoverflow.com/a/38966946/3877726

演示。所有做扭曲的東西都在功能顯示中。 for循環從0到1循環,並且所有波形都嘗試將值保持在0和1之間。只有當我從圖像中獲取線並將其放在畫布上時,我纔可以將單位值轉換回像素座標,只需乘以。

var image = new Image(); 
 
image.src = "http://i.stack.imgur.com/jNAXA.jpg"; 
 
var iw,ih; 
 

 
var easeInOut = function (x, pow) { 
 
    x = x < 0 ? 0 : x > 1 ? 1 : x; // clamp x 
 
\t var xx = Math.pow(x,pow); 
 
\t return xx/(xx + Math.pow(1 - x, pow)); 
 
} 
 
function display(){ // put code in here 
 
    ctx.setTransform(1,0,0,1,0,0); // reset transform 
 
    ctx.globalAlpha = 1;   // reset alpha 
 
    ctx.clearRect(0,0,w,h); 
 
    if(image.complete){ 
 
     if(ih === undefined){ 
 
      ih = image.height; 
 
      iw = image.width; 
 
     } 
 
     var step = 1/ canvas.height;; 
 
     var istep = ih/canvas.height; 
 
     var rstep = 0; 
 
     var y = 0; 
 
     var yh = 0; 
 
     var cH = canvas.height; 
 
     var cH = canvas.height; 
 
     var curve = Math.sin(globalTime /1020) + 1.2; 
 
     var curve2 = Math.sin(globalTime /2217) + 1.4; 
 
     var curve3 = Math.sin(globalTime /533) * Math.PI; 
 
     var curve4 = (Math.sin(globalTime /731) + 1.1) * Math.PI; 
 
     var wave = 4/(Math.PI * 1); 
 
     var wave1 = curve4/(Math.PI * 1); 
 
     for(var i = 0 ;i < 1; i += step){ 
 
      var wob = Math.sin(i * wave); 
 
      var wide = (Math.sin(i * wave1 * 3+curve3) + 1.0)*100; 
 
      y = easeInOut(easeInOut(wob,curve),curve2); 
 
      yh =easeInOut(easeInOut(wob+step,curve),curve2) - y; 
 
      y *= ih; 
 
      yh *= ih; 
 
      ctx.drawImage(image, wide, y, iw-wide*2, yh, 0, i*cH, canvas.width, step*cH); 
 
     } 
 
    
 
    } 
 
} 
 

 

 

 

 
function update(timer){ // Main update loop 
 
    globalTime = timer; 
 
    display(); // call demo code 
 
    requestAnimationFrame(update); 
 
} 
 

 

 

 

 

 
const RESIZE_DEBOUNCE_TIME = 100; 
 
var w,h,cw,ch,canvas,ctx,createCanvas,resizeCanvas,setGlobals,globalTime=0,resizeCount = 0; 
 
createCanvas = function() { 
 
    var c,cs; cs = (c = document.createElement("canvas")).style; 
 
    cs.position = "absolute"; 
 
    cs.top = cs.left = "0px"; 
 
    cs.zIndex = 1000; 
 
    document.body.appendChild(c); 
 
    return c; 
 
    
 
} 
 
resizeCanvas = function() { 
 
    if (canvas === undefined) { 
 
     canvas = createCanvas(); 
 
     
 
    } 
 
    canvas.width = window.innerWidth; 
 
    canvas.height = window.innerHeight; 
 
    ctx = canvas.getContext("2d"); 
 
    if (typeof setGlobals === "function") { setGlobals(); } 
 
    if (typeof onResize === "function"){ 
 
     resizeCount += 1; 
 
     setTimeout(debounceResize,RESIZE_DEBOUNCE_TIME); 
 
     
 
    } 
 
} 
 
function debounceResize(){ 
 
    resizeCount -= 1; 
 
    if(resizeCount <= 0){ onResize();} 
 
} 
 
setGlobals = function(){ 
 
    cw = (w = canvas.width)/2; 
 
    ch = (h = canvas.height)/2; 
 
} 
 

 
resizeCanvas(); 
 
window.addEventListener("resize",resizeCanvas); 
 
requestAnimationFrame(update);

1

使用畫布context.scale

// stretches the image 2x vertically 
ctx.scale(1,2); 

您可以輕鬆地垂直拉伸的圖像,並可以垂直翻轉圖像做了「底」部分圖片:

// flips the image vertically 
context.scale(1,-1); 

例子:

enter image description here

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

 
var img=new Image(); 
 
img.onload=start; 
 
img.src="https://dl.dropboxusercontent.com/u/139992952/face.jpg"; 
 
function start(){ 
 
    ctx.drawImage(img,0,0); 
 
    ctx.translate(img.width*1.25,0); 
 
    // optionally, shrink the img by half so it fits in a reasonable size 
 
    ctx.scale(0.50,0.50); 
 
    ctx.scale(1,2); 
 
    ctx.drawImage(img,0,0); 
 
    ctx.scale(1,-1); 
 
    ctx.drawImage(img,0,-img.height*2); 
 
}
body{ background-color:white; } 
 
#canvas{border:1px solid red; }
<canvas id="canvas" width=400 height=480></canvas>