2525 resolve_axis_rig_spec ,
2626)
2727from cubedynamics .utils import _infer_time_y_x_dims
28+ from cubedynamics .utils .drift_centering import drift_centering_script
2829from cubedynamics .plotting .progress import _CubeProgress
2930from cubedynamics .plotting .viewer import show_cube_viewer
3031from cubedynamics .vase import VasePanel
@@ -297,12 +298,24 @@ def _render_cube_html(
297298 --cd-axis-tick-l
298299 --cd-axis-stroke
299300 */
301+ /* Drift centering tuning (DYNAMIC DRIFT CENTERING V1):
302+ --cd-drift-max-px: maximum horizontal drift in pixels.
303+ --cd-drift-rot-range-deg: rotation range (deg) that maps to full drift.
304+ --cd-drift-scale-in: scale that cancels drift when zoomed in.
305+ --cd-drift-scale-out: scale that enables full drift when zoomed out.
306+ --cd-drift-smoothing: easing factor for motion smoothing.
307+ */
300308 --cd-cube-size: { cube_size_css } ;
301309 --cube-size: var(--cd-cube-size);
302310 --cd-axis-font: clamp(11px, calc(var(--cd-cube-size) * 0.045), 18px);
303311 --cd-axis-pill-px: clamp(4px, calc(var(--cd-cube-size) * 0.010), 8px);
304312 --cd-axis-stroke: clamp(2px, calc(var(--cd-cube-size) * 0.006), 4px);
305313 --cd-axis-tick-l: clamp(10px, calc(var(--cd-cube-size) * 0.035), 18px);
314+ --cd-drift-max-px: 220;
315+ --cd-drift-rot-range-deg: 55;
316+ --cd-drift-scale-in: 1.25;
317+ --cd-drift-scale-out: 0.85;
318+ --cd-drift-smoothing: 0.18;
306319 { css_vars }
307320 }}
308321 * {{ box-sizing: border-box; }}
@@ -430,6 +443,8 @@ def _render_cube_html(
430443 .cube-scene {{
431444 position: relative;
432445 inset: 0;
446+ width: 100%;
447+ height: 100%;
433448 perspective: 950px;
434449 transform-style: preserve-3d;
435450 --rot-x: 0rad;
@@ -454,6 +469,12 @@ def _render_cube_html(
454469 pointer-events: auto;
455470 }}
456471
472+ .cd-drift-center-fallback {{
473+ --cd-drift-x: 0px;
474+ --cd-drift-base-transform: none;
475+ transform: translateX(var(--cd-drift-x, 0px)) var(--cd-drift-base-transform, none);
476+ }}
477+
457478 .cd-cube {{
458479 position: absolute;
459480 inset: 0;
@@ -623,26 +644,28 @@ def _render_cube_html(
623644 <div class=\" cube-main\" >
624645 <div class=\" cube-inner\" >
625646 <div class=\" cube-container\" >
626- <div id=\" cube-wrapper-{ viewer_id } \" class=\" cube-wrapper\" style=\" --rot-x: { rot_x_rad :.4f} rad; --rot-y: { rot_y_rad :.4f} rad; --zoom: { zoom } ;\" >
627- <canvas class=\" cube-canvas\" id=\" cube-canvas-{ viewer_id } \" ></canvas>
628- <div class=\" cube-rotation\" id=\" cube-rotation-{ viewer_id } \" >
629- { cube_faces_html }
630- { interior_html }
631- { vase_html }
632- { axis_rig_markup }
647+ <div class=\" cube-scene\" id=\" cube-scene-{ viewer_id } \" >
648+ <div id=\" cube-wrapper-{ viewer_id } \" class=\" cube-wrapper\" style=\" --rot-x: { rot_x_rad :.4f} rad; --rot-y: { rot_y_rad :.4f} rad; --zoom: { zoom } ;\" >
649+ <canvas class=\" cube-canvas\" id=\" cube-canvas-{ viewer_id } \" ></canvas>
650+ <div class=\" cube-rotation\" id=\" cube-rotation-{ viewer_id } \" >
651+ { cube_faces_html }
652+ { interior_html }
653+ { vase_html }
654+ { axis_rig_markup }
655+ </div>
656+ <div class=\" cube-drag-surface\" id=\" cube-drag-{ viewer_id } \" ></div>
633657 </div>
634- <div class=\" cube-drag-surface\" id=\" cube-drag-{ viewer_id } \" ></div>
635- </div>
636658
637- <div class=\" axis-label cube-label cube-label-x axis-x-min\" >{ x_meta .get ('min' ,'' )} </div>
638- <div class=\" axis-label cube-label cube-label-x axis-x-max\" >{ x_meta .get ('max' ,'' )} </div>
639- <div class=\" axis-label cube-label cube-label-y axis-y-min\" >{ y_meta .get ('min' ,'' )} </div>
640- <div class=\" axis-label cube-label cube-label-y axis-y-max\" >{ y_meta .get ('max' ,'' )} </div>
641- <div class=\" axis-label cube-label cube-label-time axis-t-min\" >{ time_meta .get ('min' ,'' )} </div>
642- <div class=\" axis-label cube-label cube-label-time axis-t-max\" >{ time_meta .get ('max' ,'' )} </div>
643- <div class=\" axis-label cube-label cube-label-x axis-x-name\" >{ x_meta .get ('name' ,'' )} </div>
644- <div class=\" axis-label cube-label cube-label-y axis-y-name\" >{ y_meta .get ('name' ,'' )} </div>
645- <div class=\" axis-label cube-label cube-label-time axis-t-name\" >{ time_meta .get ('name' ,'' )} </div>
659+ <div class=\" axis-label cube-label cube-label-x axis-x-min\" >{ x_meta .get ('min' ,'' )} </div>
660+ <div class=\" axis-label cube-label cube-label-x axis-x-max\" >{ x_meta .get ('max' ,'' )} </div>
661+ <div class=\" axis-label cube-label cube-label-y axis-y-min\" >{ y_meta .get ('min' ,'' )} </div>
662+ <div class=\" axis-label cube-label cube-label-y axis-y-max\" >{ y_meta .get ('max' ,'' )} </div>
663+ <div class=\" axis-label cube-label cube-label-time axis-t-min\" >{ time_meta .get ('min' ,'' )} </div>
664+ <div class=\" axis-label cube-label cube-label-time axis-t-max\" >{ time_meta .get ('max' ,'' )} </div>
665+ <div class=\" axis-label cube-label cube-label-x axis-x-name\" >{ x_meta .get ('name' ,'' )} </div>
666+ <div class=\" axis-label cube-label cube-label-y axis-y-name\" >{ y_meta .get ('name' ,'' )} </div>
667+ <div class=\" axis-label cube-label cube-label-time axis-t-name\" >{ time_meta .get ('name' ,'' )} </div>
668+ </div>
646669 </div>
647670 </div>
648671 </div>
@@ -660,6 +683,7 @@ def _render_cube_html(
660683 </div>
661684
662685 { axis_rig_meta_block }
686+ { drift_centering_script (viewer_id )}
663687 <script>
664688 (function() {{
665689 const viewerId = "{ viewer_id } ";
0 commit comments