我正在尝试使SVG元素在内部可拖动,但是PanResponder无法解决SVG viewBox导致拖动的元素不跟随屏幕周围的触摸的问题。
我尝试利用触摸事件的X和Y值来影响SVG元素的X和Y值,但效果比使用PanResponder时差。当我切换为仅使用触摸事件的X和Y值时,我尝试使用在svgwg.org上找到的方程式将触摸事件X和Y转换为SVG坐标。
viewBox: "0 0 960.1 1856.51"
将X Y值转换为SVG坐标时使用的代码
svgXYConvert = (eX, eY) =>{
let eW = this.props.width;
let eH = this.props.height;
let [vbX, vbY, vbW, vbH] = this.props.viewBox.split(" ");
// Calculate the scale of elements and vb
let scaleX = eW/vbW;
let scaleY = eH/vbH;
// translation points
let translateX = eX - (vbX * scaleX);
let translateY = eY - (vbY * scaleY);
return [translateX, translateY];
}
PanResponder组件
import React from 'react';
import {PanResponder, Animated} from 'react-native';
import {Image, G, Rect} from 'react-native-svg';
const AnimatedG = Animated.createAnimatedComponent(G);
class DragImg extends React.Component {
constructor(props) {
super(props)
this.state = {
pan: new Animated.ValueXY({x: this.props.x, y: this.props.y}),
x: this.props.x,
y: this.props.y,
}
}
componentWillMount() {
this._panResponder = PanResponder.create({
onPanResponderTerminationRequest: () => false,
onStartShouldSetPanResponder: (e, gesture) => true,
onPanResponderGrant: (e, gesture) => {
this.state.pan.setOffset(this.state.pan.__getValue());
},
onPanResponderMove: Animated.event([
null, { dx: this.state.pan.x, dy: this.state.pan.y}
])
},
onPanResponderRelease: (e) => {
this.state.pan.flattenOffset();
}
})
}
render(){
let imgStyle = {transform: this.state.pan.getTranslateTransform()};
return <AnimatedG style={imgStyle} {...this._panResponder.panHandlers} x={this.state.x} y={this.state.y}>
<Image href={this.props.href} height={this.props.height} width={this.props.width} />
<Rect fill="transparent" height={this.props.height} width={this.props.width}/>
</AnimatedG>
}
}
export default DragImg;
将其呈现在设备高度为100%的SVG内部时,我在iPad上施加横向压力,允许他们缩放正在使用的SVG,以便更清晰地查看细节。如果他们放大了SVG占据整个屏幕的位置,则元素将通过PanResponder以正确的速度移动并几乎完美地跟随触摸,但是如果将它们缩小或使用默认屏幕,我们将向他们显示整个SVG的可见位置。拖动的元素移动缓慢且跟踪效果不佳。
我不确定该如何使SVG元素正确跟踪,而不管它们是在SVG上放大还是缩小。
答案 0 :(得分:0)
我做了一些类似的代码。我在Animated.View
上添加了position: absolute
,所以我将其移动,同时将SVG Circle
移动到SVG区域内。为此,我将SVG大小缩放为具有maxWidth和minWidth的理想大小。此外,SVG必须具有以下属性:preserveAspectRatio="xMinYMin"
,因为它需要从(0,0)开始作为起点。
您可以看到它在这里工作:https://snack.expo.io/@albertcito/svg-pan-responder