<commit_before>// =============================================================================
// Boost.js | Draggable Component
// (c) Mathigon
// =============================================================================


import { Evented, clamp } from '@mathigon/core';
import { roundTo } from '@mathigon/fermat';
import { Browser } from './browser';
import { slide } from './events';


export class Draggable extends Evented {

  constructor($el, $parent, direction = '', margin = 0, useTransform = false, snap = null) {
    super();
    let _this = this;
    let lastPosn, noMove;

    this.$el = $el;
    this._posn = { x: null, y: null };
    this.move = { x: direction !== 'y', y: direction !== 'x' };
    this.useTransform = useTransform;
    this.snap = snap;
    this.disabled = false;

    slide($el, {
      start: function(posn) {
        if (_this.disabled) return;
        lastPosn = posn;
        noMove = true;
        _this.trigger('start');
      },
      move: function(posn) {
        if (_this.disabled) return;
        noMove = false;

        let x = clamp(_this._posn.x + posn.x - lastPosn.x, 0, _this.width);
        let y = clamp(_this._posn.y + posn.y - lastPosn.y, 0, _this.height);

        lastPosn = posn;
        _this.position = { x, y };
        _this.trigger('drag');
      },
      end: function() {
        if (_this.disabled) return;
        _this.trigger(noMove ? 'click' : 'end');
      }
    });

    Browser.resize(function () {
      let oldWidth = _this.width;
      let oldHeight = _this.height;

      _this.width  = $parent.width  - margin * 2;
      _this.height = $parent.height - margin * 2;

      let x = _this.width  / oldWidth  * _this._posn.x;
      let y = _this.height / oldHeight * _this._posn.y;
      _this.draw({ x, y });
    });
  }

  get position() {
    return this._posn;
  }

  set position(posn) {
    this.draw(posn);
    this._posn = posn;
    this.trigger('move', posn);
  }

  draw({ x, y }) {
    if (this.snap) {
      x = roundTo(x, this.snap);
      y = roundTo(y, this.snap);
    }

    if (this.useTransform) {
      this.$el.translate(this.move.x ? Math.round(x) : 0, this.move.y ? Math.round(y) : 0);
    } else {
      if (this.move.x) this.$el.css('left', Math.round(x) + 'px');
      if (this.move.y) this.$el.css('top',  Math.round(y) + 'px');
    }
  }

}<commit_msg>Draggable.position should return the "snapped" position<commit_after>// =============================================================================
// Boost.js | Draggable Component
// (c) Mathigon
// =============================================================================


import { Evented, clamp } from '@mathigon/core';
import { roundTo } from '@mathigon/fermat';
import { Browser } from './browser';
import { slide } from './events';


export class Draggable extends Evented {

  constructor($el, $parent, direction = '', margin = 0, useTransform = false, snap = 1) {
    super();
    let _this = this;
    let lastPosn, noMove;

    this.$el = $el;
    this._posn = { x: null, y: null };
    this.move = { x: direction !== 'y', y: direction !== 'x' };
    this.useTransform = useTransform;
    this.snap = snap;
    this.disabled = false;

    slide($el, {
      start: function(posn) {
        if (_this.disabled) return;
        lastPosn = posn;
        noMove = true;
        _this.trigger('start');
      },
      move: function(posn) {
        if (_this.disabled) return;
        noMove = false;

        let x = clamp(_this._posn.x + posn.x - lastPosn.x, 0, _this.width);
        let y = clamp(_this._posn.y + posn.y - lastPosn.y, 0, _this.height);

        lastPosn = posn;
        _this.position = { x, y };
        _this.trigger('drag');
      },
      end: function() {
        if (_this.disabled) return;
        _this.trigger(noMove ? 'click' : 'end');
      }
    });

    Browser.resize(function () {
      let oldWidth = _this.width;
      let oldHeight = _this.height;

      _this.width  = $parent.width  - margin * 2;
      _this.height = $parent.height - margin * 2;

      let x = _this.width  / oldWidth  * _this._posn.x;
      let y = _this.height / oldHeight * _this._posn.y;
      _this.draw({ x, y });
    });
  }

  get position() {
    return {
      x: roundTo(this._posn.x, this.snap),
      y: roundTo(this._posn.y, this.snap)
    };
  }

  set position(posn) {
    this.draw(posn);
    this._posn = posn;
    this.trigger('move', posn);
  }

  draw({ x, y }) {
    if (this.snap) {
      x = roundTo(x, this.snap);
      y = roundTo(y, this.snap);
    }

    if (this.useTransform) {
      this.$el.translate(this.move.x ? Math.round(x) : 0, this.move.y ? Math.round(y) : 0);
    } else {
      if (this.move.x) this.$el.css('left', Math.round(x) + 'px');
      if (this.move.y) this.$el.css('top',  Math.round(y) + 'px');
    }
  }

}
{'fraction_non_alphanumeric': 0.22091341186195496, 'fraction_numerical': 0.0030998140111593306, 'mean_word_length': 2.377529658060014, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5784625', 'n_tokens_mistral': 1689, 'n_tokens_neox': 1612, 'n_words': 368}