按比例缩放Javascript中的x和y坐标

时间:2016-08-09 06:21:59

标签: javascript user-interface scale axes

我正在尝试构建如下控件:

enter image description here enter image description here

当它取消关联时,我可以使用它,但我无法弄清楚如何根据在第一个或第二个输入字段中输入的任何值来缩放它。

class OffsetControl extends Component {
    constructor(props) {
      super(props)
      this.state = {
        axes: { x: 0, y: 0 },
        isLinked: false
      }
      this._handleAxisChange = this._handleAxisChange.bind(this)
    }

    _scale(axes) {
      const { axes: { x, y } } = this.state
      let ratio = [axes.x / x, axes.y / y ]

      ratio = Math.min(ratio[0], ratio[1])

      this.setState({
        axes: {
          x: x * ratio,
          y: y * ratio
        }
      })
    }

    _handleAxisChange({ target: { name, value } }) {
      const { isLinked, axes } = this.state
      const newAxes = { ...axes, [name]: +value }
      if (isLinked) {
        this._scale(newAxes)
      } else {
        this.setState(newAxes)
      }
    }

    render() {
      const { axes: { x, y }, isLinked } = this.state
      return (
        <div>
          <input type="number" name="x" value={x} onChange={this._handleAxisChange}/>
          <button onClick={() => this.setState({ isLinked: !isLinked })}>
            { isLinked ? 'Unlink' : 'Link' }
          </button>
          <input type="number" name="y" value={y} onChange={this._handleAxisChange}/>
        </div>
      )
    }
  }

您可以找到实时版here。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

基本上是直线公式:

y = mx + c

在一般情况下(如将cm转换为英寸)c为零。所以这个公式只是:

y = mx

在有偏移的情况下(例如将摄氏温度转换为华氏温度),您只需要c

如何将此应用于链接缩放?

找出m(或者如果你更熟悉微积分,dy / dx - 这是我将在下面的代码中使用的术语):

var current_input = 5;
var current_output = 9;

var dy_dx = current_output/current_input;

var new_output = dy_dx * new_input;

所以,一个具体的例子:

current_input = 5;
current_output = 9;

// change 5 to 11, what should 9 change to?

new_output = (9/5) * 11; // result is 19.8

如果您需要在更改第二个值时计算第一个值,则可以翻转等式:

current_input = 9;
current_output = 5;

// change 9 to 15, what should 5 change to?

new_output = (5/9) * 15; // result is 8.333

通常,您可以将其实现为:

function scale (old_input, old_output, new_input) {
    return (old_output/old_input) * new_input;
}

虽然在数字上最好存储m的值,以便在进行大量计算后不会失去准确性:

function Scaler (x,y) {
    this.m = y/x;
}

Scaler.prototype.calculate_y (new_x) {
    return this.m * new_x;
}

Scaler.prototype.calculate_x (new_y) {
    return (1/this.m) * new_y;
}

// so you can do:

var scaler = new Scaler(5,9);
var new_output = scaler.calculate_y(11);

毕竟高中数学很有用。