自定义输入价格范围之间的动画 SVG 线

Posted

技术标签:

【中文标题】自定义输入价格范围之间的动画 SVG 线【英文标题】:Animate SVG line between custom input price range 【发布时间】:2021-04-16 13:43:42 【问题描述】:

我正在构建一个价格范围滑块,其中包含从最低价格到最高价格的 2 个输入和一条 SVG 线,该线将在滑块拇指内向左/向右动画。

我正在努力寻找该功能的数学方程式,因为如果有意义的话,左 SVG x1 值需要为 0 而不是最小输入值。

我留下了一个codeSandBox,所以你们可以看看我在这里想要实现的确切目标。

https://codesandbox.io/s/practical-bush-qq7dl?file=/src/App.js

import React,  useState  from "react";

export default function App() 
  const [minRange, setMinRange] = useState("");
  const [maxRange, setMaxRange] = useState("");
  const [staticRange, setStaticRange] = useState(
    min: 20,
    max: 112
  );
  const rangeSplit = staticRange.min + staticRange.max / 2;

  const handleChange = (input, e) => 
    const value = e.target.value;
    input === "min" ? setMinRange(value) : setMaxRange(value);
  ;

  return (
    <div className="slider">
      <div className="slider__inputs">
        <input
          min=staticRange.min
          max=rangeSplit
          type="range"
          value=minRange
          onChange=(e) => handleChange("min", e)
        />
        <input
          min=rangeSplit
          max=staticRange.max
          type="range"
          value=maxRange
          onChange=(e) => handleChange("max", e)
        />

        <svg  >
          <line
            x1=minRange
            y1="0"
            x2=maxRange
            y2="0"
            stroke="#444"
            stroke-
          ></line>
        </svg>
      </div>
      <div className="slider__range">
        <span>`£$minRange`</span>
        <span>`£$maxRange`</span>
      </div>
    </div>
  );


想要的效果:

【问题讨论】:

【参考方案1】:

您的 svg 线是用 % 定义的,因此您需要将 x1、x2 值转换为上述 kca 所示的百分比。

因此,您需要做的就是将总范围计算为 staticRange.max - staticRange.min。

const totalRange=(staticRange.max - staticRange.min);

此外,您需要将范围拆分设置为静态最小值和最大值之间的位置,因此如果您的最小值为 20,最大值为 112,则范围拆分需要为 66,(66 比 46 多) 20 和 46 小于 112)。

const rangeSplit = staticRange.min+(totalRange / 2);

然后,在定义 x1 和 x2 点时,将滑块位置与 staticRange.min 值之间的差值转换为 %。

x1=(100 * ((minRange-staticRange.min)/totalRange)) + "%"

x2=(100 * ((maxRange-staticRange.min)/totalRange)) + "%"

如您所见,当 minRange == staticRange.min 时,值为 0%,当 maxRange == staticRange.max 时,值为 totalRange/totalRange,等于 100%。

【讨论】:

珍惜你的时间,工作就像一个魅力。【参考方案2】:

数学是

x% = 100% * 值/范围

您必须对行的开头和结尾都进行此计算。

说明

见Cross-multiplication。

x% / value = 100% / (112-20),乘以value 表示x% = 100% / (112-20) * value

有时在除法之前先乘以更好,因此我喜欢总是这样做:x% = 100% * value / (112-20)

示例

const usePercent = (min, max, value)=>
  const [ valuePct, setValuePct ] = useState(0);

  useEffect(()=>
    const valueNum      = (value && value > min) ? value : min; // should never be less than min
    const rangeSize     = max - min;       // e.g. 112 - 20 = 92
    const relativeValue = valueNum - min;  // e.g. change value 20...112 --> 0...91
    const percent       = 100 * relativeValue / rangeSize  // 100% / 92 === x% / relativeValue

    setValuePct( percent );

  , [ min, max, value ]);

  return valuePct;
;

const Line = (props)=>
  const  minValue, maxValue, minOffset, maxOffset  = props;
  const minPercent = usePercent( minOffset, maxOffset, minValue );
  const maxPercent = usePercent( minOffset, maxOffset, maxValue );

  return (<svg  >
    <line
        x1= minPercent + '%' 
        y1="0"
        x2= maxPercent + '%' 
        y2="0"
        stroke="#444"
        strokeWidth="12"
    />
  </svg>);
;

export default function App() 
...
  return (
...
        <Line
            minValue= minRange 
            maxValue= maxRange 
            minOffset= 20 
            maxOffset= 112 
        />
...
  );
;

【讨论】:

感谢您花时间回答,我错过了那部分,我想我不擅长数学:)

以上是关于自定义输入价格范围之间的动画 SVG 线的主要内容,如果未能解决你的问题,请参考以下文章

如何在Canvas中实现自定义路径动画

如何在Canvas中实现自定义路径动画

presentModalViewController 超出屏幕范围以获取自定义动画

如何将 flyto 传单功能添加到自定义 Svg 地图

Xamarin.forms 页面之间导航的自定义动画?

如何将动画添加到由 AnyView 制作的自定义导航项之间的过渡?