我正在制作一个像 https://www.camexcalc.com 上的那样的曝光计算器,但在 React.JS 中重新制作了该网站。我正在使用 Material UI 滑块。当我制作这个滑块时,它是线性显示的,但该系列是对数的,这意味着右侧的数字很少,左侧的数字密度很高。如何覆盖此滑块以采用对数刻度,或者将值沿刻度等距离间隔为字符串而不考虑值?请注意,我不是 React 开发人员,这对我来说都是新鲜事。
const isoValues = [3, 7, 12, 25, 50, 100, 200, 400, 800, 1600, 3200];
const isoMarks = isoValues.map((value) => ({value, label: value.toString()}));
const [iso, setIso] = useState(100);
const handleIsoChange = (event: Event, newValue: number | number[]) => {
setIso(newValue as number);
};
return(
<div className="row">
<div className="col-xs-3 col-sm-2 col-md-4">ISO</div>
<div className="hidden-xs col-sm-2 col-md-2">
<label id="IsoDisplay">{iso}</label>
</div>
<div className="col-xs-8 col-sm-8 col-md-6">
<Slider
className="slider"
id="Iso"
min = {isoValues[0]}
max = {isoValues[isoValues.length - 1]}
step={null}
value={iso}
onChange={handleIsoChange}
marks={isoMarks}
/>
</div>
)
结果是一个线性刻度,左侧有很多小数字。我想要 ISO 值之间的间距相等
下面的代码是一个带有自定义滑块的 React 组件,该滑块均匀地间隔 ISO 值,无论其数值如何。 shadcn/ui 用于创建滑块组件,它提供了更多自定义选项:
import React, { useState } from 'react';
import { Slider } from '@/components/ui/slider';
import { Label } from '@/components/ui/label';
const ISOSlider = () => {
// ISO values array
const isoValues = [3, 7, 12, 25, 50, 100, 200, 400, 800, 1600, 3200];
// Instead of using actual ISO values, we'll use array indices
const [selectedIndex, setSelectedIndex] = useState(isoValues.indexOf(100));
// Convert index back to ISO value
const currentISOValue = isoValues[selectedIndex];
const handleSliderChange = (newValue) => {
setSelectedIndex(newValue[0]);
};
return (
<div className="w-full max-w-md space-y-4">
<div className="flex items-center justify-between">
<Label htmlFor="iso-slider" className="text-sm font-medium">
ISO
</Label>
<span className="text-sm font-medium">
{currentISOValue}
</span>
</div>
<Slider
id="iso-slider"
min={0}
max={isoValues.length - 1}
step={1}
value={[selectedIndex]}
onValueChange={handleSliderChange}
className="w-full"
/>
<div className="flex justify-between text-xs text-gray-500">
{isoValues.map((value, index) => (
<span
key={value}
className="relative"
style={{
position: 'absolute',
left: `${(index / (isoValues.length - 1)) * 100}%`,
transform: 'translateX(-50%)'
}}
>
{value}
</span>
))}
</div>
</div>
);
};
export default ISOSlider;
工作原理:
与原始代码的主要区别:
此方法可确保:
您可以将样式或位置修改为您想要的外观。
我希望这有帮助。