P.cleanOutput = function () {
let self = this;
return new Promise((resolve, reject) => {
self.dirtyOutput = false;
self.setSourceDimension();
let sourceDimension = self.sourceDimension,
sourceData = self.sourceImageData;
if (sourceDimension && sourceData) {
let mHypot = Math.hypot,
mFloor = Math.floor,
mCeil = Math.ceil,
mAtan2 = Math.atan2,
mCos = Math.cos,
mSin = Math.sin;
let fromPathData = self.fromPathData,
toPathData = self.toPathData,
dataLen = fromPathData.length,
fPathStart = self.fromPathStart,
fCursor = fPathStart * dataLen,
fStep = self.fromPathSteps || 1,
tPathStart = self.toPathStart,
tCursor = tPathStart * dataLen,
tStep = self.toPathSteps || 1,
magicHorizontalPi = 0.5 * Math.PI,
magicVerticalPi = magicHorizontalPi - 1.5708,
isHorizontalCopy = self.isHorizontalCopy,
loop = self.loopPathCursors,
fx, fy, tx, ty, dx, dy, dLength, dAngle, cos, sin,
watchFromPath = self.watchFromPath,
watchIndex = self.watchIndex,
engineInstructions = self.engineInstructions,
engineDeltaLengths = self.engineDeltaLengths,
instruction;
let [startX, startY, outputWidth, outputHeight] = self.getBoundingBox();
let inputCell = requestCell(),
inputEngine = inputCell.engine,
inputCanvas = inputCell.element;
inputCanvas.width = sourceDimension;
inputCanvas.height = sourceDimension;
inputEngine.setTransform(1, 0, 0, 1, 0, 0);
inputEngine.putImageData(sourceData, 0, 0);
let outputCell = requestCell(),
outputEngine = outputCell.engine,
outputCanvas = outputCell.element;
outputCanvas.width = outputWidth;
outputCanvas.height = outputHeight;
outputEngine.globalAlpha = self.state.globalAlpha;
outputEngine.setTransform(1, 0, 0, 1, 0, 0);
if(!engineInstructions.length) {
for (let i = 0; i < sourceDimension; i++) {
if (watchIndex < 0) {
if (watchFromPath && fCursor < 1) watchIndex = i;
else if (!watchFromPath && tCursor < 1) watchIndex = i;
}
if (fCursor < dataLen && tCursor < dataLen && fCursor >= 0 && tCursor >= 0) {
[fx, fy] = fromPathData[mFloor(fCursor)];
[tx, ty] = toPathData[mFloor(tCursor)];
dx = tx - fx;
dy = ty - fy;
dLength = mHypot(dx, dy);
if (isHorizontalCopy) {
dAngle = -mAtan2(dx, dy) + magicHorizontalPi;
cos = mCos(dAngle);
sin = mSin(dAngle);
engineInstructions.push([cos, sin, -sin, cos, fx, fy]);
engineDeltaLengths.push(dLength);
}
else {
dAngle = -mAtan2(dx, dy) + magicVerticalPi;
cos = mCos(dAngle);
sin = mSin(dAngle);
engineInstructions.push([cos, sin, -sin, cos, fx, fy, dLength]);
engineDeltaLengths.push(dLength);
}
}
else {
engineInstructions.push(false);
engineDeltaLengths.push(false);
}
fCursor += fStep;
tCursor += tStep;
if (loop) {
if (fCursor >= dataLen) fCursor -= dataLen;
if (tCursor >= dataLen) tCursor -= dataLen;
}
}
if (watchIndex < 0) watchIndex = 0;
self.watchIndex = watchIndex;
}
if (isHorizontalCopy) {
for (let i = 0; i < sourceDimension; i++) {
instruction = engineInstructions[watchIndex];
if (instruction) {
outputEngine.setTransform(...instruction);
outputEngine.drawImage(inputCanvas, 0, watchIndex, sourceDimension, 1, 0, 0, engineDeltaLengths[watchIndex], 1);
}
watchIndex++;
if (watchIndex >= sourceDimension) watchIndex = 0;
}
}
else {
for (let i = 0; i < sourceDimension; i++) {
instruction = engineInstructions[watchIndex];
if (instruction) {
outputEngine.setTransform(...instruction);
outputEngine.drawImage(inputCanvas, watchIndex, 0, 1, sourceDimension, 0, 0, 1, engineDeltaLengths[watchIndex]);
}
watchIndex++;
if (watchIndex >= sourceDimension) watchIndex = 0;
}
}
let iFactor = self.interferenceFactor,
iLoops = self.interferenceLoops,
iWidth = mCeil(outputWidth * iFactor),
iHeight = mCeil(outputHeight * iFactor);
inputCanvas.width = iWidth;
inputCanvas.height = iHeight;
outputEngine.setTransform(1, 0, 0, 1, 0, 0);
inputEngine.setTransform(1, 0, 0, 1, 0, 0);
for (let j = 0; j < iLoops; j++) {
inputEngine.drawImage(outputCanvas, 0, 0, outputWidth, outputHeight, 0, 0, iWidth, iHeight);
outputEngine.drawImage(inputCanvas, 0, 0, iWidth, iHeight, 0, 0, outputWidth, outputHeight);
}
let outputData = outputEngine.getImageData(0, 0, outputWidth, outputHeight);
releaseCell(inputCell);
releaseCell(outputCell);
self.dirtyTargetImage = true;
resolve(outputData);
}
else reject(new Error(`${this.name} - cleanOutput Error: source has a zero dimension, or no data`));
});
};