组件代码
const DesignerDragScaleContainer =()=>{
const { setScale, setRatio } = useAppStore();
const scaleCallback = useCallback(
(dsData: DragScaleData) => {
console.log("缩放率回调:" + JSON.stringify(dsData.scale));
setScale(dsData.scale);
setRatio(dsData.ratio);
},
[setScale, setRatio]
);
useDragScaleProvider({
container: containRef,
content: contentRef,
scaleCallback: scaleCallback,
});
}
hooks 相关
export interface DragScaleData {
scale: number;
ratio: number;
position: IPoint;
}
interface DragScaleParams{
container:MutableRefObject<HTMLDivElement> | undefined
content:MutableRefObject<HTMLDivElement> | undefined
scaleCallback?: (dsData: DragScaleData) => void;
}
export function useDragScaleProvider(params: DragScaleParams) {
const { container, scaleCallback } = params;
const { scale, ratio, compute } = useScaleCore();
const [wheelEvent,setWheelEvent] = useState<WheelEvent>()
const [position, setPosition] = useState<IPoint>({ x: 0, y: 0 });
const handleWheel = useCallback((e: WheelEvent): void => {
if (e.altKey && e.buttons !== 2) {
compute(e.deltaY > 0 ? 0 : 1);
// setWheelEvent(e)
}
}, [compute]);
useEffect(() => {
const handleWheelWithCallback = (e: WheelEvent) => {
handleWheel(e);
};
const currentContainer = container.current;
if (currentContainer) {
currentContainer.addEventListener('wheel', handleWheelWithCallback, { passive: true });
return () => {
currentContainer.removeEventListener('wheel', handleWheelWithCallback);
};
}
}, [container, handleWheel, scale, ratio, position, scaleCallback]);
useEffect(()=>{
scaleCallback?.({ scale, ratio, position });
},[position, ratio, scale, scaleCallback])
return { scale, ratio };
}
function useScaleCore(initialMax = 3, initialMin = 0.05, initialScale = 1, initialRatio = 1) {
const [max, setMax] = useState(initialMax);
const [min, setMin] = useState(initialMin);
const [scale, setScale] = useState(initialScale);
const [ratio, setRatio] = useState(initialRatio);
const compute = useCallback((type: number) => {
let _ratio = 1.2;
// 缩小
if (type === 0) _ratio = 1 / 1.2;
// 限制缩放倍数
let _scale = scale * _ratio;
if (_scale > max) {
_ratio = max / scale;
_scale = max;
} else if (_scale < min) {
_ratio = min / scale;
_scale = min;
}
// 使用函数式更新方式更新 scale 和 ratio
setScale(_scale);
setRatio(_ratio);
}, [max, min, scale]);
return { max, min, scale, ratio, compute };
}
export default useScaleCore;
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.