自定义输入价格范围之间的动画 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 线的主要内容,如果未能解决你的问题,请参考以下文章