zoom-control.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import React from 'react';
  2. import Slider from 'rc-slider';
  3. import { scaleLog } from 'd3-scale';
  4. const SLIDER_STEP = 0.001;
  5. const CLICK_STEP = 0.05;
  6. // Returns a log-scale that maps zoom factors to slider values.
  7. const getSliderScale = ({ minScale, maxScale }) => (
  8. scaleLog()
  9. // Zoom limits may vary between different views.
  10. .domain([minScale, maxScale])
  11. // Taking the unit range for the slider ensures consistency
  12. // of the zoom button steps across different zoom domains.
  13. .range([0, 1])
  14. // This makes sure the input values are always clamped into the valid domain/range.
  15. .clamp(true)
  16. );
  17. export default class ZoomControl extends React.Component {
  18. constructor(props, context) {
  19. super(props, context);
  20. this.handleChange = this.handleChange.bind(this);
  21. this.handleZoomOut = this.handleZoomOut.bind(this);
  22. this.handleZoomIn = this.handleZoomIn.bind(this);
  23. this.getSliderValue = this.getSliderValue.bind(this);
  24. this.toZoomScale = this.toZoomScale.bind(this);
  25. }
  26. handleChange(sliderValue) {
  27. this.props.zoomAction(this.toZoomScale(sliderValue));
  28. }
  29. handleZoomOut() {
  30. this.props.zoomAction(this.toZoomScale(this.getSliderValue() - CLICK_STEP));
  31. }
  32. handleZoomIn() {
  33. this.props.zoomAction(this.toZoomScale(this.getSliderValue() + CLICK_STEP));
  34. }
  35. getSliderValue() {
  36. const toSliderValue = getSliderScale(this.props);
  37. return toSliderValue(this.props.scale);
  38. }
  39. toZoomScale(sliderValue) {
  40. const toSliderValue = getSliderScale(this.props);
  41. return toSliderValue.invert(sliderValue);
  42. }
  43. render() {
  44. const value = this.getSliderValue();
  45. return (
  46. <div className="zoom-control">
  47. <button className="zoom-in" type="button" onClick={this.handleZoomIn}>
  48. <i className="fa fa-plus" />
  49. </button>
  50. <Slider value={value} max={1} step={SLIDER_STEP} vertical onChange={this.handleChange} />
  51. <button className="zoom-out" type="button" onClick={this.handleZoomOut}>
  52. <i className="fa fa-minus" />
  53. </button>
  54. </div>
  55. );
  56. }
  57. }