Skip to content

Commit

Permalink
Add disableScrollLock option to zoom on hover and zoom on click 💞 (#233)
Browse files Browse the repository at this point in the history
  • Loading branch information
willnguyen1312 authored Oct 11, 2023
1 parent d4ace4c commit 5d3131b
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 40 deletions.
5 changes: 5 additions & 0 deletions .changeset/neat-needles-itch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@zoom-image/core": minor
---

Add disableScrollLock option to zoom on hover and zoom on click 💞
12 changes: 7 additions & 5 deletions packages/core/src/createZoomImageClick.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { createStore } from "@namnode/store"
import { imageLoader } from "./imageLoader"
import { ZoomedImgStatus } from "./types"
import { disableScroll, enableScroll, getSourceImage } from "./utils"
import { disableScroll, enableScroll, getSourceImage, noop } from "./utils"

export type ZoomImageClickOptions = {
zoomFactor?: number
zoomImageSource?: string
disableScrollLock?: boolean
}

export type ZoomImageClickState = {
Expand All @@ -15,11 +16,12 @@ export type ZoomImageClickState = {
export function createZoomImageClick(container: HTMLElement, options: ZoomImageClickOptions = {}) {
const sourceImgElement = getSourceImage(container)
const finalOptions: Required<ZoomImageClickOptions> = {
zoomFactor: options.zoomFactor ?? 4,
zoomFactor: options.zoomFactor ?? 2,
zoomImageSource: options.zoomImageSource ?? sourceImgElement.src,
disableScrollLock: options.disableScrollLock ?? false,
}

const { zoomFactor, zoomImageSource } = finalOptions
const { zoomFactor, zoomImageSource, disableScrollLock } = finalOptions

let isOnMove = false

Expand Down Expand Up @@ -87,8 +89,8 @@ export function createZoomImageClick(container: HTMLElement, options: ZoomImageC
const controller = new AbortController()
const { signal } = controller
container.addEventListener("pointerdown", handlePointerDown, { signal })
container.addEventListener("pointerenter", disableScroll, { signal })
container.addEventListener("pointerleave", enableScroll, { signal })
container.addEventListener("pointerenter", disableScrollLock ? noop : disableScroll, { signal })
container.addEventListener("pointerleave", disableScrollLock ? noop : enableScroll, { signal })
container.addEventListener("pointermove", handlePointerMove, { signal })

return {
Expand Down
20 changes: 16 additions & 4 deletions packages/core/src/createZoomImageHover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type ZoomImageHoverOptions = {
zoomTarget: HTMLElement
zoomTargetClass?: string
scale?: number
disableScrollLock?: boolean
}

export type ZoomImageHoverState = {
Expand Down Expand Up @@ -38,9 +39,19 @@ export function createZoomImageHover(container: HTMLElement, options: ZoomImageH
scale: options.scale || 2,
zoomTarget: options.zoomTarget,
zoomLensScale: options.zoomLensScale || 1,
disableScrollLock: options.disableScrollLock || false,
}

const { scale, zoomImageSource, customZoom, zoomLensClass, zoomTarget, zoomLensScale, zoomTargetClass } = finalOptions
const {
scale,
zoomImageSource,
customZoom,
zoomLensClass,
zoomTarget,
zoomLensScale,
zoomTargetClass,
disableScrollLock,
} = finalOptions

const store = createStore<ZoomImageHoverState>({
zoomedImgStatus: "idle",
Expand Down Expand Up @@ -146,26 +157,27 @@ export function createZoomImageHover(container: HTMLElement, options: ZoomImageH

async function handlePointerEnter() {
imageLoader.createZoomImage(zoomedImg, zoomImageSource, store)

disableScroll()
zoomedImg.style.display = "block"
zoomLens.style.display = "block"

if (zoomTargetClass) {
const classes = zoomTargetClass.split(" ")
classes.forEach((className) => zoomTarget.classList.add(className))
}

if (!disableScrollLock) disableScroll()
}

function handlePointerLeave() {
enableScroll()
zoomedImg.style.display = "none"
zoomLens.style.display = "none"

if (zoomTargetClass) {
const classes = zoomTargetClass.split(" ")
classes.forEach((className) => zoomTarget.classList.remove(className))
}

if (!disableScrollLock) enableScroll()
}

function handleScroll() {
Expand Down
6 changes: 2 additions & 4 deletions packages/core/src/createZoomImageMove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ export function createZoomImageMove(container: HTMLElement, options: ZoomImageMo

processZoom(event)

if (disableScrollLock) return
disableScroll()
if (!disableScrollLock) disableScroll()
}

function handlePointerMove(event: PointerEvent) {
Expand All @@ -67,8 +66,7 @@ export function createZoomImageMove(container: HTMLElement, options: ZoomImageMo
function handlePointerLeave() {
zoomedImg.style.display = "none"
zoomedImg.style.transform = "none"
if (disableScrollLock) return
enableScroll()
if (disableScrollLock) enableScroll()
}

const calculatePositionX = (newPositionX: number) => {
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ export function clamp(value: number, min: number, max: number) {
return Math.max(min, Math.min(max, value))
}

export function noop() {}

function preventDefault(event: Event) {
event.preventDefault()
}
Expand Down
5 changes: 4 additions & 1 deletion packages/docs/src/api/createZoomImageClick.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ type ZoomImageClickState = {
}

type ZoomImageClickOptions = {
// Zoom scale, default is 4
// Zoom scale, default is 2
zoomFactor?: number

// The source of zoomed image, default is the same as the original image
zoomImageSource?: string

// Disable scroll lock on zoom, default is false
disableScrollLock?: boolean
}

function createZoomImageClick(
Expand Down
6 changes: 4 additions & 2 deletions packages/docs/src/api/createZoomImageHover.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ type ZoomImageHoverOptions = {
// The css classes will be added to zoom lens element
zoomLensClass?: string

// By default, zoomLensScale have a value of 1
// The smaller the value, the bigger zoomed image and smaller zoom lens
// The smaller the value, the bigger zoomed image and smaller zoom lens, default is 1
zoomLensScale?: Partial<CSSStyleDeclaration>

// The container of zoomed image
Expand All @@ -50,6 +49,9 @@ type ZoomImageHoverOptions = {

// The scale of zoomed image, default is 2
scale?: number

// Disable scroll lock on zoom, default is false
disableScrollLock?: boolean
}

function createZoomImageHover(
Expand Down
48 changes: 24 additions & 24 deletions size.json
Original file line number Diff line number Diff line change
@@ -1,53 +1,53 @@
{
"@zoom-image/core": {
"createZoomImageWheel": "1.5 KB",
"createZoomImageHover": "1.16 KB",
"createZoomImageWheel": "1.49 KB",
"createZoomImageHover": "1.18 KB",
"createZoomImageMove": "870 B",
"createZoomImageClick": "819 B",
"createZoomImageClick": "847 B",
"cropImage": "202 B",
"makeCalculateZoom": "98 B",
"makeCalculatePercentage": "96 B"
"makeCalculateZoom": "97 B",
"makeCalculatePercentage": "95 B"
},
"@zoom-image/react": {
"useZoomImageWheel": "1.79 KB",
"useZoomImageHover": "1.43 KB",
"useZoomImageHover": "1.45 KB",
"useZoomImageMove": "1.1 KB",
"useZoomImageClick": "1.04 KB"
"useZoomImageClick": "1.08 KB"
},
"@zoom-image/preact": {
"useZoomImageWheel": "2.7 KB",
"useZoomImageHover": "2.37 KB",
"useZoomImageMove": "2.05 KB",
"useZoomImageClick": "1.99 KB"
"useZoomImageHover": "2.38 KB",
"useZoomImageMove": "2.06 KB",
"useZoomImageClick": "2.02 KB"
},
"@zoom-image/qwik": {
"useZoomImageWheel": "1.94 KB",
"useZoomImageHover": "1.56 KB",
"useZoomImageMove": "1.22 KB",
"useZoomImageClick": "1.17 KB"
"useZoomImageWheel": "1.95 KB",
"useZoomImageHover": "1.58 KB",
"useZoomImageMove": "1.23 KB",
"useZoomImageClick": "1.2 KB"
},
"@zoom-image/solid": {
"useZoomImageWheel": "2.98 KB",
"useZoomImageHover": "2.64 KB",
"useZoomImageHover": "2.65 KB",
"useZoomImageMove": "2.32 KB",
"useZoomImageClick": "2.26 KB"
"useZoomImageClick": "2.29 KB"
},
"@zoom-image/svelte": {
"useZoomImageWheel": "1.98 KB",
"useZoomImageHover": "1.63 KB",
"useZoomImageHover": "1.65 KB",
"useZoomImageMove": "1.32 KB",
"useZoomImageClick": "1.26 KB"
"useZoomImageClick": "1.29 KB"
},
"@zoom-image/vue": {
"useZoomImageWheel": "1.76 KB",
"useZoomImageHover": "1.42 KB",
"useZoomImageHover": "1.44 KB",
"useZoomImageMove": "1.08 KB",
"useZoomImageClick": "1.04 KB"
"useZoomImageClick": "1.07 KB"
},
"@zoom-image/angular": {
"ZoomImageClickService": "3.23 KB",
"ZoomImageHoverService": "3.23 KB",
"ZoomImageMoveService": "3.23 KB",
"ZoomImageWheelService": "3.23 KB"
"ZoomImageWheelService": "3.25 KB",
"ZoomImageClickService": "3.25 KB",
"ZoomImageMoveService": "3.25 KB",
"ZoomImageHoverService": "3.25 KB"
}
}

0 comments on commit 5d3131b

Please sign in to comment.