如何沿指定方向/轴(+x、-y等)独立调整节点大小?
单方向缩放节点的枢轴调整方案
核心思路是拖动对应手柄时,临时将节点的pivot(枢轴)切换到手柄所在的边缘,配合scale实现单方向扩展;缩放完成后,同步更新节点的位置或边界记录,以此支持多次不同方向的调整操作。
具体实现逻辑(2D/3D通用)
假设节点有原始尺寸(width, height, depth),我们需要同步维护节点的实际物理边界(左/右/上/下/前/后),而非仅依赖scale和pivot:
拖动+x方向手柄:
- 将节点pivot.x设为
1(以节点自身坐标系为准,1代表右侧边缘) - 根据拖动偏移量调整
scale.x,此时缩放只会向+x方向延伸 - 缩放完成后,更新节点的右边界位置,可选择将pivot重置回默认值(如0.5),同时调整节点x坐标抵消枢轴变化带来的位置偏移
- 将节点pivot.x设为
拖动-x方向手柄:
- 将pivot.x设为
0(左侧边缘) - 调整
scale.x,缩放仅向-x方向收缩/扩展 - 更新左边界,同步调整节点x坐标保证位置正确
- 将pivot.x设为
y/z方向逻辑完全对应:
- +y手柄:pivot.y设为1,调整scale.y
- -y手柄:pivot.y设为0,调整scale.y
- +z手柄:pivot.z设为1,调整scale.z
- -z手柄:pivot.z设为0,调整scale.z
多次调整的关键:维护实际边界
每次缩放后,通过当前的scale、pivot和原始尺寸计算节点的真实边界(比如left = x - width*scale.x*pivot.x)。下次拖动其他手柄时,基于最新边界重新计算枢轴和scale的对应关系,确保缩放方向不冲突。
伪代码示例
// 节点初始状态 const node = { x: 0, y: 0, z: 0, scale: { x: 1, y: 1, z: 1 }, pivot: { x: 0.5, y: 0.5, z: 0.5 }, originalSize: { width: 100, height: 100, depth: 100 } }; // 计算当前节点边界 function getCurrentBounds(node) { return { left: node.x - node.originalSize.width * node.scale.x * node.pivot.x, right: node.x + node.originalSize.width * node.scale.x * (1 - node.pivot.x), top: node.y + node.originalSize.height * node.scale.y * (1 - node.pivot.y), bottom: node.y - node.originalSize.height * node.scale.y * node.pivot.y, front: node.z + node.originalSize.depth * node.scale.z * (1 - node.pivot.z), back: node.z - node.originalSize.depth * node.scale.z * node.pivot.z }; } // 处理+x方向拖动 function handleXPlusResize(node, dragOffset) { const bounds = getCurrentBounds(node); // 切换枢轴到右侧 node.pivot.x = 1; // 计算新缩放比例(防止缩放到0以下) node.scale.x = Math.max(node.scale.x + dragOffset / node.originalSize.width, 0.1); // 保持左边界不变,更新节点位置 node.x = bounds.left + node.originalSize.width * node.scale.x * node.pivot.x; }
内容的提问来源于stack exchange,提问作者Andy Hin
相关产品推荐
相关产品推荐

