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

Proportionally scale x and y coordinates in Javascript

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

当它未链接时我可以使用它,但我不知道如何根据在第一个或第二个输入字段中输入的任何值来缩放它。

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。非常感谢任何帮助。

基本就是直线公式:

y = mx + c

在一般情况下(比如将厘米转换为英寸)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);

高中数学还是有用的