|
1 | 1 | /** |
2 | | - * this function calculates the transform of the canvas. |
3 | | - * while scaling (zooming) the canvas, the transform should be made according to scale origin point. |
| 2 | + * this function calculates the offset of the xy that should be applied to the canvas while transforming. |
4 | 3 | * |
5 | | - * the canvas is in 0, 0 as in xy. |
6 | | - * the input is |
7 | | - * 1. scale origin as xy point |
8 | | - * 2. scale delta as number |
| 4 | + * the canvas is transformed with css transform() with scale, translateX, translateY. |
| 5 | + * if the xy is not translated, the canvas will visually scaled from top left. |
| 6 | + * what we want is to make the canvas scale from center (visaully). |
9 | 7 | * |
10 | | - * the output is the xy delta. |
| 8 | + * input: |
| 9 | + * @param zoomDelta: the delta of the zoom |
| 10 | + * @param center: the absolute point where the zoom was initiated. the canvas will transform from this point, keeping this point visually still. |
| 11 | + * @param canvasOffset: the origin of the canvas (the offset) (not scaled) |
| 12 | + * |
| 13 | + * the output is the absolute offset that should be applyied to the canvas to make it trasform with scale and translate from the origin as center. |
11 | 14 | */ |
12 | | -export function transform_by_zoom_delta( |
| 15 | +export function translate_while_keeping_center( |
13 | 16 | zoomDelta: number, |
14 | | - zoomOrigin: [number, number] |
| 17 | + center: [number, number], |
| 18 | + canvasOffset: [number, number] |
15 | 19 | ): [number, number] { |
16 | | - //TODO: this is incorrect. |
17 | | - const [x, y] = zoomOrigin; |
18 | | - const dX = -(x * zoomDelta); |
19 | | - const dY = -(y * zoomDelta); |
20 | | - return [dX, dY]; |
| 20 | + const [x, y] = center; |
| 21 | + const [ox, oy] = canvasOffset; |
| 22 | + const [cx, cy] = [x - ox, y - oy]; |
| 23 | + const [dx, dy] = [cx * zoomDelta, cy * zoomDelta]; |
| 24 | + return [ox - dx, oy - dy]; |
| 25 | +} |
| 26 | + |
| 27 | +/** |
| 28 | + * |
| 29 | + * @param zoomDelta the delta of the zoom |
| 30 | + * @param canvasOffset the origin of the canvas (the offset) |
| 31 | + * @param canvasSize size of the canvas in width and height |
| 32 | + * |
| 33 | + * @returns the final xy position that canvas should be positioned after the scaling. |
| 34 | + */ |
| 35 | +export function transform_center_by_zoom_delta( |
| 36 | + zoomDelta: number, |
| 37 | + canvasOffset: [number, number], |
| 38 | + canvasSize: [number, number] |
| 39 | +): [number, number] { |
| 40 | + const [cx, cy] = canvasOffset; |
| 41 | + const [cw, ch] = canvasSize; |
| 42 | + const dx = cx + (cw / 2) * zoomDelta; |
| 43 | + const dy = cy + (ch / 2) * zoomDelta; |
| 44 | + return [dx, dy]; |
| 45 | +} |
| 46 | + |
| 47 | +/** |
| 48 | + * |
| 49 | + * @param s scale value |
| 50 | + * @param x current x |
| 51 | + * scale(1) translateX(100) |
| 52 | + * scale(2, 100) // target scale, current x |
| 53 | + * scale(1) translateX(n) |
| 54 | + * n = ? |
| 55 | + * |
| 56 | + * => transform(scale(2), translateX(50)) |
| 57 | + */ |
| 58 | +function preserve_abs_after_scale(s: number, x: number): number { |
| 59 | + // get the n |
| 60 | + const n = x / s; |
| 61 | + return n; |
21 | 62 | } |
0 commit comments