合并画布代码
This commit is contained in:
@@ -0,0 +1,480 @@
|
||||
/**
|
||||
* 液化功能集成测试
|
||||
* 用于在浏览器环境中测试完整的液化工作流程
|
||||
*/
|
||||
|
||||
import { LiquifyCPUManager } from "../managers/liquify/LiquifyCPUManager.js";
|
||||
import { LiquifyWebGLManager } from "../managers/liquify/LiquifyWebGLManager.js";
|
||||
import { LiquifyRealTimeUpdater } from "../managers/liquify/LiquifyRealTimeUpdater.js";
|
||||
import { EnhancedLiquifyManager } from "../managers/liquify/EnhancedLiquifyManager.js";
|
||||
|
||||
// 集成测试结果
|
||||
let testResults = {
|
||||
totalTests: 0,
|
||||
passedTests: 0,
|
||||
failedTests: 0,
|
||||
errors: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* 创建测试图像数据
|
||||
*/
|
||||
function createTestImageData(width = 100, height = 100) {
|
||||
const imageData = new ImageData(width, height);
|
||||
const data = imageData.data;
|
||||
|
||||
// 创建一个简单的渐变图案用于测试
|
||||
for (let y = 0; y < height; y++) {
|
||||
for (let x = 0; x < width; x++) {
|
||||
const index = (y * width + x) * 4;
|
||||
data[index] = (x / width) * 255; // Red
|
||||
data[index + 1] = (y / height) * 255; // Green
|
||||
data[index + 2] = 128; // Blue
|
||||
data[index + 3] = 255; // Alpha
|
||||
}
|
||||
}
|
||||
|
||||
return imageData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建测试Canvas
|
||||
*/
|
||||
function createTestCanvas(width = 200, height = 200) {
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
return canvas;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建模拟Fabric对象
|
||||
*/
|
||||
function createMockFabricObject(imageData) {
|
||||
return {
|
||||
left: 50,
|
||||
top: 50,
|
||||
width: imageData.width,
|
||||
height: imageData.height,
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
angle: 0,
|
||||
flipX: false,
|
||||
flipY: false,
|
||||
_element: null,
|
||||
calcTransformMatrix: function () {
|
||||
return [this.scaleX, 0, 0, this.scaleY, this.left, this.top];
|
||||
},
|
||||
set: function (props) {
|
||||
Object.assign(this, props);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行单个测试
|
||||
*/
|
||||
async function runTest(testName, testFunction) {
|
||||
testResults.totalTests++;
|
||||
|
||||
try {
|
||||
console.log(`🧪 运行测试: ${testName}`);
|
||||
await testFunction();
|
||||
testResults.passedTests++;
|
||||
console.log(`✅ 测试通过: ${testName}`);
|
||||
} catch (error) {
|
||||
testResults.failedTests++;
|
||||
testResults.errors.push({ testName, error: error.message });
|
||||
console.error(`❌ 测试失败: ${testName}`, error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试CPU管理器基本功能
|
||||
*/
|
||||
async function testCPUManagerBasics() {
|
||||
const manager = new LiquifyCPUManager();
|
||||
const testImageData = createTestImageData();
|
||||
|
||||
// 初始化
|
||||
manager.initialize(testImageData);
|
||||
|
||||
// 设置参数
|
||||
manager.setParams({
|
||||
size: 50,
|
||||
pressure: 0.5,
|
||||
distortion: 0.3,
|
||||
power: 0.8,
|
||||
});
|
||||
|
||||
// 设置模式
|
||||
manager.setMode("push");
|
||||
|
||||
// 应用变形
|
||||
const result = manager.applyDeformation(50, 50);
|
||||
|
||||
if (
|
||||
!result ||
|
||||
result.width !== testImageData.width ||
|
||||
result.height !== testImageData.height
|
||||
) {
|
||||
throw new Error("CPU管理器变形结果无效");
|
||||
}
|
||||
|
||||
// 测试不同模式
|
||||
const modes = [
|
||||
"push",
|
||||
"clockwise",
|
||||
"counterclockwise",
|
||||
"pinch",
|
||||
"expand",
|
||||
"reconstruct",
|
||||
];
|
||||
for (const mode of modes) {
|
||||
manager.setMode(mode);
|
||||
const modeResult = manager.applyDeformation(25, 25);
|
||||
if (!modeResult) {
|
||||
throw new Error(`模式 ${mode} 变形失败`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试WebGL管理器基本功能
|
||||
*/
|
||||
async function testWebGLManagerBasics() {
|
||||
const manager = new LiquifyWebGLManager();
|
||||
const testImageData = createTestImageData();
|
||||
|
||||
try {
|
||||
// 初始化
|
||||
manager.initialize(testImageData);
|
||||
|
||||
// 检查WebGL是否可用
|
||||
if (!manager.initialized) {
|
||||
console.warn("WebGL不可用,跳过WebGL测试");
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置参数
|
||||
manager.setParams({
|
||||
size: 50,
|
||||
pressure: 0.5,
|
||||
distortion: 0.3,
|
||||
power: 0.8,
|
||||
});
|
||||
|
||||
// 设置模式
|
||||
manager.setMode("push");
|
||||
|
||||
// 应用变形
|
||||
const result = manager.applyDeformation(50, 50);
|
||||
|
||||
if (
|
||||
!result ||
|
||||
result.width !== testImageData.width ||
|
||||
result.height !== testImageData.height
|
||||
) {
|
||||
throw new Error("WebGL管理器变形结果无效");
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.message.includes("WebGL")) {
|
||||
console.warn("WebGL不支持,跳过WebGL测试");
|
||||
return;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试实时更新器功能
|
||||
*/
|
||||
async function testRealTimeUpdater() {
|
||||
const canvas = createTestCanvas();
|
||||
const testImageData = createTestImageData();
|
||||
const mockFabricObject = createMockFabricObject(testImageData);
|
||||
|
||||
// 模拟fabric Canvas
|
||||
const fabricCanvas = {
|
||||
getObjects: () => [mockFabricObject],
|
||||
remove: () => {},
|
||||
insertAt: () => {},
|
||||
renderAll: () => {},
|
||||
};
|
||||
|
||||
const updater = new LiquifyRealTimeUpdater(fabricCanvas);
|
||||
|
||||
// 设置目标对象
|
||||
updater.setTargetObject(mockFabricObject);
|
||||
|
||||
// 测试快速更新
|
||||
await updater.updateImage(testImageData, true);
|
||||
|
||||
// 测试完整更新
|
||||
await updater.updateImage(testImageData, false);
|
||||
|
||||
// 测试待处理更新
|
||||
updater.pendingImageData = testImageData;
|
||||
await updater.processPendingUpdates();
|
||||
|
||||
// 清理
|
||||
updater.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试增强液化管理器
|
||||
*/
|
||||
async function testEnhancedLiquifyManager() {
|
||||
const manager = new EnhancedLiquifyManager();
|
||||
const testImageData = createTestImageData();
|
||||
const mockFabricObject = createMockFabricObject(testImageData);
|
||||
|
||||
// 初始化
|
||||
const result = await manager.prepareForLiquify(mockFabricObject);
|
||||
|
||||
if (!result || !result.originalImageData) {
|
||||
throw new Error("增强液化管理器初始化失败");
|
||||
}
|
||||
|
||||
// 设置参数
|
||||
manager.setParams({
|
||||
size: 50,
|
||||
pressure: 0.5,
|
||||
distortion: 0.3,
|
||||
power: 0.8,
|
||||
});
|
||||
|
||||
// 应用液化
|
||||
const liquifyResult = await manager.applyLiquify(
|
||||
mockFabricObject,
|
||||
"push",
|
||||
{ size: 50, pressure: 0.5, distortion: 0.3, power: 0.8 },
|
||||
50,
|
||||
50
|
||||
);
|
||||
|
||||
if (!liquifyResult) {
|
||||
throw new Error("液化应用失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试坐标转换准确性
|
||||
*/
|
||||
async function testCoordinateConversion() {
|
||||
const testImageData = createTestImageData(200, 200);
|
||||
const mockFabricObject = createMockFabricObject(testImageData);
|
||||
|
||||
// 测试不同的缩放情况
|
||||
const testCases = [
|
||||
{ scaleX: 1, scaleY: 1, flipX: false, flipY: false },
|
||||
{ scaleX: 2, scaleY: 2, flipX: false, flipY: false },
|
||||
{ scaleX: 0.5, scaleY: 0.5, flipX: false, flipY: false },
|
||||
{ scaleX: 1, scaleY: 1, flipX: true, flipY: false },
|
||||
{ scaleX: 1, scaleY: 1, flipX: false, flipY: true },
|
||||
];
|
||||
|
||||
for (const testCase of testCases) {
|
||||
Object.assign(mockFabricObject, testCase);
|
||||
|
||||
// 模拟坐标转换函数(简化版)
|
||||
const fabricX = 100,
|
||||
fabricY = 100;
|
||||
|
||||
// 创建变换矩阵模拟
|
||||
const transform = mockFabricObject.calcTransformMatrix();
|
||||
|
||||
// 基本的坐标边界检查
|
||||
const localX = (fabricX - mockFabricObject.left) / mockFabricObject.scaleX;
|
||||
const localY = (fabricY - mockFabricObject.top) / mockFabricObject.scaleY;
|
||||
|
||||
if (
|
||||
localX < -mockFabricObject.width / 2 ||
|
||||
localX > mockFabricObject.width / 2 ||
|
||||
localY < -mockFabricObject.height / 2 ||
|
||||
localY > mockFabricObject.height / 2
|
||||
) {
|
||||
// 坐标在对象外部,这是正常情况
|
||||
continue;
|
||||
}
|
||||
|
||||
// 转换到图像坐标
|
||||
let imageX =
|
||||
(localX + mockFabricObject.width / 2) *
|
||||
(testImageData.width / mockFabricObject.width);
|
||||
let imageY =
|
||||
(localY + mockFabricObject.height / 2) *
|
||||
(testImageData.height / mockFabricObject.height);
|
||||
|
||||
// 处理翻转
|
||||
if (mockFabricObject.flipX) {
|
||||
imageX = testImageData.width - imageX;
|
||||
}
|
||||
if (mockFabricObject.flipY) {
|
||||
imageY = testImageData.height - imageY;
|
||||
}
|
||||
|
||||
// 验证结果在合理范围内
|
||||
if (
|
||||
imageX < 0 ||
|
||||
imageX >= testImageData.width ||
|
||||
imageY < 0 ||
|
||||
imageY >= testImageData.height
|
||||
) {
|
||||
throw new Error(`坐标转换结果超出图像范围: (${imageX}, ${imageY})`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试性能表现
|
||||
*/
|
||||
async function testPerformance() {
|
||||
const manager = new LiquifyCPUManager();
|
||||
const testImageData = createTestImageData(400, 400); // 更大的图像
|
||||
|
||||
manager.initialize(testImageData);
|
||||
manager.setParams({
|
||||
size: 50,
|
||||
pressure: 0.5,
|
||||
distortion: 0.3,
|
||||
power: 0.8,
|
||||
});
|
||||
manager.setMode("push");
|
||||
|
||||
// 测试多次操作的性能
|
||||
const startTime = performance.now();
|
||||
const operationCount = 100;
|
||||
|
||||
for (let i = 0; i < operationCount; i++) {
|
||||
const x = Math.random() * testImageData.width;
|
||||
const y = Math.random() * testImageData.height;
|
||||
manager.applyDeformation(x, y);
|
||||
}
|
||||
|
||||
const endTime = performance.now();
|
||||
const totalTime = endTime - startTime;
|
||||
const avgTime = totalTime / operationCount;
|
||||
|
||||
console.log(
|
||||
`性能测试结果: ${operationCount} 次操作,总耗时 ${totalTime.toFixed(
|
||||
2
|
||||
)}ms,平均 ${avgTime.toFixed(2)}ms/次`
|
||||
);
|
||||
|
||||
// 验证性能阈值(每次操作不应超过50ms)
|
||||
if (avgTime > 50) {
|
||||
throw new Error(
|
||||
`性能不达标:平均操作时间 ${avgTime.toFixed(2)}ms 超过阈值 50ms`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试内存管理
|
||||
*/
|
||||
async function testMemoryManagement() {
|
||||
const initialMemory = performance.memory
|
||||
? performance.memory.usedJSHeapSize
|
||||
: 0;
|
||||
|
||||
// 创建多个管理器实例
|
||||
const managers = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const manager = new LiquifyCPUManager();
|
||||
const testImageData = createTestImageData(200, 200);
|
||||
manager.initialize(testImageData);
|
||||
managers.push(manager);
|
||||
}
|
||||
|
||||
// 销毁所有管理器
|
||||
for (const manager of managers) {
|
||||
if (manager.destroy) {
|
||||
manager.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
// 强制垃圾回收(如果可用)
|
||||
if (window.gc) {
|
||||
window.gc();
|
||||
}
|
||||
|
||||
const finalMemory = performance.memory
|
||||
? performance.memory.usedJSHeapSize
|
||||
: 0;
|
||||
const memoryIncrease = finalMemory - initialMemory;
|
||||
|
||||
console.log(
|
||||
`内存测试: 初始 ${(initialMemory / 1024 / 1024).toFixed(2)}MB, 最终 ${(
|
||||
finalMemory /
|
||||
1024 /
|
||||
1024
|
||||
).toFixed(2)}MB, 增长 ${(memoryIncrease / 1024 / 1024).toFixed(2)}MB`
|
||||
);
|
||||
|
||||
// 验证内存增长不超过10MB(基本的内存泄漏检查)
|
||||
if (memoryIncrease > 10 * 1024 * 1024) {
|
||||
console.warn(
|
||||
`潜在内存泄漏: 内存增长 ${(memoryIncrease / 1024 / 1024).toFixed(2)}MB`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行所有集成测试
|
||||
*/
|
||||
export async function runLiquifyIntegrationTests() {
|
||||
console.log("🚀 开始液化功能集成测试...");
|
||||
|
||||
// 重置测试结果
|
||||
testResults = {
|
||||
totalTests: 0,
|
||||
passedTests: 0,
|
||||
failedTests: 0,
|
||||
errors: [],
|
||||
};
|
||||
|
||||
try {
|
||||
// 基础功能测试
|
||||
await runTest("CPU管理器基本功能", testCPUManagerBasics);
|
||||
await runTest("WebGL管理器基本功能", testWebGLManagerBasics);
|
||||
await runTest("实时更新器功能", testRealTimeUpdater);
|
||||
await runTest("增强液化管理器", testEnhancedLiquifyManager);
|
||||
|
||||
// 高级功能测试
|
||||
await runTest("坐标转换准确性", testCoordinateConversion);
|
||||
await runTest("性能表现", testPerformance);
|
||||
await runTest("内存管理", testMemoryManagement);
|
||||
} catch (error) {
|
||||
console.error("集成测试出现严重错误:", error);
|
||||
}
|
||||
|
||||
// 输出测试结果
|
||||
console.log("\n📊 液化功能集成测试结果:");
|
||||
console.log(`总测试数: ${testResults.totalTests}`);
|
||||
console.log(`通过: ${testResults.passedTests}`);
|
||||
console.log(`失败: ${testResults.failedTests}`);
|
||||
console.log(
|
||||
`成功率: ${(
|
||||
(testResults.passedTests / testResults.totalTests) *
|
||||
100
|
||||
).toFixed(1)}%`
|
||||
);
|
||||
|
||||
if (testResults.errors.length > 0) {
|
||||
console.log("\n❌ 失败的测试:");
|
||||
testResults.errors.forEach(({ testName, error }) => {
|
||||
console.log(` - ${testName}: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
return testResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在浏览器控制台中运行测试
|
||||
*/
|
||||
if (typeof window !== "undefined") {
|
||||
window.runLiquifyIntegrationTests = runLiquifyIntegrationTests;
|
||||
console.log("💡 使用 window.runLiquifyIntegrationTests() 运行液化集成测试");
|
||||
}
|
||||
Reference in New Issue
Block a user