mirror of
https://github.com/infeng/react-viewer.git
synced 2025-12-08 17:36:40 +00:00
refactor: use transform improve performance
This commit is contained in:
parent
b7e406e9ad
commit
0a3b829675
@ -14,8 +14,8 @@ export interface ViewerCanvasProps {
|
||||
onResize: () => void;
|
||||
onZoom: (targetX: number, targetY: number, direct: number, scale: number) => void;
|
||||
zIndex: number;
|
||||
scaleX: 1 | -1;
|
||||
scaleY: 1 | -1;
|
||||
scaleX: number;
|
||||
scaleY: number;
|
||||
loading: boolean;
|
||||
drag: boolean;
|
||||
onCanvasMouseDown: (e: React.MouseEvent<HTMLDivElement>) => void;
|
||||
@ -146,9 +146,8 @@ export default class ViewerCanvas extends React.Component<ViewerCanvasProps, Vie
|
||||
let imgStyle: React.CSSProperties = {
|
||||
width: `${this.props.width}px`,
|
||||
height: `${this.props.height}px`,
|
||||
marginTop: `${this.props.top}px`,
|
||||
marginLeft: this.props.left ? `${this.props.left}px` : 'auto',
|
||||
transform: `rotate(${this.props.rotate}deg) scaleX(${this.props.scaleX}) scaleY(${this.props.scaleY})`,
|
||||
transform: `translateX(${this.props.left ? this.props.left + 'px' : 'aoto'}) translateY(${this.props.top}px)
|
||||
rotate(${this.props.rotate}deg) scaleX(${this.props.scaleX}) scaleY(${this.props.scaleY})`,
|
||||
};
|
||||
|
||||
let imgClass = this.props.drag ? 'drag' : '';
|
||||
@ -170,10 +169,18 @@ export default class ViewerCanvas extends React.Component<ViewerCanvasProps, Vie
|
||||
/>;
|
||||
}
|
||||
if (this.props.loading) {
|
||||
imgNode = <Loading style={{
|
||||
marginTop: this.props.top,
|
||||
marginLeft: this.props.left,
|
||||
}}/>;
|
||||
imgNode = (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
height: '100%',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Loading/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@ -22,8 +22,8 @@ export interface ViewerCoreState {
|
||||
rotate?: number;
|
||||
imageWidth?: number;
|
||||
imageHeight?: number;
|
||||
scaleX?: 1 | -1;
|
||||
scaleY?: 1 | -1;
|
||||
scaleX?: number;
|
||||
scaleY?: number;
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
@ -144,8 +144,8 @@ export default class ViewerCore extends React.Component<ViewerProps, ViewerCoreS
|
||||
activeIndex: activeIndex,
|
||||
width: 0,
|
||||
height: 0,
|
||||
left: this.containerWidth / 2,
|
||||
top: (this.containerHeight - this.footerHeight) / 2,
|
||||
left: 0,
|
||||
top: 0,
|
||||
rotate: 0,
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
@ -247,10 +247,10 @@ export default class ViewerCore extends React.Component<ViewerProps, ViewerCoreS
|
||||
this.loadImg(this.state.activeIndex);
|
||||
break;
|
||||
case ActionType.scaleX:
|
||||
this.handleScaleX(this.state.scaleX === 1 ? -1 : 1);
|
||||
this.handleScaleX(-1);
|
||||
break;
|
||||
case ActionType.scaleY:
|
||||
this.handleScaleY(this.state.scaleY === 1 ? -1 : 1);
|
||||
this.handleScaleY(-1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -259,13 +259,13 @@ export default class ViewerCore extends React.Component<ViewerProps, ViewerCoreS
|
||||
|
||||
handleScaleX(newScale: 1 | -1) {
|
||||
this.setState({
|
||||
scaleX: newScale,
|
||||
scaleX: this.state.scaleX * newScale,
|
||||
});
|
||||
}
|
||||
|
||||
handleScaleY(newScale: 1 | -1) {
|
||||
this.setState({
|
||||
scaleY: newScale,
|
||||
scaleY: this.state.scaleY * newScale,
|
||||
});
|
||||
}
|
||||
|
||||
@ -273,27 +273,50 @@ export default class ViewerCore extends React.Component<ViewerProps, ViewerCoreS
|
||||
let imgCenterXY = this.getImageCenterXY();
|
||||
let diffX = targetX - imgCenterXY.x;
|
||||
let diffY = targetY - imgCenterXY.y;
|
||||
let diffWidth = direct * this.state.width * scale;
|
||||
let diffHeight = direct * this.state.height * scale;
|
||||
// when image width is 0, set original width
|
||||
if (diffWidth === 0) {
|
||||
const [ width, height ] = this.getImgWidthHeight(this.state.imageWidth, this.state.imageHeight);
|
||||
diffWidth = width;
|
||||
diffHeight = height;
|
||||
let reset = false;
|
||||
let top = 0;
|
||||
let left = 0;
|
||||
let width = 0;
|
||||
let height = 0;
|
||||
let scaleX = 0;
|
||||
let scaleY = 0;
|
||||
if (this.state.width === 0) {
|
||||
const [ imgWidth, imgHeight ] = this.getImgWidthHeight(this.state.imageWidth, this.state.imageHeight);
|
||||
reset = true;
|
||||
left = (this.containerWidth - imgWidth) / 2;
|
||||
top = (this.containerHeight - this.footerHeight - imgHeight) / 2;
|
||||
width = this.state.width + imgWidth;
|
||||
height = this.state.height + imgHeight;
|
||||
scaleX = scaleY = 1;
|
||||
}else {
|
||||
let directX = this.state.scaleX > 0 ? 1 : -1;
|
||||
let directY = this.state.scaleY > 0 ? 1 : -1;
|
||||
scaleX = this.state.scaleX + scale * direct * directX;
|
||||
scaleY = this.state.scaleY + scale * direct * directY;
|
||||
if (Math.abs(scaleX) < 0.1 || Math.abs(scaleY) < 0.1) {
|
||||
return;
|
||||
}
|
||||
top = this.state.top + -direct * diffY / this.state.scaleX * scale * directX;
|
||||
left = this.state.left + -direct * diffX / this.state.scaleY * scale * directY;
|
||||
width = this.state.width;
|
||||
height = this.state.height;
|
||||
}
|
||||
this.setState({
|
||||
width: this.state.width + diffWidth,
|
||||
height: this.state.height + diffHeight,
|
||||
top: this.state.top + -diffHeight / 2 + -direct * diffY * scale,
|
||||
left: this.state.left + -diffWidth / 2 + -direct * diffX * scale,
|
||||
width: width,
|
||||
scaleX: scaleX,
|
||||
scaleY: scaleY,
|
||||
height: height,
|
||||
top: top,
|
||||
left: left,
|
||||
loading: false,
|
||||
});
|
||||
}
|
||||
|
||||
getImageCenterXY() {
|
||||
return {
|
||||
x: this.state.left + this.state.width / 2,
|
||||
y: this.state.top + this.state.height / 2,
|
||||
x: (this.state.left + this.state.width / 2),
|
||||
y: (this.state.top + this.state.height / 2),
|
||||
};
|
||||
}
|
||||
|
||||
@ -402,12 +425,18 @@ export default class ViewerCore extends React.Component<ViewerProps, ViewerCoreS
|
||||
}
|
||||
if (this.props.visible && !nextProps.visible) {
|
||||
this.bindEvent(true);
|
||||
let imgCenterXY2 = this.getImageCenterXY();
|
||||
this.handleZoom(imgCenterXY2.x, imgCenterXY2.y, -1, 1);
|
||||
this.handleZoom(
|
||||
this.containerWidth / 2,
|
||||
(this.containerHeight - this.footerHeight) / 2,
|
||||
-1,
|
||||
(this.state.scaleX > 0 ? 1 : -1) * this.state.scaleX - 0.11,
|
||||
);
|
||||
setTimeout(() => {
|
||||
this.setState({
|
||||
visible: false,
|
||||
transitionEnd: false,
|
||||
width: 0,
|
||||
height: 0,
|
||||
});
|
||||
}, transitionDuration);
|
||||
return;
|
||||
|
||||
@ -86,7 +86,6 @@
|
||||
z-index: @zIndex + 5;
|
||||
> img {
|
||||
display: block;
|
||||
margin: 15px auto;
|
||||
width: auto;
|
||||
height: auto;
|
||||
user-select: none;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user