1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-23 20:37:42 +00:00

support changing the image view position by dragging after zooming in (#7964)

Co-authored-by: zhouwenxuan <aries@Mac.local>
This commit is contained in:
Aries
2025-06-26 17:20:15 +08:00
committed by GitHub
parent 3f0e3591e9
commit 0aec56f8ab
2 changed files with 77 additions and 15 deletions

View File

@@ -61,16 +61,25 @@ class FileContent extends React.Component {
thumbnailURL = `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForOriginal}${Utils.encodePath(filePath)}?mtime=${lastModificationTime}`;
}
const { scale, angle } = this.props;
let style = {};
if (scale && angle != undefined) {
style = { transform: `scale(${scale}) rotate(${angle}deg)` };
} else if (scale) {
style = { transform: `scale(${scale})` };
} else if (angle != undefined) {
style = { transform: `rotate(${angle}deg)` };
const { scale, angle, offset } = this.props;
let transforms = [];
if (scale) {
transforms.push(`scale(${scale})`);
}
if (angle !== undefined) {
transforms.push(`rotate(${angle}deg)`);
}
let style = {};
if (transforms.length > 0) {
style.transform = transforms.join(' ');
}
if (scale > 1 && offset && typeof offset === 'object') {
if (offset.x !== undefined) style.left = offset.x;
if (offset.y !== undefined) style.top = offset.y;
style.position = 'relative';
}
return (
<div className="file-view-content flex-1 image-file-view">
@@ -89,7 +98,8 @@ class FileContent extends React.Component {
FileContent.propTypes = {
tip: PropTypes.object.isRequired,
scale: PropTypes.number,
angle: PropTypes.number
angle: PropTypes.number,
offset: PropTypes.object,
};
export default FileContent;

View File

@@ -22,14 +22,20 @@ class InnerFileView extends React.Component {
super();
this.state = {
imageScale: 1,
imageAngle: 0
imageAngle: 0,
imageOffset: { x: 0, y: 0 },
isDragging: false,
dragStart: null,
dragOrigin: null,
};
this.imageContainerRef = React.createRef();
}
setImageScale = (scale) => {
this.setState({
imageScale: scale
});
this.setState(prevState => ({
imageScale: scale,
imageOffset: scale === 1 ? { x: 0, y: 0 } : prevState.imageOffset,
}));
};
rotateImage = () => {
@@ -46,6 +52,36 @@ class InnerFileView extends React.Component {
});
};
handleImageMouseDown = (e) => {
if (this.state.imageScale <= 1) return;
e.preventDefault();
this.setState({
isDragging: true,
dragStart: { x: e.clientX, y: e.clientY },
dragOrigin: { ...this.state.imageOffset }
});
document.addEventListener('mousedown', this.handleImageMouseDown);
document.addEventListener('mouseup', this.handleImageMouseUp);
};
handleImageMouseMove = (e) => {
if (!this.state.isDragging) return;
const dx = e.clientX - this.state.dragStart.x;
const dy = e.clientY - this.state.dragStart.y;
this.setState({
imageOffset: {
x: this.state.dragOrigin.x + dx,
y: this.state.dragOrigin.y + dy
}
});
};
handleImageMouseUp = (e) => {
this.setState({ isDragging: false });
document.removeEventListener('mousedown', this.handleImageMouseDown);
document.removeEventListener('mouseup', this.handleImageMouseUp);
};
render() {
if (err) {
return (
@@ -53,11 +89,27 @@ class InnerFileView extends React.Component {
);
}
const { imageScale, imageAngle } = this.state;
const { imageScale, imageAngle, imageOffset } = this.state;
let content;
switch (fileType) {
case 'Image':
content = <Image tip={<FileViewTip />} scale={imageScale} angle={imageAngle} />;
content = (
<div
ref={this.imageContainerRef}
className="d-flex w-100 h-100"
style={{ cursor: imageScale > 1 ? 'move' : 'default' }}
onMouseDown={this.handleImageMouseDown}
onMouseMove={this.handleImageMouseMove}
onMouseUp={this.handleImageMouseUp}
>
<Image
tip={<FileViewTip />}
scale={imageScale}
angle={imageAngle}
offset={imageOffset}
/>
</div>
);
break;
case 'SVG':
content = <SVG />;