File size: 3,232 Bytes
695ea30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**
 * dat-gui JavaScript Controller Library
 * https://github.com/dataarts/dat.gui
 *
 * Copyright 2011 Data Arts Team, Google Creative Lab
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 */

import Controller from './Controller';
import common from '../utils/common';

function numDecimals(x) {
  const _x = x.toString();
  if (_x.indexOf('.') > -1) {
    return _x.length - _x.indexOf('.') - 1;
  }

  return 0;
}

/**
 * @class Represents a given property of an object that is a number.
 *
 * @extends dat.controllers.Controller
 *
 * @param {Object} object The object to be manipulated
 * @param {string} property The name of the property to be manipulated
 * @param {Object} [params] Optional parameters
 * @param {Number} [params.min] Minimum allowed value
 * @param {Number} [params.max] Maximum allowed value
 * @param {Number} [params.step] Increment by which to change value
 */
class NumberController extends Controller {
  constructor(object, property, params) {
    super(object, property);

    const _params = params || {};

    this.__min = _params.min;
    this.__max = _params.max;
    this.__step = _params.step;

    if (common.isUndefined(this.__step)) {
      if (this.initialValue === 0) {
        this.__impliedStep = 1; // What are we, psychics?
      } else {
        // Hey Doug, check this out.
        this.__impliedStep = Math.pow(10, Math.floor(Math.log(Math.abs(this.initialValue)) / Math.LN10)) / 10;
      }
    } else {
      this.__impliedStep = this.__step;
    }

    this.__precision = numDecimals(this.__impliedStep);
  }

  setValue(v) {
    let _v = v;

    if (this.__min !== undefined && _v < this.__min) {
      _v = this.__min;
    } else if (this.__max !== undefined && _v > this.__max) {
      _v = this.__max;
    }

    if (this.__step !== undefined && _v % this.__step !== 0) {
      _v = Math.round(_v / this.__step) * this.__step;
    }

    return super.setValue(_v);
  }

  /**
   * Specify a minimum value for <code>object[property]</code>.
   *
   * @param {Number} minValue The minimum value for
   * <code>object[property]</code>
   * @returns {dat.controllers.NumberController} this
   */
  min(minValue) {
    this.__min = minValue;
    return this;
  }

  /**
   * Specify a maximum value for <code>object[property]</code>.
   *
   * @param {Number} maxValue The maximum value for
   * <code>object[property]</code>
   * @returns {dat.controllers.NumberController} this
   */
  max(maxValue) {
    this.__max = maxValue;
    return this;
  }

  /**
   * Specify a step value that dat.controllers.NumberController
   * increments by.
   *
   * @param {Number} stepValue The step value for
   * dat.controllers.NumberController
   * @default if minimum and maximum specified increment is 1% of the
   * difference otherwise stepValue is 1
   * @returns {dat.controllers.NumberController} this
   */
  step(stepValue) {
    this.__step = stepValue;
    this.__impliedStep = stepValue;
    this.__precision = numDecimals(stepValue);
    return this;
  }
}

export default NumberController;