You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: editor-packages/editor-canvas/canvas/canvas.tsx
+71-64Lines changed: 71 additions & 64 deletions
Original file line number
Diff line number
Diff line change
@@ -59,67 +59,6 @@ interface HovringNode {
59
59
reason: "frame-title"|"raycast"|"external";
60
60
}
61
61
62
-
functionauto_initial_transform(
63
-
viewbound: Box,
64
-
nodes: ReflectSceneNode[]
65
-
): CanvasTransform{
66
-
const_default={
67
-
scale: INITIAL_SCALE,
68
-
xy: INITIAL_XY,
69
-
};
70
-
71
-
if(!nodes||viewbound_not_measured(viewbound)){
72
-
return_default;
73
-
}
74
-
75
-
constfit_single_node=(n: ReflectSceneNode)=>{
76
-
returncenterOf(viewbound,n);
77
-
};
78
-
79
-
if(nodes.length===0){
80
-
return_default;
81
-
}elseif(nodes.length===1){
82
-
// return center the node
83
-
constc=fit_single_node(nodes[0]);
84
-
return{
85
-
xy: c.translate,
86
-
scale: c.scale,
87
-
};
88
-
}elseif(nodes.length<20){
89
-
// fit bounds
90
-
constc=centerOf(viewbound, ...nodes);
91
-
return{
92
-
xy: c.translate,
93
-
scale: c.scale,
94
-
};
95
-
}else{
96
-
// if more than 20 nodes, just center the first one. why? -> loading all frames at once will slow down the canvas, and in most cases, we don't have to show the whole content of the canvas.
97
-
// fit first item
98
-
constc=fit_single_node(nodes[0]);
99
-
return{
100
-
xy: c.translate,
101
-
scale: c.scale,
102
-
};
103
-
}
104
-
105
-
return_default;
106
-
}
107
-
108
-
/**
109
-
* when viewbound is not measured, it means the canvas is not ready to render. and the value will be `[0,0,0,0]` (from react-use-measure)
110
-
* @param viewbound visible canvas area bound
111
-
* @returns
112
-
*/
113
-
constviewbound_not_measured=(viewbound: Box)=>{
114
-
return(
115
-
!viewbound||
116
-
(viewbound[0]===0&&
117
-
viewbound[1]===0&&
118
-
viewbound[2]===0&&
119
-
viewbound[3]===0)
120
-
);
121
-
};
122
-
123
62
exportfunctionCanvas({
124
63
viewbound,
125
64
renderItem,
@@ -251,17 +190,24 @@ export function Canvas({
251
190
252
191
constonZooming: OnZoomingHandler=(state)=>{
253
192
constzoomdelta=state.delta[0];
254
-
constzoompoint: XY=[
193
+
// the origin point of the zooming point in x, y
194
+
const[ox,oy]: XY=[
255
195
// @ts-ignore
256
196
state.event.clientX??0,
257
197
// @ts-ignore
258
198
state.event.clientY??0,
259
199
];
260
200
261
201
constnewzoom=Math.max(zoom+zoomdelta,MIN_ZOOM);
202
+
203
+
// calculate the offset that should be applied with scale with css transform.
204
+
const[newx,newy]=[
205
+
ox-(ox-offset[0])*(newzoom/zoom),
206
+
oy-(oy-offset[1])*(newzoom/zoom),
207
+
];
208
+
262
209
setZoom(newzoom);
263
-
// TODO: transform offset
264
-
// setOffset([offset[0], offset[1]]);
210
+
setOffset([newx,newy]);
265
211
};
266
212
267
213
constis_canvas_transforming=isPanning||isZooming;
@@ -388,3 +334,64 @@ function DisableBackdropFilter({ children }: { children: React.ReactNode }) {
388
334
</div>
389
335
);
390
336
}
337
+
338
+
functionauto_initial_transform(
339
+
viewbound: Box,
340
+
nodes: ReflectSceneNode[]
341
+
): CanvasTransform{
342
+
const_default={
343
+
scale: INITIAL_SCALE,
344
+
xy: INITIAL_XY,
345
+
};
346
+
347
+
if(!nodes||viewbound_not_measured(viewbound)){
348
+
return_default;
349
+
}
350
+
351
+
constfit_single_node=(n: ReflectSceneNode)=>{
352
+
returncenterOf(viewbound,n);
353
+
};
354
+
355
+
if(nodes.length===0){
356
+
return_default;
357
+
}elseif(nodes.length===1){
358
+
// return center the node
359
+
constc=fit_single_node(nodes[0]);
360
+
return{
361
+
xy: c.translate,
362
+
scale: c.scale,
363
+
};
364
+
}elseif(nodes.length<20){
365
+
// fit bounds
366
+
constc=centerOf(viewbound, ...nodes);
367
+
return{
368
+
xy: c.translate,
369
+
scale: c.scale,
370
+
};
371
+
}else{
372
+
// if more than 20 nodes, just center the first one. why? -> loading all frames at once will slow down the canvas, and in most cases, we don't have to show the whole content of the canvas.
373
+
// fit first item
374
+
constc=fit_single_node(nodes[0]);
375
+
return{
376
+
xy: c.translate,
377
+
scale: c.scale,
378
+
};
379
+
}
380
+
381
+
return_default;
382
+
}
383
+
384
+
/**
385
+
* when viewbound is not measured, it means the canvas is not ready to render. and the value will be `[0,0,0,0]` (from react-use-measure)
0 commit comments