Skip to content

Commit

Permalink
fix: Image preview motion (#133)
Browse files Browse the repository at this point in the history
* refactor: use rc-motion

* fix: zoom animation

* chore: refactor code

* fix: do not prevent default keydown event

* refactor: move operations outof Dialog

* fix: motion style

* fix: z-index

* fix: className and z-index

* chore: add enzyme-adapter-react-16 in devDeps

* chore: fix test
  • Loading branch information
afc163 authored Nov 6, 2022
1 parent 935f8f1 commit 178fc51
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 150 deletions.
36 changes: 10 additions & 26 deletions assets/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
.@{prefixCls} {
display: inline-flex;
position: relative;

&-img {
width: 100%;
height: auto;
Expand Down Expand Up @@ -83,8 +84,7 @@
left: 0;
z-index: @zindex-preview-mask;
height: 100%;
background-color: @preview-mask-bg;
filter: ~'alpha(opacity=50)';
background-color: fade(@preview-mask-bg, 45%);

&-hidden {
display: none;
Expand Down Expand Up @@ -145,7 +145,7 @@
width: 100%;
align-items: center;
flex-direction: row-reverse;
z-index: 1;
z-index: @zindex-preview-mask + 1;
color: @text-color;
background: fade(@preview-mask-bg, 45%);

Expand Down Expand Up @@ -184,7 +184,7 @@
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
z-index: @zindex-preview-mask + 1;
pointer-events: auto;
color: @text-color;
&-disabled {
Expand Down Expand Up @@ -212,7 +212,7 @@
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
z-index: @zindex-preview-mask + 1;
pointer-events: auto;
color: @text-color;
&-disabled {
Expand All @@ -232,12 +232,12 @@

.fade-enter,
.fade-appear {
animation-duration: 0.2s;
animation-duration: 0.3s;
animation-fill-mode: both;
animation-play-state: paused;
}
.fade-leave {
animation-duration: 0.2s;
animation-duration: 0.3s;
animation-fill-mode: both;
animation-play-state: paused;
}
Expand Down Expand Up @@ -280,67 +280,51 @@

.zoom-enter,
.zoom-appear {
-webkit-animation-duration: 0.2s;
animation-duration: 0.2s;
-webkit-animation-fill-mode: both;
animation-duration: 0.3s;
animation-fill-mode: both;
-webkit-animation-play-state: paused;
animation-play-state: paused;
}
.zoom-leave {
-webkit-animation-duration: 0.2s;
animation-duration: 0.2s;
-webkit-animation-fill-mode: both;
animation-duration: 0.3s;
animation-fill-mode: both;
-webkit-animation-play-state: paused;
animation-play-state: paused;
}
.zoom-enter.zoom-enter-active,
.zoom-appear.zoom-appear-active {
-webkit-animation-name: rcImageZoomIn;
animation-name: rcImageZoomIn;
-webkit-animation-play-state: running;
animation-play-state: running;
}
.zoom-leave.zoom-leave-active {
-webkit-animation-name: rcImageZoomOut;
animation-name: rcImageZoomOut;
-webkit-animation-play-state: running;
animation-play-state: running;
pointer-events: none;
}
.zoom-enter,
.zoom-appear {
-webkit-transform: scale(0);
transform: scale(0);
opacity: 0;
-webkit-animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1);
animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1);
}
.zoom-leave {
-webkit-animation-timing-function: cubic-bezier(0.78, 0.14, 0.15, 0.86);
animation-timing-function: cubic-bezier(0.78, 0.14, 0.15, 0.86);
}

@keyframes rcImageZoomIn {
0% {
-webkit-transform: scale(0.2);
transform: scale(0.2);
opacity: 0;
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 1;
}
}

@keyframes rcImageZoomOut {
0% {
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
-webkit-transform: scale(0.2);
transform: scale(0.2);
opacity: 0;
}
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
"@umijs/fabric": "^2.2.2",
"cross-env": "^7.0.2",
"dumi": "^1.1.4",
"enzyme": "^3.11.0",
"eslint": "^7.6.0",
"father": "^4.0.0",
"glob": "^7.1.6",
Expand Down
121 changes: 70 additions & 51 deletions src/Preview.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import type { DialogProps as IDialogPropTypes } from 'rc-dialog';
import Dialog from 'rc-dialog';
import CSSMotion from 'rc-motion';
import classnames from 'classnames';
import addEventListener from 'rc-util/lib/Dom/addEventListener';
import KeyCode from 'rc-util/lib/KeyCode';
Expand Down Expand Up @@ -46,6 +47,8 @@ const Preview: React.FC<PreviewProps> = props => {
rootClassName,
countRender,
scaleStep = 0.5,
transitionName = 'zoom',
maskTransitionName = 'fade',
...restProps
} = props;
const { rotateLeft, rotateRight, zoomIn, zoomOut, close, left, right } = icons;
Expand Down Expand Up @@ -211,7 +214,6 @@ const Preview: React.FC<PreviewProps> = props => {
(event: KeyboardEvent) => {
if (!visible || !showLeftOrRightSwitches) return;

event.preventDefault();
if (event.keyCode === KeyCode.LEFT) {
if (currentPreviewIndex > 0) {
setCurrent(previewUrlsKeys[currentPreviewIndex - 1]);
Expand Down Expand Up @@ -280,28 +282,35 @@ const Preview: React.FC<PreviewProps> = props => {
onMouseMoveListener.remove();
onScrollWheelListener.remove();
onKeyDownListener.remove();

/* istanbul ignore next */
if (onTopMouseUpListener) onTopMouseUpListener.remove();
onTopMouseUpListener?.remove();
/* istanbul ignore next */
if (onTopMouseMoveListener) onTopMouseMoveListener.remove();
onTopMouseMoveListener?.remove();
};
}, [visible, isMoving, onKeyDown]);

return (
<Dialog
transitionName="zoom"
maskTransitionName="fade"
closable={false}
keyboard
prefixCls={prefixCls}
onClose={onClose}
afterClose={onAfterClose}
visible={visible}
wrapClassName={wrapClassName}
rootClassName={rootClassName}
{...restProps}
>
const operations = (
<>
{showLeftOrRightSwitches && (
<div
className={classnames(`${prefixCls}-switch-left`, {
[`${prefixCls}-switch-left-disabled`]: currentPreviewIndex === 0,
})}
onClick={onSwitchLeft}
>
{left}
</div>
)}
{showLeftOrRightSwitches && (
<div
className={classnames(`${prefixCls}-switch-right`, {
[`${prefixCls}-switch-right-disabled`]: currentPreviewIndex === previewGroupCount - 1,
})}
onClick={onSwitchRight}
>
{right}
</div>
)}
<ul className={`${prefixCls}-operations`}>
{showOperationsProgress && (
<li className={`${prefixCls}-operations-progress`}>
Expand All @@ -312,6 +321,7 @@ const Preview: React.FC<PreviewProps> = props => {
{tools.map(({ icon, onClick, type, disabled }) => (
<li
className={classnames(toolClassName, {
[`${prefixCls}-operations-operation-${type}`]: true,
[`${prefixCls}-operations-operation-disabled`]: !!disabled,
})}
onClick={onClick}
Expand All @@ -323,43 +333,52 @@ const Preview: React.FC<PreviewProps> = props => {
</li>
))}
</ul>
<div
className={`${prefixCls}-img-wrapper`}
style={{ transform: `translate3d(${position.x}px, ${position.y}px, 0)` }}
</>
);

return (
<>
<Dialog
transitionName={transitionName}
maskTransitionName={maskTransitionName}
closable={false}
keyboard
prefixCls={prefixCls}
onClose={onClose}
afterClose={onAfterClose}
visible={visible}
wrapClassName={wrapClassName}
rootClassName={rootClassName}
{...restProps}
>
<img
width={props.width}
height={props.height}
onMouseDown={onMouseDown}
onDoubleClick={onDoubleClick}
ref={imgRef}
className={`${prefixCls}-img`}
src={combinationSrc}
alt={alt}
style={{ transform: `scale3d(${scale}, ${scale}, 1) rotate(${rotate}deg)` }}
/>
</div>
{showLeftOrRightSwitches && (
<div
className={classnames(`${prefixCls}-switch-left`, {
[`${prefixCls}-switch-left-disabled`]: currentPreviewIndex === 0,
})}
onClick={onSwitchLeft}
>
{left}
</div>
)}
{showLeftOrRightSwitches && (
<div
className={classnames(`${prefixCls}-switch-right`, {
[`${prefixCls}-switch-right-disabled`]: currentPreviewIndex === previewGroupCount - 1,
})}
onClick={onSwitchRight}
className={`${prefixCls}-img-wrapper`}
style={{ transform: `translate3d(${position.x}px, ${position.y}px, 0)` }}
>
{right}
<img
width={props.width}
height={props.height}
onMouseDown={onMouseDown}
onDoubleClick={onDoubleClick}
ref={imgRef}
className={`${prefixCls}-img`}
src={combinationSrc}
alt={alt}
style={{ transform: `scale3d(${scale}, ${scale}, 1) rotate(${rotate}deg)` }}
/>
</div>
)}
</Dialog>
</Dialog>
<CSSMotion visible={visible} motionName={maskTransitionName}>
{({ className, style }) => (
<div
className={className}
style={style}
>
{operations}
</div>
)}
</CSSMotion>
</>
);
};

Expand Down
19 changes: 0 additions & 19 deletions tests/__snapshots__/controlled.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,6 @@ exports[`Controlled With previewVisible 1`] = `
<div
class="rc-image-preview-body"
>
<ul
class="rc-image-preview-operations"
>
<li
class="rc-image-preview-operations-operation"
/>
<li
class="rc-image-preview-operations-operation"
/>
<li
class="rc-image-preview-operations-operation rc-image-preview-operations-operation-disabled"
/>
<li
class="rc-image-preview-operations-operation"
/>
<li
class="rc-image-preview-operations-operation"
/>
</ul>
<div
class="rc-image-preview-img-wrapper"
style="transform: translate3d(0px, 0px, 0);"
Expand Down
40 changes: 21 additions & 19 deletions tests/__snapshots__/preview.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,27 @@ exports[`Preview add rootClassName should be correct when open preview 1`] = `
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
/>
</div>
<div>
<ul
class="rc-image-preview-operations"
>
<li
class="rc-image-preview-operations-operation rc-image-preview-operations-operation-close"
/>
<li
class="rc-image-preview-operations-operation rc-image-preview-operations-operation-zoomIn"
/>
<li
class="rc-image-preview-operations-operation rc-image-preview-operations-operation-zoomOut rc-image-preview-operations-operation-disabled"
/>
<li
class="rc-image-preview-operations-operation rc-image-preview-operations-operation-rotateRight"
/>
<li
class="rc-image-preview-operations-operation rc-image-preview-operations-operation-rotateLeft"
/>
</ul>
</div>
</div>,
<div>
<div
Expand Down Expand Up @@ -50,25 +71,6 @@ exports[`Preview add rootClassName should be correct when open preview 1`] = `
<div
class="rc-image-preview-body"
>
<ul
class="rc-image-preview-operations"
>
<li
class="rc-image-preview-operations-operation"
/>
<li
class="rc-image-preview-operations-operation"
/>
<li
class="rc-image-preview-operations-operation rc-image-preview-operations-operation-disabled"
/>
<li
class="rc-image-preview-operations-operation"
/>
<li
class="rc-image-preview-operations-operation"
/>
</ul>
<div
class="rc-image-preview-img-wrapper"
style="transform: translate3d(0px, 0px, 0);"
Expand Down
Loading

1 comment on commit 178fc51

@vercel
Copy link

@vercel vercel bot commented on 178fc51 Nov 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.