next-chessground 0.9.2 → 0.9.3

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.
Files changed (3) hide show
  1. package/dist/index.es.js +116 -115
  2. package/dist/index.js +116 -115
  3. package/package.json +2 -2
package/dist/index.es.js CHANGED
@@ -2231,10 +2231,21 @@ const distanceSq = (pos1, pos2) => {
2231
2231
  return dx * dx + dy * dy;
2232
2232
  };
2233
2233
  const samePiece = (p1, p2) => p1.role === p2.role && p1.color === p2.color;
2234
- const posToTranslate = bounds => (pos, asWhite) => [(asWhite ? pos[0] : 7 - pos[0]) * bounds.width / 8, (asWhite ? 7 - pos[1] : pos[1]) * bounds.height / 8];
2235
- const translate = (el, pos) => {
2234
+
2235
+ const posToTranslateBase = (pos, asWhite, xFactor, yFactor) => [(asWhite ? pos[0] : 7 - pos[0]) * xFactor, (asWhite ? 7 - pos[1] : pos[1]) * yFactor];
2236
+
2237
+ const posToTranslateAbs = bounds => {
2238
+ const xFactor = bounds.width / 8,
2239
+ yFactor = bounds.height / 8;
2240
+ return (pos, asWhite) => posToTranslateBase(pos, asWhite, xFactor, yFactor);
2241
+ };
2242
+ const posToTranslateRel = (pos, asWhite) => posToTranslateBase(pos, asWhite, 100, 100);
2243
+ const translateAbs = (el, pos) => {
2236
2244
  el.style.transform = `translate(${pos[0]}px,${pos[1]}px)`;
2237
2245
  };
2246
+ const translateRel = (el, percents) => {
2247
+ el.style.transform = `translate(${percents[0]}%,${percents[1]}%)`;
2248
+ };
2238
2249
  const setVisible = (el, v) => {
2239
2250
  el.style.visibility = v ? 'visible' : 'hidden';
2240
2251
  };
@@ -2702,20 +2713,13 @@ function write(pieces) {
2702
2713
  }).join('')).join('/').replace(/1{2,}/g, s => s.length.toString());
2703
2714
  }
2704
2715
 
