@jungherz-de/glasskit-elements 1.27.0 → 1.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,13 +51,32 @@ function attachDroplet(row, options = {}) {
51
51
  let chosen = null, left = 0, placed = null, liftTimer = 0, lensFrame = 0, edgeFrame = 0;
52
52
  let drag = null, eatClick = false, under = null;
53
53
 
54
+ // The row on screen and its scale there. Rects are viewport pixels, scaled
55
+ // by every transform on an ancestor — an app that zooms in on start, a
56
+ // popover that opens from scale(0.96) — while the drop's lengths are the
57
+ // row's own. So distances on screen are divided by the scale: the drop
58
+ // sits right at rest and while such a transform runs, and nothing needs
59
+ // measuring again when it ends (before 1.28.0 it stayed beside the item).
60
+ // The layout size is the computed one under GlassKit's border-box,
61
+ // unscaled and nearly unrounded, else the offset size, rounded to whole
62
+ // pixels. A difference within that rounding is no transform: the rects
63
+ // are then taken as they are, as before.
64
+ const frame = () => {
65
+ const n = row.getBoundingClientRect(), cs = getComputedStyle(row);
66
+ const exact = cs.boxSizing === 'border-box', tolerance = exact ? 0.05 : 0.5;
67
+ const w = exact ? parseFloat(cs.width) : row.offsetWidth;
68
+ const h = exact ? parseFloat(cs.height) : row.offsetHeight;
69
+ const scale = (onScreen, own) => onScreen > 0 && own > 0 && Math.abs(onScreen - own) > tolerance ? onScreen / own : 1;
70
+ return { n, sx: scale(n.width, w), sy: scale(n.height, h) };
71
+ };
54
72
  // An item's box in the row's padding box; in a row that scrolls, in its
55
73
  // scrolled content, where the drop scrolls along with the items.
56
- const boxOf = it => {
57
- const n = row.getBoundingClientRect(), r = it.getBoundingClientRect();
58
- const l = r.left - n.left - row.clientLeft + row.scrollLeft;
59
- const t = r.top - n.top - row.clientTop + row.scrollTop;
60
- return { left: l, width: r.width, top: t, bottom: row.clientHeight - t - r.height };
74
+ const boxOf = (it, f = frame()) => {
75
+ const r = it.getBoundingClientRect();
76
+ const l = (r.left - f.n.left) / f.sx - row.clientLeft + row.scrollLeft;
77
+ const t = (r.top - f.n.top) / f.sy - row.clientTop + row.scrollTop;
78
+ const height = r.height / f.sy;
79
+ return { left: l, width: r.width / f.sx, top: t, bottom: row.clientHeight - t - height };
61
80
  };
62
81
  const put = (l, width, b) => {
63
82
  left = l;
@@ -68,9 +87,10 @@ function attachDroplet(row, options = {}) {
68
87
  // The usable item nearest a point of the row lights up as under a lens.
69
88
  const lens = centre => {
70
89
  let below = null, best = Infinity;
71
- if (centre != null) for (const it of items()) {
90
+ const f = centre == null ? null : frame();
91
+ if (f) for (const it of items()) {
72
92
  if (!usable(it)) continue;
73
- const b = boxOf(it), d = Math.abs(b.left + b.width / 2 - centre);
93
+ const b = boxOf(it, f), d = Math.abs(b.left + b.width / 2 - centre);
74
94
  if (d < best) { best = d; below = it; }
75
95
  }
76
96
  if (below !== under) {
@@ -135,9 +155,9 @@ function attachDroplet(row, options = {}) {
135
155
  // Dragging: past 8px the drop slides under the finger and grows into a
136
156
  // lens; let go, the item below it is chosen and the drop settles on it.
137
157
  const at = clientX => {
138
- const n = row.getBoundingClientRect();
139
- const x = clientX - n.left - row.clientLeft + row.scrollLeft;
140
- const boxes = items().map(boxOf);
158
+ const f = frame();
159
+ const x = (clientX - f.n.left) / f.sx - row.clientLeft + row.scrollLeft;
160
+ const boxes = items().map(it => boxOf(it, f));
141
161
  const min = Math.min(...boxes.map(b => b.left));
142
162
  const max = Math.max(...boxes.map(b => b.left + b.width)) - drag.width;
143
163
  return Math.min(max, Math.max(min, x - drag.width / 2));