我试图找到一种方法来执行与persona.co上类似的效果,但是在对各种搜索词进行大量搜索之后,我却找不到任何可能有用的方法。我可以看到很多关于在3d空间中转换图像或拉伸(stretch)图像以适合其需求的文章,而实际上并没有按照我的需要在数学上扭曲像素。

javascript - 使用JavaScript和Canvas在单轴上扭曲图像-LMLPHP

我最初曾研究过使用细分来拉开法师,但这只能平等地拉伸(stretch)图像,除非我在轴上进行了数百次分割,然后这不允许我垂直镜像图像以获得相同的图像影响。

我目前的计划是逐个像素地遍历图像,并垂直增加它们的数量,然后反向取下,尽管这无疑会导致问题,而不会对相邻像素进行插值。

如果有人可以向我指出正确的方向,或者有什么想法可以帮助我入门,那就足够了。

最佳答案

容易造成失真的是,您对自己想要的东西不太挑剔。

通过一次将图像绘制成一条线,并更改从图像获得图像的位置,可以使其延伸到所需的任何位置。您绘制的每条线也可以水平搜索以添加其他效果

以下内容将六次正弦波应用于图像。一次绘制一张图像。数学只是随机的,因此可以进行任意效果。

您也可以使用webGL,它将为您提供更大的功能。看到这个答案https://stackoverflow.com/a/38966946/3877726

演示。在功能显示屏中,所有要进行变形的内容都在其中。 for循环从0到1循环,所有wave都尝试将值保持在0到1之间。只有当我从图像中获得线并将其放在 Canvas 上时,我才通过简单地乘以将单位值转换回像素坐标。

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);

09-20 02:10