ejsoon 写了: gemini
子元素的transform裏有translate(x1,y1)和scale(z1),兩手指在父元素初始坐標分別為(x20,y20)和(x30,y30),兩手指移動到父元素坐標(x2,y2)和(x3,y3),我們希望子元素因兩手指坐標的變化而縮放及平移,則子元素的x1,y1,z1應如何變化?
Understanding the Problem
We're dealing with a touch-based scaling and translation of a child element within a parent element. The child already has an initial transform applied (translate and scale). We need to calculate the *change* in translation and scale based on the two-finger gesture.
Calculations
1.
Initial Distance and Center
The initial distance between the two fingers is:
代码: 全选
$initialDistance = sqrt(pow($x30 - $x20, 2) + pow($y30 - $y20, 2));
The initial center point between the two fingers is:
代码: 全选
$initialCenterX = ($x20 + $x30) / 2;
$initialCenterY = ($y20 + $y30) / 2;
2.
Final Distance and Center
The final distance between the two fingers is:
代码: 全选
$finalDistance = sqrt(pow($x3 - $x2, 2) + pow($y3 - $y2, 2));
The final center point between the two fingers is:
代码: 全选
$finalCenterX = ($x2 + $x3) / 2;
$finalCenterY = ($y2 + $y3) / 2;
3.
Scale Change
The scale factor change is the ratio of the final distance to the initial distance:
代码: 全选
$scaleChange = $finalDistance / $initialDistance;
The new scale (z1) will be:
代码: 全选
$newZ1 = $z1 * $scaleChange;
4.
Translation Change
The translation change is the difference between the final and initial center points, considering the scaling:
代码: 全选
$translateXChange = ($finalCenterX - $initialCenterX) * $newZ1;
$translateYChange = ($finalCenterY - $initialCenterY) * $newZ1;
The new translation values (x1, y1) will be:
代码: 全选
$newX1 = $x1 + $translateXChange;
$newY1 = $y1 + $translateYChange;
Final Transform
The final transform of the child element should be:
代码: 全选
transform: translate($newX1px, $newY1px) scale($newZ1);
Important Considerations
*
Divide by Zero: If `$initialDistance` is zero (fingers start at the same point), you'll encounter a divide-by-zero error. Handle this case by either setting a minimum `$initialDistance` or ignoring the scaling until the fingers move apart.
*
Units: Ensure all your coordinates are in the same units (likely pixels).
*
Accumulated Transformations: This calculation assumes you're applying the new transform directly. If you're accumulating transformations, you'll need to adjust the logic accordingly. It's generally better to recalculate the transform from the original state each time rather than accumulating transformations, as this avoids compounding rounding errors.
*
JavaScript Implementation: This logic would typically be implemented in JavaScript to handle the touch events. The provided code snippets are illustrative and need to be adapted to a JavaScript context.
This approach provides a smooth and intuitive scaling and translation behavior based on two-finger touch gestures. Remember to test thoroughly on different devices and browsers.