Skip to content

feat: add wheel zoom feature for image preview #6816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"semi": false,
"singleQuote": true,
"printWidth": 80,
"removeUnused": false,
"trailingComma": "none",
"proseWrap": "never"
}
1 change: 1 addition & 0 deletions CHANGELOG.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- `n-modal` adds `draggable` prop, closes [#6525](https://github.com/tusen-ai/naive-ui/issues/6525), [#5792](https://github.com/tusen-ai/naive-ui/issues/5792), [#5711](https://github.com/tusen-ai/naive-ui/issues/5711), [#5501](https://github.com/tusen-ai/naive-ui/issues/5501) and [#2152](https://github.com/tusen-ai/naive-ui/issues/2152).
- `useDialog` supports `draggable` option.
- `useModal` supports `draggable` option.
- `n-image`支持通过`enable-wheel`属性配置是否启用鼠标滚轮缩放,默认为`true`

### Fixes

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- `n-modal` 新增 `draggable` 属性,关闭 [#6525](https://github.com/tusen-ai/naive-ui/issues/6525)、[#5792](https://github.com/tusen-ai/naive-ui/issues/5792)、[#5711](https://github.com/tusen-ai/naive-ui/issues/5711)、[#5501](https://github.com/tusen-ai/naive-ui/issues/5501)、[#2152](https://github.com/tusen-ai/naive-ui/issues/2152)
- `useDialog` 支持 `draggable` 参数
- `useModal` 支持 `draggable` 参数
- `n-image`支持通过`enable-wheel`属性配置是否启用鼠标滚轮缩放,默认为`true`

### Fixes

Expand Down
3 changes: 3 additions & 0 deletions src/image/demos/zhCN/index.demo-entry.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ tooltip.vue
full-debug.vue
lazy.vue
previewed-img-props.vue
wheel-zoom.vue
```

## API
Expand All @@ -25,6 +26,7 @@ previewed-img-props.vue
| 名称 | 类型 | 默认值 | 说明 | 版本 |
| --- | --- | --- | --- | --- |
| alt | `string` | `undefined` | 图片说明 | |
| enable-wheel | `boolean` | `true` | 是否启用鼠标滚轮缩放图片 | 2.41.0 |
| fallback-src | `string` | `undefined` | 图片加载失败时显示的地址 | |
| height | `string \| number` | `undefined` | 图片高度 | |
| img-props | `ImgHTMLAttributes` | `undefined` | 组件中 img 元素的属性 | |
Expand All @@ -46,6 +48,7 @@ previewed-img-props.vue

| 名称 | 类型 | 默认值 | 说明 | 版本 |
| --- | --- | --- | --- | --- |
| enable-wheel | `boolean` | `true` | 是否启用鼠标滚轮缩放图片 | 2.41.0 |
| render-toolbar | `(props: { nodes: { prev: VNode, next: VNode, rotateCounterclockwise: VNode, rotateClockwise: VNode, resizeToOriginalSize: VNode, zoomOut: VNode, zoomIn: VNode, download: VNode, close: VNode } }) => VNodeChild` | `undefined` | 工具栏的渲染函数 | `2.38.2` |
| show-toolbar | `boolean` | `true` | 图片放大后是否展示底部工具栏 | |
| show-toolbar-tooltip | `boolean` | `false` | 是否展示工具栏的提示 | 2.24.0 |
Expand Down
31 changes: 31 additions & 0 deletions src/image/demos/zhCN/wheel-zoom.demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<markdown>
# 鼠标滚轮缩放

使用鼠标滚轮可以放大图片,向下滚动只能缩小到原图大小,不能更小。可以通过`enable-wheel`属性来控制是否启用此功能。
</markdown>

<script lang="ts">
import { defineComponent, ref } from 'vue'

export default defineComponent({
setup() {
return {
enableWheel: ref(true)
}
}
})
</script>

<template>
<n-space vertical>
<n-space>
<n-switch v-model:value="enableWheel" />
<span>启用鼠标滚轮缩放: {{ enableWheel ? '是' : '否' }}</span>
</n-space>
<n-image
width="300"
:enable-wheel="enableWheel"
src="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg"
/>
</n-space>
</template>
1 change: 1 addition & 0 deletions src/image/src/Image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ export default defineComponent({
showToolbar={this.showToolbar}
showToolbarTooltip={this.showToolbarTooltip}
renderToolbar={this.renderToolbar}
enableWheel={this.enableWheel}
>
{{
default: () => imgNode
Expand Down
27 changes: 27 additions & 0 deletions src/image/src/ImagePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,24 @@ export default defineComponent({
}
}

function zoomToOriginalSize(): void {
const originalScale = getOrignalImageSizeScale()
if (scale > originalScale) {
const originalScaleValue = scale
scaleExp = Math.floor(Math.log(originalScale) / Math.log(scaleRadix))
scale = Math.max(originalScale, scaleRadix ** scaleExp)
const diff = originalScaleValue - scale
derivePreviewStyle(false)
const offset = getDerivedOffset()
scale += diff
derivePreviewStyle(false)
scale -= diff
offsetX = offset.offsetX
offsetY = offset.offsetY
derivePreviewStyle()
}
}

function handleDownloadClick(): void {
const src = previewSrcRef.value
if (src) {
Expand Down Expand Up @@ -474,6 +492,14 @@ export default defineComponent({
previewedImgProps: imageContext?.previewedImgPropsRef,
handleWheel(e: WheelEvent) {
e.preventDefault()
if (props.enableWheel && showRef.value) {
if (e.deltaY < 0) {
zoomIn()
}
else {
zoomToOriginalSize()
}
}
},
handlePreviewMousedown,
handlePreviewDblclick,
Expand All @@ -489,6 +515,7 @@ export default defineComponent({
},
zoomIn,
zoomOut,
zoomToOriginalSize,
handleDownloadClick,
rotateCounterclockwise,
rotateClockwise,
Expand Down
3 changes: 2 additions & 1 deletion src/image/src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export const imagePreviewSharedProps = {
onPreviewNext: Function as PropType<() => void>,
showToolbar: { type: Boolean, default: true },
showToolbarTooltip: Boolean,
renderToolbar: Function as PropType<ImageRenderToolbar>
renderToolbar: Function as PropType<ImageRenderToolbar>,
enableWheel: { type: Boolean, default: true }
}

export interface ImageContext {
Expand Down
8 changes: 8 additions & 0 deletions src/image/src/public-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,11 @@ export interface ImageRenderToolbarProps {
export type ImageRenderToolbar = (props: ImageRenderToolbarProps) => VNodeChild
export type ImageGroupRenderToolbarProps = ImageRenderToolbarProps
export type ImageGroupRenderToolbar = ImageRenderToolbar

export interface ImagePreviewProps {
/**
* 是否启用鼠标滚轮缩放图片
* @default true
*/
enableWheel?: boolean
}