как реагировать-конва масштабирование на скролл

Привет, я пытаюсь реализовать функцию масштабирования на прямоугольнике в моем проекте реакции, но не могу найти способ сделать это таким образом? любая помощь, пожалуйста?

это пример html konva, который я нашел:
https://konvajs.github.io/docs/sandbox/Zooming_Relative_To_Pointer.html.


person HachimJ    schedule 28.08.2018    source источник


Ответы (2)


import React, { Component } from 'react';
import Konva from 'konva';
import { render } from 'react-dom';
import { Stage, Layer, Circle } from 'react-konva';

class App extends Component {
  state = {
    stageScale: 1,
    stageX: 0,
    stageY: 0
  };
  handleWheel = e => {
    e.evt.preventDefault();

    const scaleBy = 1.02;
    const stage = e.target.getStage();
    const oldScale = stage.scaleX();
    const mousePointTo = {
      x: stage.getPointerPosition().x / oldScale - stage.x() / oldScale,
      y: stage.getPointerPosition().y / oldScale - stage.y() / oldScale
    };

    const newScale = e.evt.deltaY > 0 ? oldScale * scaleBy : oldScale / scaleBy;


    this.setState({
      stageScale: newScale,
      stageX:
        -(mousePointTo.x - stage.getPointerPosition().x / newScale) * newScale,
      stageY:
        -(mousePointTo.y - stage.getPointerPosition().y / newScale) * newScale
    });
  };
  render() {
    return (
      <Stage
        width={window.innerWidth}
        height={window.innerHeight}
        onWheel={this.handleWheel}
        scaleX={this.state.stageScale}
        scaleY={this.state.stageScale}
        x={this.state.stageX}
        y={this.state.stageY}
      >
        <Layer>
          <Circle
            x={window.innerWidth / 2}
            y={window.innerHeight / 2}
            radius={50}
            fill="green"
            shadowBlur={5}
          />
        </Layer>
      </Stage>
    );
  }
}

render(<App />, document.getElementById('root'));

Демо: https://codesandbox.io/s/react-konva-zoom-on-scroll-demo-9t7ks

person lavrton    schedule 29.08.2018
comment
как этого добиться с помощью крючков? - person suraj sharma; 12.08.2020
comment
К вашему сведению: чтобы изменить направление масштабирования, просто измените условие newScale с e.evt.deltaY > 0 на e.evt.deltaY < 0. - person khanguslee; 10.12.2020

Обновленный ответ с использованием крючков и обратного направления масштабирования:

import React, { useState } from "react";
import Konva from "konva";
import { render } from "react-dom";
import { Stage, Layer, Circle } from "react-konva";

const App = () => {
  const [stage, setStage] = useState({
    scale: 1,
    x: 0,
    y: 0
  });

  const handleWheel = (e) => {
    e.evt.preventDefault();

    const scaleBy = 1.02;
    const stage = e.target.getStage();
    const oldScale = stage.scaleX();
    const mousePointTo = {
      x: stage.getPointerPosition().x / oldScale - stage.x() / oldScale,
      y: stage.getPointerPosition().y / oldScale - stage.y() / oldScale
    };

    const newScale = e.evt.deltaY < 0 ? oldScale * scaleBy : oldScale / scaleBy;

    setStage({
      scale: newScale,
      x: (stage.getPointerPosition().x / newScale - mousePointTo.x) * newScale,
      y: (stage.getPointerPosition().y / newScale - mousePointTo.y) * newScale
    });
  };

  return (
    <Stage
      width={window.innerWidth}
      height={window.innerHeight}
      onWheel={handleWheel}
      scaleX={stage.scale}
      scaleY={stage.scale}
      x={stage.x}
      y={stage.y}
    >
      <Layer>
        <Circle
          x={window.innerWidth / 2}
          y={window.innerHeight / 2}
          radius={50}
          fill="green"
          shadowBlur={5}
        />
      </Layer>
    </Stage>
  );
};

render(<App />, document.getElementById("root"));

Демо: https://codesandbox.io/s/react-konva-zoom-on-scroll-demo-forked-70vsj

person Paras Daryanani    schedule 21.04.2021