diff --git a/README.md b/README.md index 9c6d4fdf..1cc24bde 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ export default () => ( | Name | Type | Default | Description | | --- | --- | --- | --- | -| visible | boolean | - | Whether the preview is open or not | +| open | boolean | - | Whether the preview is open or not | | closeIcon | React.ReactNode | - | Custom close icon | | src | string | - | Customize preview src | | movable | boolean | true | Enable drag | @@ -87,8 +87,8 @@ export default () => ( | forceRender | boolean | - | Force render preview | | getContainer | string \| HTMLElement \| (() => HTMLElement) \| false | document.body | Return the mount node for preview | | imageRender | (originalNode: React.ReactElement, info: { transform: [TransformType](#TransformType) }) => React.ReactNode | - | Customize image | -| toolbarRender | (originalNode: React.ReactElement, info: Omit<[ToolbarRenderInfoType](#ToolbarRenderInfoType), 'current' \| 'total'>) => React.ReactNode | - | Customize toolbar | -| onVisibleChange | (visible: boolean, prevVisible: boolean) => void | - | Callback when visible is changed | +| actionsRender | (originalNode: React.ReactElement, info: Omit<[ToolbarRenderInfoType](#ToolbarRenderInfoType), 'current' \| 'total'>) => React.ReactNode | - | Customize toolbar | +| onOpenChange | (open: boolean, prevVisible: boolean) => void | - | Callback when open is changed | | onTransform | { transform: [TransformType](#TransformType), action: [TransformAction](#TransformAction) } | - | Callback when transform is changed | ## Image.PreviewGroup @@ -120,7 +120,7 @@ export default () => ( | Name | Type | Default | Description | | --- | --- | --- | --- | -| visible | boolean | - | Whether the preview is open or not | +| open | boolean | - | Whether the preview is open or not | | movable | boolean | true | Enable drag | | current | number | - | Current index | | closeIcon | React.ReactNode | - | Custom close icon | @@ -131,8 +131,8 @@ export default () => ( | getContainer | string \| HTMLElement \| (() => HTMLElement) \| false | document.body | Return the mount node for preview | | countRender | (current: number, total: number) => ReactNode | - | Customize count | | imageRender | (originalNode: React.ReactElement, info: { transform: [TransformType](#TransformType), current: number }) => React.ReactNode | - | Customize image | -| toolbarRender | (originalNode: React.ReactElement, info: [ToolbarRenderInfoType](#ToolbarRenderInfoType)) => React.ReactNode | - | Customize toolbar | -| onVisibleChange | (visible: boolean, prevVisible: boolean, current: number) => void | - | Callback when visible is changed | +| actionsRender | (originalNode: React.ReactElement, info: [ToolbarRenderInfoType](#ToolbarRenderInfoType)) => React.ReactNode | - | Customize toolbar | +| onOpenChange | (open: boolean, prevVisible: boolean, current: number) => void | - | Callback when open is changed | | onTransform | { transform: [TransformType](#TransformType), action: [TransformAction](#TransformAction) } | - | Callback when transform is changed | ### TransformType diff --git a/assets/index.less b/assets/index.less index c0999ccf..1afaa2b5 100644 --- a/assets/index.less +++ b/assets/index.less @@ -1,3 +1,5 @@ +@import 'preview.less'; + @prefixCls: rc-image; @zindex-preview-mask: 1000; @preview-mask-bg: fade(#000, 100%); @@ -6,31 +8,31 @@ @background-color: #f3f3f3; .reset() { + box-sizing: border-box; margin: 0; padding: 0; - box-sizing: border-box; } .box() { position: absolute; top: 0; - left: 0; right: 0; bottom: 0; + left: 0; } .@{prefixCls} { - display: inline-flex; position: relative; + display: inline-flex; &-img { width: 100%; height: auto; &-placeholder { background-color: @background-color; + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjhweCIgaGVpZ2h0PSIyMnB4IiB2aWV3Qm94PSIwIDAgMjggMjIiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDU1LjIgKDc4MTgxKSAtIGh0dHBzOi8vc2tldGNoYXBwLmNvbSAtLT4KICAgIDx0aXRsZT5pbWFnZS1maWxs5aSH5Lu9PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGcgaWQ9Iuafpeeci+WbvueJh+S8mOWMljQuMCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IuWKoOi9veWbvueJhyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTU3Mi4wMDAwMDAsIC01MDYuMDAwMDAwKSI+CiAgICAgICAgICAgIDxnIGlkPSJpbWFnZS1maWxs5aSH5Lu9IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1NzAuMDAwMDAwLCA1MDEuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlIiBmaWxsPSIjMDAwMDAwIiBvcGFjaXR5PSIwIiB4PSIwIiB5PSIwIiB3aWR0aD0iMzIiIGhlaWdodD0iMzIiPjwvcmVjdD4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yOSw1IEwzLDUgQzIuNDQ2ODc1LDUgMiw1LjQ0Njg3NSAyLDYgTDIsMjYgQzIsMjYuNTUzMTI1IDIuNDQ2ODc1LDI3IDMsMjcgTDI5LDI3IEMyOS41NTMxMjUsMjcgMzAsMjYuNTUzMTI1IDMwLDI2IEwzMCw2IEMzMCw1LjQ0Njg3NSAyOS41NTMxMjUsNSAyOSw1IFogTTEwLjU2MjUsOS41IEMxMS42NjU2MjUsOS41IDEyLjU2MjUsMTAuMzk2ODc1IDEyLjU2MjUsMTEuNSBDMTIuNTYyNSwxMi42MDMxMjUgMTEuNjY1NjI1LDEzLjUgMTAuNTYyNSwxMy41IEM5LjQ1OTM3NSwxMy41IDguNTYyNSwxMi42MDMxMjUgOC41NjI1LDExLjUgQzguNTYyNSwxMC4zOTY4NzUgOS40NTkzNzUsOS41IDEwLjU2MjUsOS41IFogTTI2LjYyMTg3NSwyMy4xNTkzNzUgQzI2LjU3ODEyNSwyMy4xOTY4NzUgMjYuNTE4NzUsMjMuMjE4NzUgMjYuNDU5Mzc1LDIzLjIxODc1IEw1LjUzNzUsMjMuMjE4NzUgQzUuNCwyMy4yMTg3NSA1LjI4NzUsMjMuMTA2MjUgNS4yODc1LDIyLjk2ODc1IEM1LjI4NzUsMjIuOTA5Mzc1IDUuMzA5Mzc1LDIyLjg1MzEyNSA1LjM0Njg3NSwyMi44MDYyNSBMMTAuNjY4NzUsMTYuNDkzNzUgQzEwLjc1NjI1LDE2LjM4NzUgMTAuOTE1NjI1LDE2LjM3NSAxMS4wMjE4NzUsMTYuNDYyNSBDMTEuMDMxMjUsMTYuNDcxODc1IDExLjA0Mzc1LDE2LjQ4MTI1IDExLjA1MzEyNSwxNi40OTM3NSBMMTQuMTU5Mzc1LDIwLjE4MTI1IEwxOS4xLDE0LjMyMTg3NSBDMTkuMTg3NSwxNC4yMTU2MjUgMTkuMzQ2ODc1LDE0LjIwMzEyNSAxOS40NTMxMjUsMTQuMjkwNjI1IEMxOS40NjI1LDE0LjMgMTkuNDc1LDE0LjMwOTM3NSAxOS40ODQzNzUsMTQuMzIxODc1IEwyNi42NTkzNzUsMjIuODA5Mzc1IEMyNi43NDA2MjUsMjIuOTEyNSAyNi43MjgxMjUsMjMuMDcxODc1IDI2LjYyMTg3NSwyMy4xNTkzNzUgWiIgaWQ9IlNoYXBlIiBmaWxsPSIjRThFOEU4Ij48L3BhdGg+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==); background-repeat: no-repeat; background-position: center center; - background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjhweCIgaGVpZ2h0PSIyMnB4IiB2aWV3Qm94PSIwIDAgMjggMjIiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDU1LjIgKDc4MTgxKSAtIGh0dHBzOi8vc2tldGNoYXBwLmNvbSAtLT4KICAgIDx0aXRsZT5pbWFnZS1maWxs5aSH5Lu9PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGcgaWQ9Iuafpeeci+WbvueJh+S8mOWMljQuMCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IuWKoOi9veWbvueJhyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTU3Mi4wMDAwMDAsIC01MDYuMDAwMDAwKSI+CiAgICAgICAgICAgIDxnIGlkPSJpbWFnZS1maWxs5aSH5Lu9IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1NzAuMDAwMDAwLCA1MDEuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlIiBmaWxsPSIjMDAwMDAwIiBvcGFjaXR5PSIwIiB4PSIwIiB5PSIwIiB3aWR0aD0iMzIiIGhlaWdodD0iMzIiPjwvcmVjdD4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yOSw1IEwzLDUgQzIuNDQ2ODc1LDUgMiw1LjQ0Njg3NSAyLDYgTDIsMjYgQzIsMjYuNTUzMTI1IDIuNDQ2ODc1LDI3IDMsMjcgTDI5LDI3IEMyOS41NTMxMjUsMjcgMzAsMjYuNTUzMTI1IDMwLDI2IEwzMCw2IEMzMCw1LjQ0Njg3NSAyOS41NTMxMjUsNSAyOSw1IFogTTEwLjU2MjUsOS41IEMxMS42NjU2MjUsOS41IDEyLjU2MjUsMTAuMzk2ODc1IDEyLjU2MjUsMTEuNSBDMTIuNTYyNSwxMi42MDMxMjUgMTEuNjY1NjI1LDEzLjUgMTAuNTYyNSwxMy41IEM5LjQ1OTM3NSwxMy41IDguNTYyNSwxMi42MDMxMjUgOC41NjI1LDExLjUgQzguNTYyNSwxMC4zOTY4NzUgOS40NTkzNzUsOS41IDEwLjU2MjUsOS41IFogTTI2LjYyMTg3NSwyMy4xNTkzNzUgQzI2LjU3ODEyNSwyMy4xOTY4NzUgMjYuNTE4NzUsMjMuMjE4NzUgMjYuNDU5Mzc1LDIzLjIxODc1IEw1LjUzNzUsMjMuMjE4NzUgQzUuNCwyMy4yMTg3NSA1LjI4NzUsMjMuMTA2MjUgNS4yODc1LDIyLjk2ODc1IEM1LjI4NzUsMjIuOTA5Mzc1IDUuMzA5Mzc1LDIyLjg1MzEyNSA1LjM0Njg3NSwyMi44MDYyNSBMMTAuNjY4NzUsMTYuNDkzNzUgQzEwLjc1NjI1LDE2LjM4NzUgMTAuOTE1NjI1LDE2LjM3NSAxMS4wMjE4NzUsMTYuNDYyNSBDMTEuMDMxMjUsMTYuNDcxODc1IDExLjA0Mzc1LDE2LjQ4MTI1IDExLjA1MzEyNSwxNi40OTM3NSBMMTQuMTU5Mzc1LDIwLjE4MTI1IEwxOS4xLDE0LjMyMTg3NSBDMTkuMTg3NSwxNC4yMTU2MjUgMTkuMzQ2ODc1LDE0LjIwMzEyNSAxOS40NTMxMjUsMTQuMjkwNjI1IEMxOS40NjI1LDE0LjMgMTkuNDc1LDE0LjMwOTM3NSAxOS40ODQzNzUsMTQuMzIxODc1IEwyNi42NTkzNzUsMjIuODA5Mzc1IEMyNi43NDA2MjUsMjIuOTEyNSAyNi43MjgxMjUsMjMuMDcxODc1IDI2LjYyMTg3NSwyMy4xNTkzNzUgWiIgaWQ9IlNoYXBlIiBmaWxsPSIjRThFOEU4Ij48L3BhdGg+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==); } } @@ -41,294 +43,294 @@ // >>> Mask &-mask { position: absolute; - left: 0; - right: 0; top: 0; + right: 0; bottom: 0; - background: rgba(0, 0, 0, 0.3); - opacity: 0; - pointer-events: none; + left: 0; display: flex; align-items: center; justify-content: center; color: #fff; + background: rgba(0, 0, 0, 0.3); + opacity: 0; transition: opacity 0.3s; - } - - &:hover &-mask { - opacity: 1; - } - - &-preview { - text-align: center; - height: 100%; pointer-events: none; - - &-body { - .box; - overflow: hidden; - } - - &.zoom-enter, - &.zoom-appear { - transform: none; - opacity: 0; - animation-duration: 0.3s; - } - - &-mask { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: @zindex-preview-mask; - height: 100%; - background-color: fade(@preview-mask-bg, 45%); - - &-hidden { - display: none; - } - } - - &-img { - cursor: grab; - transform: scale3d(1, 1, 1); - transition: transform 0.3s cubic-bezier(0, 0, 0.25, 1) 0s; - user-select: none; - vertical-align: middle; - max-width: 100%; - max-height: 70%; - - &-wrapper { - .box; - display: flex; - justify-content: center; - align-items: center; - - & > * { - pointer-events: auto; - } - } - } - - &-moving { - .@{prefixCls}-preview-img { - cursor: grabbing; - &-wrapper { - transition-duration: 0s; - } - } - } - - &-wrap { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: @zindex-preview-mask; - overflow: auto; - outline: 0; - -webkit-overflow-scrolling: touch; - } - - &-close { - position: fixed; - top: 32px; - right: 32px; - display: flex; - color: #fff; - background-color: rgba(0, 0, 0, 0.5); - border-radius: 50%; - padding: 15px; - outline: 0; - border: 0; - cursor: pointer; - - &:hover { - opacity: 0.3; - } - } - - &-operations-wrapper { - position: fixed; - z-index: @zindex-preview-mask + 1; - } - - &-footer { - position: fixed; - z-index: @zindex-preview-mask + 1; - bottom: 32px; - left: 0; - width: 100%; - display: flex; - flex-direction: column; - align-items: center; - } - - &-progress { - margin-bottom: 20px; - } - - &-operations { - display: flex; - color: @text-color; - background: fade(@preview-mask-bg, 45%); - border-radius: 100px; - padding: 0 20px; - - &-operation { - padding: 10px; - cursor: pointer; - margin-left: 10px; - font-size: 18px; - &-disabled { - pointer-events: none; - color: @text-color-disabled; - } - &:first-of-type { - margin-left: 0; - } - } - } - - &-switch-left { - position: fixed; - left: 10px; - top: 50%; - width: 44px; - height: 44px; - margin-top: -22px; - background: fade(@text-color, 45%); - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - z-index: @zindex-preview-mask + 1; - cursor: pointer; - color: @text-color; - &-disabled { - background: fade(@text-color, 30%); - color: @text-color-disabled; - cursor: not-allowed; - > .anticon { - cursor: not-allowed; - } - } - > .anticon { - font-size: 24px; - } - } - - &-switch-right { - position: fixed; - right: 10px; - top: 50%; - width: 44px; - height: 44px; - margin-top: -22px; - background: fade(@text-color, 45%); - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - z-index: @zindex-preview-mask + 1; - cursor: pointer; - color: @text-color; - &-disabled { - background: fade(@text-color, 20%); - color: @text-color-disabled; - cursor: not-allowed; - > .anticon { - cursor: not-allowed; - } - } - > .anticon { - font-size: 24px; - } - } } -} - -.fade-enter, -.fade-appear { - animation-duration: 0.3s; - animation-fill-mode: both; - animation-play-state: paused; -} -.fade-leave { - animation-duration: 0.3s; - animation-fill-mode: both; - animation-play-state: paused; -} -.fade-enter.fade-enter-active, -.fade-appear.fade-appear-active { - animation-name: rcImageFadeIn; - animation-play-state: running; -} -.fade-leave.fade-leave-active { - animation-name: rcImageFadeOut; - animation-play-state: running; - pointer-events: none; -} -.fade-enter, -.fade-appear { - opacity: 0; - animation-timing-function: linear; -} -.fade-leave { - animation-timing-function: linear; -} -@keyframes rcImageFadeIn { - 0% { - opacity: 0; - } - 100% { + &:hover &-mask { opacity: 1; } -} -@keyframes rcImageFadeOut { - 0% { - opacity: 1; - } - 100% { - opacity: 0; - } + // &-preview { + // height: 100%; + // text-align: center; + // pointer-events: none; + + // &-body { + // .box; + // overflow: hidden; + // } + + // // &.zoom-enter, + // // &.zoom-appear { + // // transform: none; + // // opacity: 0; + // // animation-duration: 0.3s; + // // } + + // &-mask { + // position: fixed; + // top: 0; + // right: 0; + // bottom: 0; + // left: 0; + // z-index: @zindex-preview-mask; + // height: 100%; + // background-color: fade(@preview-mask-bg, 45%); + + // &-hidden { + // display: none; + // } + // } + + // &-img { + // max-width: 100%; + // max-height: 70%; + // vertical-align: middle; + // transform: scale3d(1, 1, 1); + // cursor: grab; + // transition: transform 0.3s cubic-bezier(0, 0, 0.25, 1) 0s; + // user-select: none; + + // &-wrapper { + // .box; + // display: flex; + // align-items: center; + // justify-content: center; + + // & > * { + // pointer-events: auto; + // } + // } + // } + + // &-moving { + // .@{prefixCls}-preview-img { + // cursor: grabbing; + // &-wrapper { + // transition-duration: 0s; + // } + // } + // } + + // &-wrap { + // position: fixed; + // top: 0; + // right: 0; + // bottom: 0; + // left: 0; + // z-index: @zindex-preview-mask; + // overflow: auto; + // outline: 0; + // -webkit-overflow-scrolling: touch; + // } + + // &-close { + // position: fixed; + // top: 32px; + // right: 32px; + // display: flex; + // padding: 15px; + // color: #fff; + // background-color: rgba(0, 0, 0, 0.5); + // border: 0; + // border-radius: 50%; + // outline: 0; + // cursor: pointer; + + // &:hover { + // opacity: 0.3; + // } + // } + + // &-operations-wrapper { + // position: fixed; + // z-index: @zindex-preview-mask + 1; + // } + + // &-footer { + // position: fixed; + // bottom: 32px; + // left: 0; + // z-index: @zindex-preview-mask + 1; + // display: flex; + // flex-direction: column; + // align-items: center; + // width: 100%; + // } + + // &-progress { + // margin-bottom: 20px; + // } + + // &-operations { + // display: flex; + // padding: 0 20px; + // color: @text-color; + // background: fade(@preview-mask-bg, 45%); + // border-radius: 100px; + + // &-operation { + // margin-left: 10px; + // padding: 10px; + // font-size: 18px; + // cursor: pointer; + // &-disabled { + // color: @text-color-disabled; + // pointer-events: none; + // } + // &:first-of-type { + // margin-left: 0; + // } + // } + // } + + // &-switch-left { + // position: fixed; + // top: 50%; + // left: 10px; + // z-index: @zindex-preview-mask + 1; + // display: flex; + // align-items: center; + // justify-content: center; + // width: 44px; + // height: 44px; + // margin-top: -22px; + // color: @text-color; + // background: fade(@text-color, 45%); + // border-radius: 50%; + // cursor: pointer; + // &-disabled { + // color: @text-color-disabled; + // background: fade(@text-color, 30%); + // cursor: not-allowed; + // > .anticon { + // cursor: not-allowed; + // } + // } + // > .anticon { + // font-size: 24px; + // } + // } + + // &-switch-right { + // position: fixed; + // top: 50%; + // right: 10px; + // z-index: @zindex-preview-mask + 1; + // display: flex; + // align-items: center; + // justify-content: center; + // width: 44px; + // height: 44px; + // margin-top: -22px; + // color: @text-color; + // background: fade(@text-color, 45%); + // border-radius: 50%; + // cursor: pointer; + // &-disabled { + // color: @text-color-disabled; + // background: fade(@text-color, 20%); + // cursor: not-allowed; + // > .anticon { + // cursor: not-allowed; + // } + // } + // > .anticon { + // font-size: 24px; + // } + // } + // } } -.zoom-enter, -.zoom-appear { - animation-duration: 0.3s; - animation-fill-mode: both; - animation-play-state: paused; -} -.zoom-leave { - animation-duration: 0.3s; - animation-fill-mode: both; - animation-play-state: paused; -} -.zoom-enter.zoom-enter-active, -.zoom-appear.zoom-appear-active { - animation-name: rcImageZoomIn; - animation-play-state: running; -} -.zoom-leave.zoom-leave-active { - animation-name: rcImageZoomOut; - animation-play-state: running; - pointer-events: none; -} -.zoom-enter, -.zoom-appear { - transform: scale(0); - opacity: 0; - animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1); -} -.zoom-leave { - animation-timing-function: cubic-bezier(0.78, 0.14, 0.15, 0.86); -} +// .fade-enter, +// .fade-appear { +// animation-duration: 0.3s; +// animation-play-state: paused; +// animation-fill-mode: both; +// } +// .fade-leave { +// animation-duration: 0.3s; +// animation-play-state: paused; +// animation-fill-mode: both; +// } +// .fade-enter.fade-enter-active, +// .fade-appear.fade-appear-active { +// animation-name: rcImageFadeIn; +// animation-play-state: running; +// } +// .fade-leave.fade-leave-active { +// animation-name: rcImageFadeOut; +// animation-play-state: running; +// pointer-events: none; +// } +// .fade-enter, +// .fade-appear { +// opacity: 0; +// animation-timing-function: linear; +// } +// .fade-leave { +// animation-timing-function: linear; +// } + +// @keyframes rcImageFadeIn { +// 0% { +// opacity: 0; +// } +// 100% { +// opacity: 1; +// } +// } + +// @keyframes rcImageFadeOut { +// 0% { +// opacity: 1; +// } +// 100% { +// opacity: 0; +// } +// } + +// .zoom-enter, +// .zoom-appear { +// animation-duration: 0.3s; +// animation-play-state: paused; +// animation-fill-mode: both; +// } +// .zoom-leave { +// animation-duration: 0.3s; +// animation-play-state: paused; +// animation-fill-mode: both; +// } +// .zoom-enter.zoom-enter-active, +// .zoom-appear.zoom-appear-active { +// animation-name: rcImageZoomIn; +// animation-play-state: running; +// } +// .zoom-leave.zoom-leave-active { +// animation-name: rcImageZoomOut; +// animation-play-state: running; +// pointer-events: none; +// } +// .zoom-enter, +// .zoom-appear { +// transform: scale(0); +// opacity: 0; +// animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1); +// } +// .zoom-leave { +// animation-timing-function: cubic-bezier(0.78, 0.14, 0.15, 0.86); +// } @keyframes rcImageZoomIn { 0% { diff --git a/assets/preview.less b/assets/preview.less new file mode 100644 index 00000000..dc7eff3f --- /dev/null +++ b/assets/preview.less @@ -0,0 +1,147 @@ +@import (reference) 'index.less'; + +.@{prefixCls}-preview { + position: fixed; + overflow: hidden; + user-select: none; + inset: 0; + + &-mask { + position: absolute; + background-color: rgba(0, 0, 0, 0.3); + inset: 0; + } + + &-body { + position: absolute; + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; + inset: 0; + + > * { + pointer-events: auto; + } + } + + &-img { + max-width: 100%; + max-height: 70%; + } + + // =================== Close ==================== + &-close { + position: absolute; + top: 16px; + right: 16px; + z-index: 1; + width: 32px; + height: 32px; + color: #fff; + background: rgba(0, 0, 0, 0.3); + border: 0; + border-radius: 99px; + cursor: pointer; + } + + // =================== Switch =================== + &-switch { + position: absolute; + top: 50%; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + color: #fff; + background: rgba(0, 0, 0, 0.3); + border-radius: 9999px; + transform: translateY(-50%); + cursor: pointer; + + &-disabled { + cursor: default; + opacity: 0.1; + } + + &-prev { + inset-inline-start: 0; + } + + &-next { + inset-inline-end: 0; + } + } + + // =================== Footer =================== + &-footer { + position: absolute; + bottom: 24px; + left: 50%; + z-index: 1; + display: flex; + flex-direction: column; + gap: 16px; + align-items: center; + transform: translateX(-50%); + } + + &-progress { + color: #fff; + } + + // =================== Action =================== + &-actions { + display: flex; + gap: 8px; + padding: 8px 16px; + background: rgba(0, 0, 0, 0.3); + border-radius: 12px; + + &-action { + color: #fff; + cursor: pointer; + + &-disabled { + cursor: default; + opacity: 0.5; + } + } + } + + // =================== Motion =================== + &.fade { + // Basic fade + transition: all 0.3s; + + // Fade in + &-enter, + &-appear { + opacity: 0; + + .@{prefixCls}-preview-body { + transform: scale(0); + } + + &-active { + opacity: 1; + + .@{prefixCls}-preview-body { + transform: scale(1); + transition: all 0.3s; + } + } + } + + // Fade out + &-leave { + opacity: 1; + + &-active { + opacity: 0; + } + } + } +} diff --git a/docs/demo/actionsRender.md b/docs/demo/actionsRender.md new file mode 100644 index 00000000..6a6cd676 --- /dev/null +++ b/docs/demo/actionsRender.md @@ -0,0 +1,8 @@ +--- +title: actionsRender +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/toolbarRender.md b/docs/demo/toolbarRender.md deleted file mode 100644 index e5f21be7..00000000 --- a/docs/demo/toolbarRender.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: toolbarRender -nav: - title: Demo - path: /demo ---- - - diff --git a/docs/examples/toolbarRender.tsx b/docs/examples/actionsRender.tsx similarity index 96% rename from docs/examples/toolbarRender.tsx rename to docs/examples/actionsRender.tsx index 8ee8214f..1b9e1b84 100644 --- a/docs/examples/toolbarRender.tsx +++ b/docs/examples/actionsRender.tsx @@ -11,7 +11,7 @@ export default function ToolbarRender() { width={200} preview={{ icons: defaultIcons, - toolbarRender: ( + actionsRender: ( _, { actions: { @@ -55,7 +55,7 @@ export default function ToolbarRender() { imageRender(_, { image }) { return
{JSON.stringify(image)}
; }, - toolbarRender(_, { image }) { + actionsRender(_, { image }) { return
{JSON.stringify(image)}
; }, }} diff --git a/docs/examples/basic.tsx b/docs/examples/basic.tsx index ff690afd..dd70505a 100644 --- a/docs/examples/basic.tsx +++ b/docs/examples/basic.tsx @@ -17,8 +17,8 @@ export default function Base() { }} preview={{ icons: defaultIcons, - onVisibleChange: visible => { - console.log('visible', visible); + onOpenChange: open => { + console.log('open', open); }, zIndex: 9999, }} @@ -30,7 +30,7 @@ export default function Base() { style={{ marginRight: 24, }} - preview={{ icons: defaultIcons, mask: 'Click to Preview' }} + preview={{ icons: defaultIcons, cover: 'Click to Preview' }} />
); diff --git a/docs/examples/fallback.tsx b/docs/examples/fallback.tsx index 36317362..8d61ebd5 100644 --- a/docs/examples/fallback.tsx +++ b/docs/examples/fallback.tsx @@ -6,7 +6,7 @@ import { defaultIcons } from './common'; export default function Base() { return ( null, + actionsRender: () => null, imageRender: () => (