feat: 裁剪组裁剪跟随选择组移动

This commit is contained in:
bighuixiang
2025-07-14 01:00:23 +08:00
parent 96e13cb22a
commit 24e9ba8ae5
80 changed files with 2052 additions and 4292 deletions

View File

@@ -113,23 +113,12 @@ async function testCPUManagerBasics() {
// 应用变形
const result = manager.applyDeformation(50, 50);
if (
!result ||
result.width !== testImageData.width ||
result.height !== testImageData.height
) {
if (!result || result.width !== testImageData.width || result.height !== testImageData.height) {
throw new Error("CPU管理器变形结果无效");
}
// 测试不同模式
const modes = [
"push",
"clockwise",
"counterclockwise",
"pinch",
"expand",
"reconstruct",
];
const modes = ["push", "clockwise", "counterclockwise", "pinch", "expand", "reconstruct"];
for (const mode of modes) {
manager.setMode(mode);
const modeResult = manager.applyDeformation(25, 25);
@@ -170,11 +159,7 @@ async function testWebGLManagerBasics() {
// 应用变形
const result = manager.applyDeformation(50, 50);
if (
!result ||
result.width !== testImageData.width ||
result.height !== testImageData.height
) {
if (!result || result.width !== testImageData.width || result.height !== testImageData.height) {
throw new Error("WebGL管理器变形结果无效");
}
} catch (error) {
@@ -300,11 +285,9 @@ async function testCoordinateConversion() {
// 转换到图像坐标
let imageX =
(localX + mockFabricObject.width / 2) *
(testImageData.width / mockFabricObject.width);
(localX + mockFabricObject.width / 2) * (testImageData.width / mockFabricObject.width);
let imageY =
(localY + mockFabricObject.height / 2) *
(testImageData.height / mockFabricObject.height);
(localY + mockFabricObject.height / 2) * (testImageData.height / mockFabricObject.height);
// 处理翻转
if (mockFabricObject.flipX) {
@@ -364,9 +347,7 @@ async function testPerformance() {
// 验证性能阈值每次操作不应超过50ms
if (avgTime > 50) {
throw new Error(
`性能不达标:平均操作时间 ${avgTime.toFixed(2)}ms 超过阈值 50ms`
);
throw new Error(`性能不达标:平均操作时间 ${avgTime.toFixed(2)}ms 超过阈值 50ms`);
}
}
@@ -374,9 +355,7 @@ async function testPerformance() {
* 测试内存管理
*/
async function testMemoryManagement() {
const initialMemory = performance.memory
? performance.memory.usedJSHeapSize
: 0;
const initialMemory = performance.memory ? performance.memory.usedJSHeapSize : 0;
// 创建多个管理器实例
const managers = [];
@@ -399,9 +378,7 @@ async function testMemoryManagement() {
window.gc();
}
const finalMemory = performance.memory
? performance.memory.usedJSHeapSize
: 0;
const finalMemory = performance.memory ? performance.memory.usedJSHeapSize : 0;
const memoryIncrease = finalMemory - initialMemory;
console.log(
@@ -414,9 +391,7 @@ async function testMemoryManagement() {
// 验证内存增长不超过10MB基本的内存泄漏检查
if (memoryIncrease > 10 * 1024 * 1024) {
console.warn(
`潜在内存泄漏: 内存增长 ${(memoryIncrease / 1024 / 1024).toFixed(2)}MB`
);
console.warn(`潜在内存泄漏: 内存增长 ${(memoryIncrease / 1024 / 1024).toFixed(2)}MB`);
}
}
@@ -454,12 +429,7 @@ export async function runLiquifyIntegrationTests() {
console.log(`总测试数: ${testResults.totalTests}`);
console.log(`通过: ${testResults.passedTests}`);
console.log(`失败: ${testResults.failedTests}`);
console.log(
`成功率: ${(
(testResults.passedTests / testResults.totalTests) *
100
).toFixed(1)}%`
);
console.log(`成功率: ${((testResults.passedTests / testResults.totalTests) * 100).toFixed(1)}%`);
if (testResults.errors.length > 0) {
console.log("\n❌ 失败的测试:");

View File

@@ -45,19 +45,13 @@ export function testCoordinateConversion() {
// 模拟转换结果
const expectedImageX =
((coord.x - mockFabricObject.left) / mockFabricObject.scaleX +
mockFabricObject.width / 2) *
((coord.x - mockFabricObject.left) / mockFabricObject.scaleX + mockFabricObject.width / 2) *
(mockImageData.width / mockFabricObject.width);
const expectedImageY =
((coord.y - mockFabricObject.top) / mockFabricObject.scaleY +
mockFabricObject.height / 2) *
((coord.y - mockFabricObject.top) / mockFabricObject.scaleY + mockFabricObject.height / 2) *
(mockImageData.height / mockFabricObject.height);
console.log(
` 预期图像坐标: (${expectedImageX.toFixed(2)}, ${expectedImageY.toFixed(
2
)})`
);
console.log(` 预期图像坐标: (${expectedImageX.toFixed(2)}, ${expectedImageY.toFixed(2)})`);
});
console.log("坐标转换测试完成");
@@ -83,10 +77,7 @@ export function testPushAlgorithmPerformance() {
// 模拟液化计算
const movementLength =
i > 0
? Math.sqrt(
Math.pow(x - movements[i - 1].x, 2) +
Math.pow(y - movements[i - 1].y, 2)
)
? Math.sqrt(Math.pow(x - movements[i - 1].x, 2) + Math.pow(y - movements[i - 1].y, 2))
: 0;
if (movementLength > 0.5) {
@@ -151,12 +142,8 @@ export function testScaleConsistency() {
const localX = (canvasCoord.x - fabricObject.left) / fabricObject.scaleX;
const localY = (canvasCoord.y - fabricObject.top) / fabricObject.scaleY;
const imageX =
(localX + fabricObject.width / 2) *
(imageData.width / fabricObject.width);
const imageY =
(localY + fabricObject.height / 2) *
(imageData.height / fabricObject.height);
const imageX = (localX + fabricObject.width / 2) * (imageData.width / fabricObject.width);
const imageY = (localY + fabricObject.height / 2) * (imageData.height / fabricObject.height);
console.log(` 画布坐标: (${canvasCoord.x}, ${canvasCoord.y})`);
console.log(` 本地坐标: (${localX.toFixed(2)}, ${localY.toFixed(2)})`);
@@ -164,10 +151,7 @@ export function testScaleConsistency() {
// 验证图像坐标是否在合理范围内
const isValid =
imageX >= 0 &&
imageX < imageData.width &&
imageY >= 0 &&
imageY < imageData.height;
imageX >= 0 && imageX < imageData.width && imageY >= 0 && imageY < imageData.height;
console.log(` 坐标有效性: ${isValid ? "✓" : "✗"}`);
});
@@ -190,10 +174,7 @@ export function runAllTests() {
console.log("=== 液化功能测试完成 ===");
console.log(
`推荐配置: 节流时间 ${Math.max(
16,
perfResult.avgTimePerOperation * 2
).toFixed(0)}ms`
`推荐配置: 节流时间 ${Math.max(16, perfResult.avgTimePerOperation * 2).toFixed(0)}ms`
);
return {