我试图找到一种方法来执行与persona.co上类似的效果,但是在对各种搜索词进行大量搜索之后,我却找不到任何可能有用的方法。我可以看到很多关于在3d空间中转换图像或拉伸(stretch)图像以适合其需求的文章,而实际上并没有按照我的需要在数学上扭曲像素。
我最初曾研究过使用细分来拉开法师,但这只能平等地拉伸(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);