使用JavaScript和Canvas在单个轴上扭曲图像

时间:2016-08-25 16:32:01

标签: javascript css image canvas

我试图找到一个类似于persona.co上发现的效果。然而,在搜索各种搜索词之后,我找不到任何可能有用的东西。我可以看到很多关于在3d空间中转换图像或者拉伸图像以适应的帖子,而不是像我需要的那样以数学方式实际扭曲像素。

enter image description here

我最初考虑使用细分来拉开法师,但这只能平等地拉伸图像,除非我在轴上做了数百个分割,然后这不允许我可能垂直镜像图像以获得相同的效果。

我目前计划逐个像素地运行图像并以递增的量垂直复制它们并在反转上移除虽然这无疑会导致问题而不插入相邻的像素。

如果有人能指出我正确的方向,或有任何想法可以帮助我开始,那就足够了。

3 个答案:

答案 0 :(得分:2)

我认为他们正在使用PixiJS:

http://www.pixijs.com

答案 1 :(得分:2)

容易做出扭曲是你对你想要的东西不太挑剔。

通过一次绘制一行图像并从图像中更改位置,您可以将其拉伸到任何您想要的位置。您绘制的每一行也可以水平搜索以添加额外的FX

以下将六个正弦波应用于图像。一次绘制一行图像。数学是随机的,所以任何FX都可以制作。

你也可以去webGL,它将为你提供更大的力量。请参阅此回答https://stackoverflow.com/a/38966946/3877726

演示。所有做扭曲的东西都在功能显示中。 for循环从0循环到1并且所有wave都尝试将值保持在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
	var xx = Math.pow(x,pow);
	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);
&#13;
&#13;
&#13;

答案 2 :(得分:1)

您可以使用画布context.scale

轻松地垂直拉伸图像
// stretches the image 2x vertically
ctx.scale(1,2);

您可以垂直翻转图像以执行&#34;底部&#34;你的形象的一部分:

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

示例:

enter image description here

&#13;
&#13;
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);
}
&#13;
body{ background-color:white; }
#canvas{border:1px solid red; }
&#13;
<canvas id="canvas" width=400 height=480></canvas>
&#13;
&#13;
&#13;