1)您提到了两种非常不同的算法:位移映射是一种 3D 技术,因此它涉及“Z”和投影,另一种是更简单的 2D 像素移位算法。
(提供的音步链接使用“位移映射”一词,但它是一种像素移动技术。)
2)无论您的 MVC 项目的大小,算法都应该是隔离的,并且具有如下签名:
var pixelShift = function (sourceCanvas, shiftCanvas, xOffset, yOffset)
并返回一个新的画布或更改 sourceCanvas 到位。
如果没有这个功能,请不要谈论MVC,除非M代表'Mess'。;-) -
3) 实际上,该算法非常简单,您必须遍历目标像素并查看它们应该来自的像素的颜色(而不是相反):
var pixelShift = function (sourceCanvas, shiftCanvas, xOffset, yOffset) {
var shiftXY = { xS:0, yS:0 };
var shiftCanvasWidth = shiftCanvas.width ;
var shiftCanvasHeight = shiftCanvas.height;
for ( var x=0 ; x < shiftCanvasWidth ; x ++) {
for ( var y = 0 ; y < shiftCanvasHeight ; y++ ) {
readShift ( shiftCanvas, x, y, shiftXY );
var sourceColor = readPixelColor ( sourceCanvas,
xOffset + shiftXY.xS,
yOffset + shiftXY.yS) ;
writePixel(sourceCanvas, xOffset + x , yOffset + y, sourceColor );
}
}
};
// sourceColor represents the color within a 32 bits integer (r,g,b,a * 8 bits).
在这里写所有东西太长了,但是:
-- 在 pixelShift 循环中,您不应处理源画布,而应处理 32 位性能数组。
-- 班次画布应转换一次为 Int8Array 数组,并按此存储。
这个数组大小是 shiftWidth * shiftHeight
奇数索引包含 x 移位,偶数包含 y 移位。
该数组经过预处理,并包含移位值 - 128。
对于此 shiftArray :
shiftX (x,y) = shiftArray [ 2 * (x + y * shiftWidth) ] ;
shiftY (x,y) = shiftArray [ 2 * (x + y * shiftWidth) + 1 ] ;
- 所以 pixelShift 应该是这样的:
var pixelShift = function (sourceCanvas,
shiftArray, shiftWidth, shiftHeight, xOffset, yOffset) {
[ Get a 32 bit performance array out of the canvas's target area ]
[ process this array using the shiftArray ]
[ write back the processed array onto the canvas's target area ]
}
- 核心循环可以以线性方式处理:
var areaSize = shiftWidth * shiftHeight ;
for ( pixelIndex=0 ; pixelIndex < areaSize ; pixelIndex++ ) {
var linearShift = shiftArray [ 2*pixelIndex ]
+ shiftWidth * shiftArray [ 2*pixelIndex + 1 ] ;
targetAreaArray [ pixelIndex ] = targetAreaArray [ pixelIndex + linearShift ] ;
}
-- Rq : 你可能想要在 [0, areaSize[.
——我想现在你不能再快了。
性能瓶颈将是获取/放置目标区域所需的 getImageData 和 putImageData,但据我所知,除了这两个 slooooow 函数之外,没有其他方法可以在 Canvas 上获取二进制视图。