2705
- function applyAnimation(state, config) {
2706
- if (config.animation) {
2707
- deepMerge(state.animation, config.animation); // no need for such short animations
2708
-
2709
- if ((state.animation.duration || 0) < 70) state.animation.enabled = false;
2710
- }
2711
- }
2712
2716
  function configure(state, config) {
2713
2717
  var _a, _b; // don't merge destinations and autoShapes. Just override.
2714
2718
 
2715
2719
 
2716
2720
  if ((_a = config.movable) === null || _a === void 0 ? void 0 : _a.dests) state.movable.dests = undefined;
2717
2721
  if ((_b = config.drawable) === null || _b === void 0 ? void 0 : _b.autoShapes) state.drawable.autoShapes = [];
2718
- deepMerge(state, config); // if a fen was provided, replace the pieces
2722
+ merge(state, config); // if a fen was provided, replace the pieces
2719
2723
 
2720
2724
  if (config.fen) {
2721
2725
  state.pieces = read(config.fen);
@@ -2729,8 +2733,9 @@ function configure(state, config) {
2729
2733
  // the merge algorithm will incorrectly keep the second square.
2730
2734
  else if (config.lastMove) state.lastMove = config.lastMove; // fix move/premove dests
2731
2735
 
2732
- if (state.selected) setSelected(state, state.selected);
2733
- applyAnimation(state, config);
2736
+ if (state.selected) setSelected(state, state.selected); // no need for such short animations
2737
+
2738
+ if (!state.animation.duration || state.animation.duration < 100) state.animation.enabled = false;
2734
2739
 
2735
2740
  if (!state.movable.rookCastle && state.movable.dests) {
2736
2741
  const rank = state.movable.color === 'white' ? '1' : '8',
@@ -2742,9 +2747,9 @@ function configure(state, config) {
2742
2747
  }
2743
2748
  }
2744
2749
 
2745
- function deepMerge(base, extend) {
2750
+ function merge(base, extend) {
2746
2751
  for (const key in extend) {
2747
- if (isObject(base[key]) && isObject(extend[key])) deepMerge(base[key], extend[key]);else base[key] = extend[key];
2752
+ if (isObject(base[key]) && isObject(extend[key])) merge(base[key], extend[key]);else base[key] = extend[key];
2748
2753
  }
2749
2754
  }
2750
2755
 
@@ -2976,9 +2981,11 @@ function start$1(s, e) {
2976
2981
  const piece = s.pieces.get(orig);
2977
2982
  const previouslySelected = s.selected;
2978
2983
  if (!previouslySelected && s.drawable.enabled && (s.drawable.eraseOnClick || !piece || piece.color !== s.turnColor)) clear(s); // Prevent touch scroll and create no corresponding mouse event, if there
2979
- // is an intent to interact with the board.
2984
+ // is an intent to interact with the board. If no color is movable
2985
+ // (and the board is not for viewing only), touches are likely intended to
2986
+ // select squares.
2980
2987
 
2981
- if (e.cancelable !== false && (!e.touches || s.blockTouchScroll || piece || previouslySelected || pieceCloseTo(s, position))) e.preventDefault();
2988
+ if (e.cancelable !== false && (!e.touches || !s.movable.color || piece || previouslySelected || pieceCloseTo(s, position))) e.preventDefault();
2982
2989
  const hadPremove = !!s.premovable.current;
2983
2990
  const hadPredrop = !!s.predroppable.current;
2984
2991
  s.stats.ctrlKey = e.ctrlKey;
@@ -3001,8 +3008,7 @@ function start$1(s, e) {
3001
3008
  started: s.draggable.autoDistance && s.stats.dragged,
3002
3009
  element,
3003
3010
  previouslySelected,
3004
- originTarget: e.target,
3005
- keyHasChanged: false
3011
+ originTarget: e.target
3006
3012
  };
3007
3013
  element.cgDragging = true;
3008
3014
  element.classList.add('dragging'); // place ghost
@@ -3011,7 +3017,7 @@ function start$1(s, e) {
3011
3017
 
3012
3018
  if (ghost) {
3013
3019
  ghost.className = `ghost ${piece.color} ${piece.role}`;
3014
- translate(ghost, posToTranslate(bounds)(key2pos(orig), whitePov(s)));
3020
+ translateAbs(ghost, posToTranslateAbs(bounds)(key2pos(orig), whitePov(s)));
3015
3021
  setVisible(ghost, true);
3016
3022
  }
3017
3023
 
@@ -3029,7 +3035,7 @@ function pieceCloseTo(s, pos) {
3029
3035
  bounds = s.dom.bounds(),
3030
3036
  radiusSq = Math.pow(bounds.width / 8, 2);
3031
3037
 
3032
- for (const key of s.pieces.keys()) {
3038
+ for (const key in s.pieces) {
3033
3039
  const center = computeSquareCenter(key, asWhite, bounds);
3034
3040
  if (distanceSq(center, pos) <= radiusSq) return true;
3035
3041
  }
@@ -3051,8 +3057,7 @@ function dragNewPiece(s, piece, e, force) {
3051
3057
  element: () => pieceElementByKey(s, key),
3052
3058
  originTarget: e.target,
3053
3059
  newPiece: true,
3054
- force: !!force,
3055
- keyHasChanged: false
3060
+ force: !!force
3056
3061
  };
3057
3062
  processDrag(s);
3058
3063
  }
@@ -3081,8 +3086,7 @@ function processDrag(s) {
3081
3086
  }
3082
3087
 
3083
3088
  const bounds = s.dom.bounds();
3084
- translate(cur.element, [cur.pos[0] - bounds.left - bounds.width / 16, cur.pos[1] - bounds.top - bounds.height / 16]);
3085
- cur.keyHasChanged || (cur.keyHasChanged = cur.orig !== getKeyAtDomPos(cur.pos, whitePov(s), bounds));
3089
+ translateAbs(cur.element, [cur.pos[0] - bounds.left - bounds.width / 16, cur.pos[1] - bounds.top - bounds.height / 16]);
3086
3090
  }
3087
3091
  }
3088
3092
  processDrag(s);
@@ -3125,7 +3129,7 @@ function end$1(s, e) {
3125
3129
  callUserFunction(s.events.change);
3126
3130
  }
3127
3131
 
3128
- if ((cur.orig === cur.previouslySelected || cur.keyHasChanged) && (cur.orig === dest || !dest)) unselect(s);else if (!s.selectable.enabled) unselect(s);
3132
+ if (cur.orig === cur.previouslySelected && (cur.orig === dest || !dest)) unselect(s);else if (!s.selectable.enabled) unselect(s);
3129
3133
  removeDragElements(s);
3130
3134
  s.draggable.current = undefined;
3131
3135
  s.dom.redraw();
@@ -3186,7 +3190,6 @@ function start$2(state, redrawAll) {
3186
3190
  return {
3187
3191
  set(config) {
3188
3192
  if (config.orientation && config.orientation !== state.orientation) toggleOrientation$1();
3189
- applyAnimation(state, config);
3190
3193
  (config.fen ? anim : render)(state => configure(state, config), state);
3191
3194
  },
3192
3195
 
@@ -3295,9 +3298,8 @@ function defaults() {
3295
3298
  autoCastle: true,
3296
3299
  viewOnly: false,
3297
3300
  disableContextMenu: false,
3301
+ resizable: true,
3298
3302
  addPieceZIndex: false,
3299
- addDimensionsCssVars: false,
3300
- blockTouchScroll: false,
3301
3303
  pieceKey: false,
3302
3304
  highlight: {
3303
3305
  lastMove: true,
@@ -3572,15 +3574,22 @@ function renderShape(state, {
3572
3574
  }
3573
3575
 
3574
3576
  function renderCustomSvg(customSvg, pos, bounds) {
3575
- const [x, y] = pos2user(pos, bounds); // Translate to top-left of `orig` square
3577
+ const {
3578
+ width,
3579
+ height
3580
+ } = bounds;
3581
+ const w = width / 8;
3582
+ const h = height / 8;
3583
+ const x = pos[0] * w;
3584
+ const y = (7 - pos[1]) * h; // Translate to top-left of `orig` square
3576
3585
 
3577
3586
  const g = setAttributes(createElement('g'), {
3578
3587
  transform: `translate(${x},${y})`
3579
3588
  }); // Give 100x100 coordinate system to the user for `orig` square
3580
3589
 
3581
3590
  const svg = setAttributes(createElement('svg'), {
3582
- width: 1,
3583
- height: 1,
3591
+ width: w,
3592
+ height: h,
3584
3593
  viewBox: '0 0 100 100'
3585
3594
  });
3586
3595
  g.appendChild(svg);
@@ -3589,9 +3598,9 @@ function renderCustomSvg(customSvg, pos, bounds) {
3589
3598
  }
3590
3599
 
3591
3600
  function renderCircle(brush, pos, current, bounds) {
3592
- const o = pos2user(pos, bounds),
3593
- widths = circleWidth(),
3594
- radius = (bounds.width + bounds.height) / (4 * Math.max(bounds.width, bounds.height));
3601
+ const o = pos2px(pos, bounds),
3602
+ widths = circleWidth(bounds),
3603
+ radius = (bounds.width + bounds.height) / 32;
3595
3604
  return setAttributes(createElement('circle'), {
3596
3605
  stroke: brush.color,
3597
3606
  'stroke-width': widths[current ? 0 : 1],
@@ -3604,9 +3613,9 @@ function renderCircle(brush, pos, current, bounds) {
3604
3613
  }
3605
3614
 
3606
3615
  function renderArrow(brush, orig, dest, current, shorten, bounds) {
3607
- const m = arrowMargin(shorten && !current),
3608
- a = pos2user(orig, bounds),
3609
- b = pos2user(dest, bounds),
3616
+ const m = arrowMargin(bounds, shorten && !current),
3617
+ a = pos2px(orig, bounds),
3618
+ b = pos2px(dest, bounds),
3610
3619
  dx = b[0] - a[0],
3611
3620
  dy = b[1] - a[1],
3612
3621
  angle = Math.atan2(dy, dx),
@@ -3614,7 +3623,7 @@ function renderArrow(brush, orig, dest, current, shorten, bounds) {
3614
3623
  yo = Math.sin(angle) * m;
3615
3624
  return setAttributes(createElement('line'), {
3616
3625
  stroke: brush.color,
3617
- 'stroke-width': lineWidth(brush, current),
3626
+ 'stroke-width': lineWidth(brush, current, bounds),
3618
3627
  'stroke-linecap': 'round',
3619
3628
  'marker-end': 'url(#arrowhead-' + brush.key + ')',
3620
3629
  opacity: opacity(brush, current),
@@ -3626,17 +3635,16 @@ function renderArrow(brush, orig, dest, current, shorten, bounds) {
3626
3635
  }
3627
3636
 
3628
3637
  function renderPiece(baseUrl, pos, piece, bounds) {
3629
- const o = pos2user(pos, bounds),
3638
+ const o = pos2px(pos, bounds),
3639
+ size = bounds.width / 8 * (piece.scale || 1),
3630
3640
  name = piece.color[0] + (piece.role === 'knight' ? 'n' : piece.role[0]).toUpperCase();
3631
3641
  return setAttributes(createElement('image'), {
3632
3642
  className: `${piece.role} ${piece.color}`,
3633
- x: o[0] - 0.5,
3634
- y: o[1] - 0.5,
3635
- width: 1,
3636
- height: 1,
3637
- href: baseUrl + name + '.svg',
3638
- transform: `scale(${piece.scale || 1})`,
3639
- 'transform-origin': `${o[0]} ${o[1]}`
3643
+ x: o[0] - size / 2,
3644
+ y: o[1] - size / 2,
3645
+ width: size,
3646
+ height: size,
3647
+ href: baseUrl + name + '.svg'
3640
3648
  });
3641
3649
  }
3642
3650
 
@@ -3676,40 +3684,40 @@ function makeCustomBrush(base, modifiers) {
3676
3684
  };
3677
3685
  }
3678
3686
 
3679
- function circleWidth() {
3680
- return [3 / 64, 4 / 64];
3687
+ function circleWidth(bounds) {
3688
+ const base = bounds.width / 512;
3689
+ return [3 * base, 4 * base];
3681
3690
  }
3682
3691
 
3683
- function lineWidth(brush, current) {
3684
- return (brush.lineWidth || 10) * (current ? 0.85 : 1) / 64;
3692
+ function lineWidth(brush, current, bounds) {
3693
+ return (brush.lineWidth || 10) * (current ? 0.85 : 1) / 512 * bounds.width;
3685
3694
  }
3686
3695
 
3687
3696
  function opacity(brush, current) {
3688
3697
  return (brush.opacity || 1) * (current ? 0.9 : 1);
3689
3698
  }
3690
3699
 
3691
- function arrowMargin(shorten) {
3692
- return (shorten ? 20 : 10) / 64;
3700
+ function arrowMargin(bounds, shorten) {
3701
+ return (shorten ? 20 : 10) / 512 * bounds.width;
3693
3702
  }
3694
3703
 
3695
- function pos2user(pos, bounds) {
3696
- const xScale = Math.min(1, bounds.width / bounds.height);
3697
- const yScale = Math.min(1, bounds.height / bounds.width);
3698
- return [(pos[0] - 3.5) * xScale, (3.5 - pos[1]) * yScale];
3704
+ function pos2px(pos, bounds) {
3705
+ return [(pos[0] + 0.5) * bounds.width / 8, (7.5 - pos[1]) * bounds.height / 8];
3699
3706
  }
3700
3707
 
3701
- function renderWrap(element, s) {
3708
+ function renderWrap(element, s, relative) {
3702
3709
  // .cg-wrap (element passed to Chessground)
3703
- // cg-container
3704
- // cg-board
3705
- // svg.cg-shapes
3706
- // defs
3707
- // g
3708
- // svg.cg-custom-svgs
3709
- // g
3710
- // coords.ranks
3711
- // coords.files
3712
- // piece.ghost
3710
+ // cg-helper (12.5%, display: table)
3711
+ // cg-container (800%)
3712
+ // cg-board
3713
+ // svg.cg-shapes
3714
+ // defs
3715
+ // g
3716
+ // svg.cg-custom-svgs
3717
+ // g
3718
+ // coords.ranks
3719
+ // coords.files
3720
+ // piece.ghost
3713
3721
  element.innerHTML = ''; // ensure the cg-wrap class is set
3714
3722
  // so bounds calculation can use the CSS width/height values
3715
3723
  // add that class yourself to the element before calling chessground
@@ -3720,25 +3728,23 @@ function renderWrap(element, s) {
3720
3728
  for (const c of colors) element.classList.toggle('orientation-' + c, s.orientation === c);
3721
3729
 
3722
3730
  element.classList.toggle('manipulable', !s.viewOnly);
3731
+ const helper = createEl('cg-helper');
3732
+ element.appendChild(helper);
3723
3733
  const container = createEl('cg-container');
3724
- element.appendChild(container);
3734
+ helper.appendChild(container);
3725
3735
  const board = createEl('cg-board');
3726
3736
  container.appendChild(board);
3727
3737
  let svg;
3728
3738
  let customSvg;
3729
3739
 
3730
- if (s.drawable.visible) {
3740
+ if (s.drawable.visible && !relative) {
3731
3741
  svg = setAttributes(createElement('svg'), {
3732
- class: 'cg-shapes',
3733
- viewBox: '-4 -4 8 8',
3734
- preserveAspectRatio: 'xMidYMid slice'
3742
+ class: 'cg-shapes'
3735
3743
  });
3736
3744
  svg.appendChild(createElement('defs'));
3737
3745
  svg.appendChild(createElement('g'));
3738
3746
  customSvg = setAttributes(createElement('svg'), {
3739
- class: 'cg-custom-svgs',
3740
- viewBox: '-3.5 -3.5 8 8',
3741
- preserveAspectRatio: 'xMidYMid slice'
3747
+ class: 'cg-custom-svgs'
3742
3748
  });
3743
3749
  customSvg.appendChild(createElement('g'));
3744
3750
  container.appendChild(svg);
@@ -3753,7 +3759,7 @@ function renderWrap(element, s) {
3753
3759
 
3754
3760
  let ghost;
3755
3761
 
3756
- if (s.draggable.showGhost) {
3762
+ if (s.draggable.showGhost && !relative) {
3757
3763
  ghost = createEl('piece', 'ghost');
3758
3764
  setVisible(ghost, false);
3759
3765
  container.appendChild(ghost);
@@ -3762,7 +3768,6 @@ function renderWrap(element, s) {
3762
3768
  return {
3763
3769
  board,
3764
3770
  container,
3765
- wrap: element,
3766
3771
  ghost,
3767
3772
  svg,
3768
3773
  customSvg
@@ -3798,9 +3803,14 @@ function drop(s, e) {
3798
3803
  s.dom.redraw();
3799
3804
  }
3800
3805
 
3801
- function bindBoard(s, onResize) {
3806
+ function bindBoard(s, boundsUpdated) {
3802
3807
  const boardEl = s.dom.elements.board;
3803
- if ('ResizeObserver' in window) new ResizeObserver(onResize).observe(s.dom.elements.wrap);
3808
+
3809
+ if (!s.dom.relative && s.resizable && 'ResizeObserver' in window) {
3810
+ const observer = new window['ResizeObserver'](boundsUpdated);
3811
+ observer.observe(boardEl);
3812
+ }
3813
+
3804
3814
  if (s.viewOnly) return; // Cannot be passive, because we prevent touch scrolling and dragging of
3805
3815
  // selected elements.
3806
3816
 
@@ -3817,11 +3827,13 @@ function bindBoard(s, onResize) {
3817
3827
  }
3818
3828
  } // returns the unbind function
3819
3829
 
3820
- function bindDocument(s, onResize) {
3830
+ function bindDocument(s, boundsUpdated) {
3821
3831
  const unbinds = []; // Old versions of Edge and Safari do not support ResizeObserver. Send
3822
3832
  // chessground.resize if a user action has changed the bounds of the board.
3823
3833
 
3824
- if (!('ResizeObserver' in window)) unbinds.push(unbindable(document.body, 'chessground.resize', onResize));
3834
+ if (!s.dom.relative && s.resizable && !('ResizeObserver' in window)) {
3835
+ unbinds.push(unbindable(document.body, 'chessground.resize', boundsUpdated));
3836
+ }
3825
3837
 
3826
3838
  if (!s.viewOnly) {
3827
3839
  const onmove = dragOrDraw(s, move$1, move);
@@ -3872,7 +3884,8 @@ function dragOrDraw(s, withDrag, withDraw) {
3872
3884
 
3873
3885
  function render$1(s) {
3874
3886
  const asWhite = whitePov(s),
3875
- posToTranslate$1 = posToTranslate(s.dom.bounds()),
3887
+ posToTranslate = s.dom.relative ? posToTranslateRel : posToTranslateAbs(s.dom.bounds()),
3888
+ translate = s.dom.relative ? translateRel : translateAbs,
3876
3889
  boardEl = s.dom.elements.board,
3877
3890
  pieces = s.pieces,
3878
3891
  curAnim = s.animation.current,
@@ -3900,7 +3913,7 @@ function render$1(s) {
3900
3913
 
3901
3914
  if (el.cgDragging && (!curDrag || curDrag.orig !== k)) {
3902
3915
  el.classList.remove('dragging');
3903
- translate(el, posToTranslate$1(key2pos(k), asWhite));
3916
+ translate(el, posToTranslate(key2pos(k), asWhite));
3904
3917
  el.cgDragging = false;
3905
3918
  } // remove fading class if it still remains
3906
3919
 
@@ -3919,11 +3932,11 @@ function render$1(s) {
3919
3932
  pos[0] += anim[2];
3920
3933
  pos[1] += anim[3];
3921
3934
  el.classList.add('anim');
3922
- translate(el, posToTranslate$1(pos, asWhite));
3935
+ translate(el, posToTranslate(pos, asWhite));
3923
3936
  } else if (el.cgAnimating) {
3924
3937
  el.cgAnimating = false;
3925
3938
  el.classList.remove('anim');
3926
- translate(el, posToTranslate$1(key2pos(k), asWhite));
3939
+ translate(el, posToTranslate(key2pos(k), asWhite));
3927
3940
  if (s.addPieceZIndex) el.style.zIndex = posZIndex(key2pos(k), asWhite);
3928
3941
  } // same piece: flag as same
3929
3942
 
@@ -3957,7 +3970,7 @@ function render$1(s) {
3957
3970
  if (!sameSquares.has(sk)) {
3958
3971
  sMvdset = movedSquares.get(className);
3959
3972
  sMvd = sMvdset && sMvdset.pop();
3960
- const translation = posToTranslate$1(key2pos(sk), asWhite);
3973
+ const translation = posToTranslate(key2pos(sk), asWhite);
3961
3974
 
3962
3975
  if (sMvd) {
3963
3976
  sMvd.cgKey = sk;
@@ -3999,7 +4012,7 @@ function render$1(s) {
3999
4012
  pos[1] += anim[3];
4000
4013
  }
4001
4014
 
4002
- translate(pMvd, posToTranslate$1(pos, asWhite));
4015
+ translate(pMvd, posToTranslate(pos, asWhite));
4003
4016
  } // no piece in moved obj: insert the new piece
4004
4017
  // assumes the new piece is not being dragged
4005
4018
  else {
@@ -4015,7 +4028,7 @@ function render$1(s) {
4015
4028
  pos[1] += anim[3];
4016
4029
  }
4017
4030
 
4018
- translate(pieceNode, posToTranslate$1(pos, asWhite));
4031
+ translate(pieceNode, posToTranslate(pos, asWhite));
4019
4032
  if (s.addPieceZIndex) pieceNode.style.zIndex = posZIndex(pos, asWhite);
4020
4033
  boardEl.appendChild(pieceNode);
4021
4034
  }
@@ -4027,34 +4040,20 @@ function render$1(s) {
4027
4040
 
4028
4041
  for (const nodes of movedSquares.values()) removeNodes(s, nodes);
4029
4042
  }
4030
- function renderResized(s) {
4043
+ function updateBounds(s) {
4044
+ if (s.dom.relative) return;
4031
4045
  const asWhite = whitePov(s),
4032
- posToTranslate$1 = posToTranslate(s.dom.bounds());
4046
+ posToTranslate = posToTranslateAbs(s.dom.bounds());
4033
4047
  let el = s.dom.elements.board.firstChild;
4034
4048
 
4035
4049
  while (el) {
4036
4050
  if (isPieceNode(el) && !el.cgAnimating || isSquareNode(el)) {
4037
- translate(el, posToTranslate$1(key2pos(el.cgKey), asWhite));
4051
+ translateAbs(el, posToTranslate(key2pos(el.cgKey), asWhite));
4038
4052
  }
4039
4053
 
4040
4054
  el = el.nextSibling;
4041
4055
  }
4042
4056
  }
4043
- function updateBounds(s) {
4044
- const bounds = s.dom.elements.wrap.getBoundingClientRect();
4045
- const container = s.dom.elements.container;
4046
- const ratio = bounds.height / bounds.width;
4047
- const width = Math.floor(bounds.width * window.devicePixelRatio / 8) * 8 / window.devicePixelRatio;
4048
- const height = width * ratio;
4049
- container.style.width = width + 'px';
4050
- container.style.height = height + 'px';
4051
- s.dom.bounds.clear();
4052
-
4053
- if (s.addDimensionsCssVars) {
4054
- document.documentElement.style.setProperty('--cg-width', width + 'px');
4055
- document.documentElement.style.setProperty('--cg-height', height + 'px');
4056
- }
4057
- }
4058
4057
 
4059
4058
  function isPieceNode(el) {
4060
4059
  return el.tagName === 'PIECE';
@@ -4069,8 +4068,8 @@ function removeNodes(s, nodes) {
4069
4068
  }
4070
4069
 
4071
4070
  function posZIndex(pos, asWhite) {
4072
- let z = 3 + pos[1] * 8 + (7 - pos[0]);
4073
- if (asWhite) z = 69 - z;
4071
+ let z = 2 + pos[1] * 8 + (7 - pos[0]);
4072
+ if (asWhite) z = 67 - z;
4074
4073
  return z + '';
4075
4074
  }
4076
4075
 
@@ -4127,15 +4126,17 @@ function Chessground(element, config) {
4127
4126
  const prevUnbind = 'dom' in maybeState ? maybeState.dom.unbind : undefined; // compute bounds from existing board element if possible
4128
4127
  // this allows non-square boards from CSS to be handled (for 3D)
4129
4128
 
4130
- const elements = renderWrap(element, maybeState),
4129
+ const relative = maybeState.viewOnly && !maybeState.drawable.visible,
4130
+ elements = renderWrap(element, maybeState, relative),
4131
4131
  bounds = memo(() => elements.board.getBoundingClientRect()),
4132
4132
  redrawNow = skipSvg => {
4133
4133
  render$1(state);
4134
4134
  if (!skipSvg && elements.svg) renderSvg(state, elements.svg, elements.customSvg);
4135
4135
  },
4136
- onResize = () => {
4136
+ boundsUpdated = () => {
4137
+ bounds.clear();
4137
4138
  updateBounds(state);
4138
- renderResized(state);
4139
+ if (elements.svg) renderSvg(state, elements.svg, elements.customSvg);
4139
4140
  };
4140
4141
 
4141
4142
  const state = maybeState;
@@ -4144,13 +4145,13 @@ function Chessground(element, config) {
4144
4145
  bounds,
4145
4146
  redraw: debounceRedraw(redrawNow),
4146
4147
  redrawNow,
4147
- unbind: prevUnbind
4148
+ unbind: prevUnbind,
4149
+ relative
4148
4150
  };
4149
4151
  state.drawable.prevSvgHash = '';
4150
- updateBounds(state);
4151
4152
  redrawNow(false);
4152
- bindBoard(state, onResize);
4153
- if (!prevUnbind) state.dom.unbind = bindDocument(state, onResize);
4153
+ bindBoard(state, boundsUpdated);
4154
+ if (!prevUnbind) state.dom.unbind = bindDocument(state, boundsUpdated);
4154
4155
  state.events.insert && state.events.insert(elements);
4155
4156
  return state;
4156
4157
  }
package/dist/index.js CHANGED
@@ -2240,10 +2240,21 @@ const distanceSq = (pos1, pos2) => {
2240
2240
  return dx * dx + dy * dy;
2241
2241
  };
2242
2242
  const samePiece = (p1, p2) => p1.role === p2.role && p1.color === p2.color;
2243
- const posToTranslate = bounds => (pos, asWhite) => [(asWhite ? pos[0] : 7 - pos[0]) * bounds.width / 8, (asWhite ? 7 - pos[1] : pos[1]) * bounds.height / 8];
2244
- const translate = (el, pos) => {
2243
+
2244
+ const posToTranslateBase = (pos, asWhite, xFactor, yFactor) => [(asWhite ? pos[0] : 7 - pos[0]) * xFactor, (asWhite ? 7 - pos[1] : pos[1]) * yFactor];
2245
+
2246
+ const posToTranslateAbs = bounds => {
2247
+ const xFactor = bounds.width / 8,
2248
+ yFactor = bounds.height / 8;
2249
+ return (pos, asWhite) => posToTranslateBase(pos, asWhite, xFactor, yFactor);
2250
+ };
2251
+ const posToTranslateRel = (pos, asWhite) => posToTranslateBase(pos, asWhite, 100, 100);
2252
+ const translateAbs = (el, pos) => {
2245
2253
  el.style.transform = `translate(${pos[0]}px,${pos[1]}px)`;
2246
2254
  };
2255
+ const translateRel = (el, percents) => {
2256
+ el.style.transform = `translate(${percents[0]}%,${percents[1]}%)`;
2257
+ };
2247
2258
  const setVisible = (el, v) => {
2248
2259
  el.style.visibility = v ? 'visible' : 'hidden';
2249
2260
  };
@@ -2711,20 +2722,13 @@ function write(pieces) {
2711
2722
  }).join('')).join('/').replace(/1{2,}/g, s => s.length.toString());
2712
2723
  }
2713
2724
 
2714
- function applyAnimation(state, config) {
2715
- if (config.animation) {
2716
- deepMerge(state.animation, config.animation); // no need for such short animations
2717
-
2718
- if ((state.animation.duration || 0) < 70) state.animation.enabled = false;
2719
- }
2720
- }
2721
2725
  function configure(state, config) {
2722
2726
  var _a, _b; // don't merge destinations and autoShapes. Just override.
2723
2727
 
2724
2728
 
2725
2729
  if ((_a = config.movable) === null || _a === void 0 ? void 0 : _a.dests) state.movable.dests = undefined;
2726
2730
  if ((_b = config.drawable) === null || _b === void 0 ? void 0 : _b.autoShapes) state.drawable.autoShapes = [];
2727
- deepMerge(state, config); // if a fen was provided, replace the pieces
2731
+ merge(state, config); // if a fen was provided, replace the pieces
2728
2732
 
2729
2733
  if (config.fen) {
2730
2734
  state.pieces = read(config.fen);
@@ -2738,8 +2742,9 @@ function configure(state, config) {
2738
2742
  // the merge algorithm will incorrectly keep the second square.
2739
2743
  else if (config.lastMove) state.lastMove = config.lastMove; // fix move/premove dests
2740
2744
 
2741
- if (state.selected) setSelected(state, state.selected);
2742
- applyAnimation(state, config);
2745
+ if (state.selected) setSelected(state, state.selected); // no need for such short animations
2746
+
2747
+ if (!state.animation.duration || state.animation.duration < 100) state.animation.enabled = false;
2743
2748
 
2744
2749
  if (!state.movable.rookCastle && state.movable.dests) {
2745
2750
  const rank = state.movable.color === 'white' ? '1' : '8',
@@ -2751,9 +2756,9 @@ function configure(state, config) {
2751
2756
  }
2752
2757
  }
2753
2758
 
2754
- function deepMerge(base, extend) {
2759
+ function merge(base, extend) {
2755
2760
  for (const key in extend) {
2756
- if (isObject(base[key]) && isObject(extend[key])) deepMerge(base[key], extend[key]);else base[key] = extend[key];
2761
+ if (isObject(base[key]) && isObject(extend[key])) merge(base[key], extend[key]);else base[key] = extend[key];
2757
2762
  }
2758
2763
  }
2759
2764
 
@@ -2985,9 +2990,11 @@ function start$1(s, e) {
2985
2990
  const piece = s.pieces.get(orig);
2986
2991
  const previouslySelected = s.selected;
2987
2992
  if (!previouslySelected && s.drawable.enabled && (s.drawable.eraseOnClick || !piece || piece.color !== s.turnColor)) clear(s); // Prevent touch scroll and create no corresponding mouse event, if there
2988
- // is an intent to interact with the board.
2993
+ // is an intent to interact with the board. If no color is movable
2994
+ // (and the board is not for viewing only), touches are likely intended to
2995
+ // select squares.
2989
2996
 
2990
- if (e.cancelable !== false && (!e.touches || s.blockTouchScroll || piece || previouslySelected || pieceCloseTo(s, position))) e.preventDefault();
2997
+ if (e.cancelable !== false && (!e.touches || !s.movable.color || piece || previouslySelected || pieceCloseTo(s, position))) e.preventDefault();
2991
2998
  const hadPremove = !!s.premovable.current;
2992
2999
  const hadPredrop = !!s.predroppable.current;
2993
3000
  s.stats.ctrlKey = e.ctrlKey;
@@ -3010,8 +3017,7 @@ function start$1(s, e) {
3010
3017
  started: s.draggable.autoDistance && s.stats.dragged,
3011
3018
  element,
3012
3019
  previouslySelected,
3013
- originTarget: e.target,
3014
- keyHasChanged: false
3020
+ originTarget: e.target
3015
3021
  };
3016
3022
  element.cgDragging = true;
3017
3023
  element.classList.add('dragging'); // place ghost
@@ -3020,7 +3026,7 @@ function start$1(s, e) {
3020
3026
 
3021
3027
  if (ghost) {
3022
3028
  ghost.className = `ghost ${piece.color} ${piece.role}`;
3023
- translate(ghost, posToTranslate(bounds)(key2pos(orig), whitePov(s)));
3029
+ translateAbs(ghost, posToTranslateAbs(bounds)(key2pos(orig), whitePov(s)));
3024
3030
  setVisible(ghost, true);
3025
3031
  }
3026
3032
 
@@ -3038,7 +3044,7 @@ function pieceCloseTo(s, pos) {
3038
3044
  bounds = s.dom.bounds(),
3039
3045
  radiusSq = Math.pow(bounds.width / 8, 2);
3040
3046
 
3041
- for (const key of s.pieces.keys()) {
3047
+ for (const key in s.pieces) {
3042
3048
  const center = computeSquareCenter(key, asWhite, bounds);
3043
3049
  if (distanceSq(center, pos) <= radiusSq) return true;
3044
3050
  }
@@ -3060,8 +3066,7 @@ function dragNewPiece(s, piece, e, force) {
3060
3066
  element: () => pieceElementByKey(s, key),
3061
3067
  originTarget: e.target,
3062
3068
  newPiece: true,
3063
- force: !!force,
3064
- keyHasChanged: false
3069
+ force: !!force
3065
3070
  };
3066
3071
  processDrag(s);
3067
3072
  }
@@ -3090,8 +3095,7 @@ function processDrag(s) {
3090
3095
  }
3091
3096
 
3092
3097
  const bounds = s.dom.bounds();
3093
- translate(cur.element, [cur.pos[0] - bounds.left - bounds.width / 16, cur.pos[1] - bounds.top - bounds.height / 16]);
3094
- cur.keyHasChanged || (cur.keyHasChanged = cur.orig !== getKeyAtDomPos(cur.pos, whitePov(s), bounds));
3098
+ translateAbs(cur.element, [cur.pos[0] - bounds.left - bounds.width / 16, cur.pos[1] - bounds.top - bounds.height / 16]);
3095
3099
  }
3096
3100
  }
3097
3101
  processDrag(s);
@@ -3134,7 +3138,7 @@ function end$1(s, e) {
3134
3138
  callUserFunction(s.events.change);
3135
3139
  }
3136
3140
 
3137
- if ((cur.orig === cur.previouslySelected || cur.keyHasChanged) && (cur.orig === dest || !dest)) unselect(s);else if (!s.selectable.enabled) unselect(s);
3141
+ if (cur.orig === cur.previouslySelected && (cur.orig === dest || !dest)) unselect(s);else if (!s.selectable.enabled) unselect(s);
3138
3142
  removeDragElements(s);
3139
3143
  s.draggable.current = undefined;
3140
3144
  s.dom.redraw();
@@ -3195,7 +3199,6 @@ function start$2(state, redrawAll) {
3195
3199
  return {
3196
3200
  set(config) {
3197
3201
  if (config.orientation && config.orientation !== state.orientation) toggleOrientation$1();
3198
- applyAnimation(state, config);
3199
3202
  (config.fen ? anim : render)(state => configure(state, config), state);
3200
3203
  },
3201
3204
 
@@ -3304,9 +3307,8 @@ function defaults() {
3304
3307
  autoCastle: true,
3305
3308
  viewOnly: false,
3306
3309
  disableContextMenu: false,
3310
+ resizable: true,
3307
3311
  addPieceZIndex: false,
3308
- addDimensionsCssVars: false,
3309
- blockTouchScroll: false,
3310
3312
  pieceKey: false,
3311
3313
  highlight: {
3312
3314
  lastMove: true,
@@ -3581,15 +3583,22 @@ function renderShape(state, {
3581
3583
  }
3582
3584
 
3583
3585
  function renderCustomSvg(customSvg, pos, bounds) {
3584
- const [x, y] = pos2user(pos, bounds); // Translate to top-left of `orig` square
3586
+ const {
3587
+ width,
3588
+ height
3589
+ } = bounds;
3590
+ const w = width / 8;
3591
+ const h = height / 8;
3592
+ const x = pos[0] * w;
3593
+ const y = (7 - pos[1]) * h; // Translate to top-left of `orig` square
3585
3594
 
3586
3595
  const g = setAttributes(createElement('g'), {
3587
3596
  transform: `translate(${x},${y})`
3588
3597
  }); // Give 100x100 coordinate system to the user for `orig` square
3589
3598
 
3590
3599
  const svg = setAttributes(createElement('svg'), {
3591
- width: 1,
3592
- height: 1,
3600
+ width: w,
3601
+ height: h,
3593
3602
  viewBox: '0 0 100 100'
3594
3603
  });
3595
3604
  g.appendChild(svg);
@@ -3598,9 +3607,9 @@ function renderCustomSvg(customSvg, pos, bounds) {
3598
3607
  }
3599
3608
 
3600
3609
  function renderCircle(brush, pos, current, bounds) {
3601
- const o = pos2user(pos, bounds),
3602
- widths = circleWidth(),
3603
- radius = (bounds.width + bounds.height) / (4 * Math.max(bounds.width, bounds.height));
3610
+ const o = pos2px(pos, bounds),
3611
+ widths = circleWidth(bounds),
3612
+ radius = (bounds.width + bounds.height) / 32;
3604
3613
  return setAttributes(createElement('circle'), {
3605
3614
  stroke: brush.color,
3606
3615
  'stroke-width': widths[current ? 0 : 1],
@@ -3613,9 +3622,9 @@ function renderCircle(brush, pos, current, bounds) {
3613
3622
  }
3614
3623
 
3615
3624
  function renderArrow(brush, orig, dest, current, shorten, bounds) {
3616
- const m = arrowMargin(shorten && !current),
3617
- a = pos2user(orig, bounds),
3618
- b = pos2user(dest, bounds),
3625
+ const m = arrowMargin(bounds, shorten && !current),
3626
+ a = pos2px(orig, bounds),
3627
+ b = pos2px(dest, bounds),
3619
3628
  dx = b[0] - a[0],
3620
3629
  dy = b[1] - a[1],
3621
3630
  angle = Math.atan2(dy, dx),
@@ -3623,7 +3632,7 @@ function renderArrow(brush, orig, dest, current, shorten, bounds) {
3623
3632
  yo = Math.sin(angle) * m;
3624
3633
  return setAttributes(createElement('line'), {
3625
3634
  stroke: brush.color,
3626
- 'stroke-width': lineWidth(brush, current),
3635
+ 'stroke-width': lineWidth(brush, current, bounds),
3627
3636
  'stroke-linecap': 'round',
3628
3637
  'marker-end': 'url(#arrowhead-' + brush.key + ')',
3629
3638
  opacity: opacity(brush, current),
@@ -3635,17 +3644,16 @@ function renderArrow(brush, orig, dest, current, shorten, bounds) {
3635
3644
  }
3636
3645
 
3637
3646
  function renderPiece(baseUrl, pos, piece, bounds) {
3638
- const o = pos2user(pos, bounds),
3647
+ const o = pos2px(pos, bounds),
3648
+ size = bounds.width / 8 * (piece.scale || 1),
3639
3649
  name = piece.color[0] + (piece.role === 'knight' ? 'n' : piece.role[0]).toUpperCase();
3640
3650
  return setAttributes(createElement('image'), {
3641
3651
  className: `${piece.role} ${piece.color}`,
3642
- x: o[0] - 0.5,
3643
- y: o[1] - 0.5,
3644
- width: 1,
3645
- height: 1,
3646
- href: baseUrl + name + '.svg',
3647
- transform: `scale(${piece.scale || 1})`,
3648
- 'transform-origin': `${o[0]} ${o[1]}`
3652
+ x: o[0] - size / 2,
3653
+ y: o[1] - size / 2,
3654
+ width: size,
3655
+ height: size,
3656
+ href: baseUrl + name + '.svg'
3649
3657
  });
3650
3658
  }
3651
3659
 
@@ -3685,40 +3693,40 @@ function makeCustomBrush(base, modifiers) {
3685
3693
  };
3686
3694
  }
3687
3695
 
3688
- function circleWidth() {
3689
- return [3 / 64, 4 / 64];
3696
+ function circleWidth(bounds) {
3697
+ const base = bounds.width / 512;
3698
+ return [3 * base, 4 * base];
3690
3699
  }
3691
3700
 
3692
- function lineWidth(brush, current) {
3693
- return (brush.lineWidth || 10) * (current ? 0.85 : 1) / 64;
3701
+ function lineWidth(brush, current, bounds) {
3702
+ return (brush.lineWidth || 10) * (current ? 0.85 : 1) / 512 * bounds.width;
3694
3703
  }
3695
3704
 
3696
3705
  function opacity(brush, current) {
3697
3706
  return (brush.opacity || 1) * (current ? 0.9 : 1);
3698
3707
  }
3699
3708
 
3700
- function arrowMargin(shorten) {
3701
- return (shorten ? 20 : 10) / 64;
3709
+ function arrowMargin(bounds, shorten) {
3710
+ return (shorten ? 20 : 10) / 512 * bounds.width;
3702
3711
  }
3703
3712
 
3704
- function pos2user(pos, bounds) {
3705
- const xScale = Math.min(1, bounds.width / bounds.height);
3706
- const yScale = Math.min(1, bounds.height / bounds.width);
3707
- return [(pos[0] - 3.5) * xScale, (3.5 - pos[1]) * yScale];
3713
+ function pos2px(pos, bounds) {
3714
+ return [(pos[0] + 0.5) * bounds.width / 8, (7.5 - pos[1]) * bounds.height / 8];
3708
3715
  }
3709
3716
 
3710
- function renderWrap(element, s) {
3717
+ function renderWrap(element, s, relative) {
3711
3718
  // .cg-wrap (element passed to Chessground)
3712
- // cg-container
3713
- // cg-board
3714
- // svg.cg-shapes
3715
- // defs
3716
- // g
3717
- // svg.cg-custom-svgs
3718
- // g
3719
- // coords.ranks
3720
- // coords.files
3721
- // piece.ghost
3719
+ // cg-helper (12.5%, display: table)
3720
+ // cg-container (800%)
3721
+ // cg-board
3722
+ // svg.cg-shapes
3723
+ // defs
3724
+ // g
3725
+ // svg.cg-custom-svgs
3726
+ // g
3727
+ // coords.ranks
3728
+ // coords.files
3729
+ // piece.ghost
3722
3730
  element.innerHTML = ''; // ensure the cg-wrap class is set
3723
3731
  // so bounds calculation can use the CSS width/height values
3724
3732
  // add that class yourself to the element before calling chessground
@@ -3729,25 +3737,23 @@ function renderWrap(element, s) {
3729
3737
  for (const c of colors) element.classList.toggle('orientation-' + c, s.orientation === c);
3730
3738
 
3731
3739
  element.classList.toggle('manipulable', !s.viewOnly);
3740
+ const helper = createEl('cg-helper');
3741
+ element.appendChild(helper);
3732
3742
  const container = createEl('cg-container');
3733
- element.appendChild(container);
3743
+ helper.appendChild(container);
3734
3744
  const board = createEl('cg-board');
3735
3745
  container.appendChild(board);
3736
3746
  let svg;
3737
3747
  let customSvg;
3738
3748
 
3739
- if (s.drawable.visible) {
3749
+ if (s.drawable.visible && !relative) {
3740
3750
  svg = setAttributes(createElement('svg'), {
3741
- class: 'cg-shapes',
3742
- viewBox: '-4 -4 8 8',
3743
- preserveAspectRatio: 'xMidYMid slice'
3751
+ class: 'cg-shapes'
3744
3752
  });
3745
3753
  svg.appendChild(createElement('defs'));
3746
3754
  svg.appendChild(createElement('g'));
3747
3755
  customSvg = setAttributes(createElement('svg'), {
3748
- class: 'cg-custom-svgs',
3749
- viewBox: '-3.5 -3.5 8 8',
3750
- preserveAspectRatio: 'xMidYMid slice'
3756
+ class: 'cg-custom-svgs'
3751
3757
  });
3752
3758
  customSvg.appendChild(createElement('g'));
3753
3759
  container.appendChild(svg);
@@ -3762,7 +3768,7 @@ function renderWrap(element, s) {
3762
3768
 
3763
3769
  let ghost;
3764
3770
 
3765
- if (s.draggable.showGhost) {
3771
+ if (s.draggable.showGhost && !relative) {
3766
3772
  ghost = createEl('piece', 'ghost');
3767
3773
  setVisible(ghost, false);
3768
3774
  container.appendChild(ghost);
@@ -3771,7 +3777,6 @@ function renderWrap(element, s) {
3771
3777
  return {
3772
3778
  board,
3773
3779
  container,
3774
- wrap: element,
3775
3780
  ghost,
3776
3781
  svg,
3777
3782
  customSvg
@@ -3807,9 +3812,14 @@ function drop(s, e) {
3807
3812
  s.dom.redraw();
3808
3813
  }
3809
3814
 
3810
- function bindBoard(s, onResize) {
3815
+ function bindBoard(s, boundsUpdated) {
3811
3816
  const boardEl = s.dom.elements.board;
3812
- if ('ResizeObserver' in window) new ResizeObserver(onResize).observe(s.dom.elements.wrap);
3817
+
3818
+ if (!s.dom.relative && s.resizable && 'ResizeObserver' in window) {
3819
+ const observer = new window['ResizeObserver'](boundsUpdated);
3820
+ observer.observe(boardEl);
3821
+ }
3822
+
3813
3823
  if (s.viewOnly) return; // Cannot be passive, because we prevent touch scrolling and dragging of
3814
3824
  // selected elements.
3815
3825
 
@@ -3826,11 +3836,13 @@ function bindBoard(s, onResize) {
3826
3836
  }
3827
3837
  } // returns the unbind function
3828
3838
 
3829
- function bindDocument(s, onResize) {
3839
+ function bindDocument(s, boundsUpdated) {
3830
3840
  const unbinds = []; // Old versions of Edge and Safari do not support ResizeObserver. Send
3831
3841
  // chessground.resize if a user action has changed the bounds of the board.
3832
3842
 
3833
- if (!('ResizeObserver' in window)) unbinds.push(unbindable(document.body, 'chessground.resize', onResize));
3843
+ if (!s.dom.relative && s.resizable && !('ResizeObserver' in window)) {
3844
+ unbinds.push(unbindable(document.body, 'chessground.resize', boundsUpdated));
3845
+ }
3834
3846
 
3835
3847
  if (!s.viewOnly) {
3836
3848
  const onmove = dragOrDraw(s, move$1, move);
@@ -3881,7 +3893,8 @@ function dragOrDraw(s, withDrag, withDraw) {
3881
3893
 
3882
3894
  function render$1(s) {
3883
3895
  const asWhite = whitePov(s),
3884
- posToTranslate$1 = posToTranslate(s.dom.bounds()),
3896
+ posToTranslate = s.dom.relative ? posToTranslateRel : posToTranslateAbs(s.dom.bounds()),
3897
+ translate = s.dom.relative ? translateRel : translateAbs,
3885
3898
  boardEl = s.dom.elements.board,
3886
3899
  pieces = s.pieces,
3887
3900
  curAnim = s.animation.current,
@@ -3909,7 +3922,7 @@ function render$1(s) {
3909
3922
 
3910
3923
  if (el.cgDragging && (!curDrag || curDrag.orig !== k)) {
3911
3924
  el.classList.remove('dragging');
3912
- translate(el, posToTranslate$1(key2pos(k), asWhite));
3925
+ translate(el, posToTranslate(key2pos(k), asWhite));
3913
3926
  el.cgDragging = false;
3914
3927
  } // remove fading class if it still remains
3915
3928
 
@@ -3928,11 +3941,11 @@ function render$1(s) {
3928
3941
  pos[0] += anim[2];
3929
3942
  pos[1] += anim[3];
3930
3943
  el.classList.add('anim');
3931
- translate(el, posToTranslate$1(pos, asWhite));
3944
+ translate(el, posToTranslate(pos, asWhite));
3932
3945
  } else if (el.cgAnimating) {
3933
3946
  el.cgAnimating = false;
3934
3947
  el.classList.remove('anim');
3935
- translate(el, posToTranslate$1(key2pos(k), asWhite));
3948
+ translate(el, posToTranslate(key2pos(k), asWhite));
3936
3949
  if (s.addPieceZIndex) el.style.zIndex = posZIndex(key2pos(k), asWhite);
3937
3950
  } // same piece: flag as same
3938
3951
 
@@ -3966,7 +3979,7 @@ function render$1(s) {
3966
3979
  if (!sameSquares.has(sk)) {
3967
3980
  sMvdset = movedSquares.get(className);
3968
3981
  sMvd = sMvdset && sMvdset.pop();
3969
- const translation = posToTranslate$1(key2pos(sk), asWhite);
3982
+ const translation = posToTranslate(key2pos(sk), asWhite);
3970
3983
 
3971
3984
  if (sMvd) {
3972
3985
  sMvd.cgKey = sk;
@@ -4008,7 +4021,7 @@ function render$1(s) {
4008
4021
  pos[1] += anim[3];
4009
4022
  }
4010
4023
 
4011
- translate(pMvd, posToTranslate$1(pos, asWhite));
4024
+ translate(pMvd, posToTranslate(pos, asWhite));
4012
4025
  } // no piece in moved obj: insert the new piece
4013
4026
  // assumes the new piece is not being dragged
4014
4027
  else {
@@ -4024,7 +4037,7 @@ function render$1(s) {
4024
4037
  pos[1] += anim[3];
4025
4038
  }
4026
4039
 
4027
- translate(pieceNode, posToTranslate$1(pos, asWhite));
4040
+ translate(pieceNode, posToTranslate(pos, asWhite));
4028
4041
  if (s.addPieceZIndex) pieceNode.style.zIndex = posZIndex(pos, asWhite);
4029
4042
  boardEl.appendChild(pieceNode);
4030
4043
  }
@@ -4036,34 +4049,20 @@ function render$1(s) {
4036
4049
 
4037
4050
  for (const nodes of movedSquares.values()) removeNodes(s, nodes);
4038
4051
  }
4039
- function renderResized(s) {
4052
+ function updateBounds(s) {
4053
+ if (s.dom.relative) return;
4040
4054
  const asWhite = whitePov(s),
4041
- posToTranslate$1 = posToTranslate(s.dom.bounds());
4055
+ posToTranslate = posToTranslateAbs(s.dom.bounds());
4042
4056
  let el = s.dom.elements.board.firstChild;
4043
4057
 
4044
4058
  while (el) {
4045
4059
  if (isPieceNode(el) && !el.cgAnimating || isSquareNode(el)) {
4046
- translate(el, posToTranslate$1(key2pos(el.cgKey), asWhite));
4060
+ translateAbs(el, posToTranslate(key2pos(el.cgKey), asWhite));
4047
4061
  }
4048
4062
 
4049
4063
  el = el.nextSibling;
4050
4064
  }
4051
4065
  }
4052
- function updateBounds(s) {
4053
- const bounds = s.dom.elements.wrap.getBoundingClientRect();
4054
- const container = s.dom.elements.container;
4055
- const ratio = bounds.height / bounds.width;
4056
- const width = Math.floor(bounds.width * window.devicePixelRatio / 8) * 8 / window.devicePixelRatio;
4057
- const height = width * ratio;
4058
- container.style.width = width + 'px';
4059
- container.style.height = height + 'px';
4060
- s.dom.bounds.clear();
4061
-
4062
- if (s.addDimensionsCssVars) {
4063
- document.documentElement.style.setProperty('--cg-width', width + 'px');
4064
- document.documentElement.style.setProperty('--cg-height', height + 'px');
4065
- }
4066
- }
4067
4066
 
4068
4067
  function isPieceNode(el) {
4069
4068
  return el.tagName === 'PIECE';
@@ -4078,8 +4077,8 @@ function removeNodes(s, nodes) {
4078
4077
  }
4079
4078
 
4080
4079
  function posZIndex(pos, asWhite) {
4081
- let z = 3 + pos[1] * 8 + (7 - pos[0]);
4082
- if (asWhite) z = 69 - z;
4080
+ let z = 2 + pos[1] * 8 + (7 - pos[0]);
4081
+ if (asWhite) z = 67 - z;
4083
4082
  return z + '';
4084
4083
  }
4085
4084
 
@@ -4136,15 +4135,17 @@ function Chessground(element, config) {
4136
4135
  const prevUnbind = 'dom' in maybeState ? maybeState.dom.unbind : undefined; // compute bounds from existing board element if possible
4137
4136
  // this allows non-square boards from CSS to be handled (for 3D)
4138
4137
 
4139
- const elements = renderWrap(element, maybeState),
4138
+ const relative = maybeState.viewOnly && !maybeState.drawable.visible,
4139
+ elements = renderWrap(element, maybeState, relative),
4140
4140
  bounds = memo(() => elements.board.getBoundingClientRect()),
4141
4141
  redrawNow = skipSvg => {
4142
4142
  render$1(state);
4143
4143
  if (!skipSvg && elements.svg) renderSvg(state, elements.svg, elements.customSvg);
4144
4144
  },
4145
- onResize = () => {
4145
+ boundsUpdated = () => {
4146
+ bounds.clear();
4146
4147
  updateBounds(state);
4147
- renderResized(state);
4148
+ if (elements.svg) renderSvg(state, elements.svg, elements.customSvg);
4148
4149
  };
4149
4150
 
4150
4151
  const state = maybeState;
@@ -4153,13 +4154,13 @@ function Chessground(element, config) {
4153
4154
  bounds,
4154
4155
  redraw: debounceRedraw(redrawNow),
4155
4156
  redrawNow,
4156
- unbind: prevUnbind
4157
+ unbind: prevUnbind,
4158
+ relative
4157
4159
  };
4158
4160
  state.drawable.prevSvgHash = '';
4159
- updateBounds(state);
4160
4161
  redrawNow(false);
4161
- bindBoard(state, onResize);
4162
- if (!prevUnbind) state.dom.unbind = bindDocument(state, onResize);
4162
+ bindBoard(state, boundsUpdated);
4163
+ if (!prevUnbind) state.dom.unbind = bindDocument(state, boundsUpdated);
4163
4164
  state.events.insert && state.events.insert(elements);
4164
4165
  return state;
4165
4166
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-chessground",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
4
4
  "description": "React and Next wrapper for Chessground with chessboard and pieces out of the box",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.es.js",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "chess.js": "^0.12.0",
31
- "chessground": "^8.1.7",
31
+ "chessground": "^7.12.0",
32
32
  "merge-class-names": "^1.4.2",
33
33
  "react-pure-modal": "^2.1.0",
34
34
  "store2": "^2.12.0"