diff --git a/assets/index.less b/assets/index.less
index 89eb30ca..463075ed 100644
--- a/assets/index.less
+++ b/assets/index.less
@@ -22,6 +22,7 @@
 .@{prefixCls} {
   display: inline-flex;
   position: relative;
+
   &-img {
     width: 100%;
     height: auto;
@@ -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;
@@ -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%);
 
@@ -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 {
@@ -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 {
@@ -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;
 }
@@ -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;
   }
diff --git a/package.json b/package.json
index 3768fc86..4bc9bdc1 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/src/Preview.tsx b/src/Preview.tsx
index bd0c7ca0..67ecf329 100644
--- a/src/Preview.tsx
+++ b/src/Preview.tsx
@@ -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';
@@ -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;
@@ -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]);
@@ -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`}>
@@ -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}
@@ -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>
+    </>
   );
 };
 
diff --git a/tests/__snapshots__/controlled.test.tsx.snap b/tests/__snapshots__/controlled.test.tsx.snap
index c1f6669e..10196b93 100644
--- a/tests/__snapshots__/controlled.test.tsx.snap
+++ b/tests/__snapshots__/controlled.test.tsx.snap
@@ -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);"
diff --git a/tests/__snapshots__/preview.test.tsx.snap b/tests/__snapshots__/preview.test.tsx.snap
index 70955d0b..cff0a190 100644
--- a/tests/__snapshots__/preview.test.tsx.snap
+++ b/tests/__snapshots__/preview.test.tsx.snap
@@ -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
@@ -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);"
diff --git a/tests/__snapshots__/previewGroup.test.tsx.snap b/tests/__snapshots__/previewGroup.test.tsx.snap
index dd5e1136..f43a1640 100644
--- a/tests/__snapshots__/previewGroup.test.tsx.snap
+++ b/tests/__snapshots__/previewGroup.test.tsx.snap
@@ -17,30 +17,6 @@ exports[`PreviewGroup With Controlled 1`] = `
     <div
       class="rc-image-preview-body"
     >
-      <ul
-        class="rc-image-preview-operations"
-      >
-        <li
-          class="rc-image-preview-operations-progress"
-        >
-          1 / 1
-        </li>
-        <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);"
diff --git a/tests/previewGroup.test.tsx b/tests/previewGroup.test.tsx
index f227604f..2a94e4f4 100644
--- a/tests/previewGroup.test.tsx
+++ b/tests/previewGroup.test.tsx
@@ -28,7 +28,7 @@ describe('PreviewGroup', () => {
     expect(document.querySelector('.rc-image-preview')).toBeTruthy();
 
     const previewProgressElement = document.querySelector(
-      '.rc-image-preview .rc-image-preview-operations-progress',
+      '.rc-image-preview-operations-progress',
     );
 
     expect(previewProgressElement).toBeTruthy();
@@ -73,7 +73,7 @@ describe('PreviewGroup', () => {
     });
 
     const previewProgressElement = document.querySelector(
-      '.rc-image-preview .rc-image-preview-operations-progress',
+      '.rc-image-preview-operations-progress',
     );
 
     expect(previewProgressElement).toBeTruthy();
@@ -81,7 +81,7 @@ describe('PreviewGroup', () => {
   });
 
   it('Switch', () => {
-    const previewProgressElementPath = '.rc-image-preview .rc-image-preview-operations-progress';
+    const previewProgressElementPath = '.rc-image-preview-operations-progress';
     const { container } = render(
       <Image.PreviewGroup>
         <Image src="src1" />
@@ -96,27 +96,27 @@ describe('PreviewGroup', () => {
     });
 
     expect(
-      document.querySelector('.rc-image-preview .rc-image-preview-switch-left-disabled'),
+      document.querySelector('.rc-image-preview-switch-left-disabled'),
     ).toBeTruthy();
     expect(document.querySelector(previewProgressElementPath).textContent).toEqual('1 / 2');
 
-    fireEvent.click(document.querySelector('.rc-image-preview .rc-image-preview-switch-right'));
+    fireEvent.click(document.querySelector('.rc-image-preview-switch-right'));
     act(() => {
       jest.runAllTimers();
     });
 
     expect(
-      document.querySelector('.rc-image-preview .rc-image-preview-switch-right-disabled'),
+      document.querySelector('.rc-image-preview-switch-right-disabled'),
     ).toBeTruthy();
     expect(document.querySelector(previewProgressElementPath).textContent).toEqual('2 / 2');
 
-    fireEvent.click(document.querySelector('.rc-image-preview .rc-image-preview-switch-left'));
+    fireEvent.click(document.querySelector('.rc-image-preview-switch-left'));
     act(() => {
       jest.runAllTimers();
     });
 
     expect(
-      document.querySelector('.rc-image-preview .rc-image-preview-switch-left-disabled'),
+      document.querySelector('.rc-image-preview-switch-left-disabled'),
     ).toBeTruthy();
 
     fireEvent.keyDown(window, { keyCode: KeyCode.RIGHT });
@@ -125,7 +125,7 @@ describe('PreviewGroup', () => {
     });
 
     expect(
-      document.querySelector('.rc-image-preview .rc-image-preview-switch-right-disabled'),
+      document.querySelector('.rc-image-preview-switch-right-disabled'),
     ).toBeTruthy();
 
     fireEvent.keyDown(window, { keyCode: KeyCode.LEFT });
@@ -134,7 +134,7 @@ describe('PreviewGroup', () => {
     });
 
     expect(
-      document.querySelector('.rc-image-preview .rc-image-preview-switch-left-disabled'),
+      document.querySelector('.rc-image-preview-switch-left-disabled'),
     ).toBeTruthy();
   });