From 36320eb3b62bc450264b617c591a63b929bd81f5 Mon Sep 17 00:00:00 2001 From: Waleed Khaled Date: Thu, 4 Aug 2022 17:28:21 +0400 Subject: [PATCH 1/3] useDevicePixelRatio more efficient mechanism --- packages/core/useDevicePixelRatio/demo.vue | 1 + packages/core/useDevicePixelRatio/index.md | 2 +- packages/core/useDevicePixelRatio/index.ts | 45 ++++++---------------- 3 files changed, 14 insertions(+), 34 deletions(-) diff --git a/packages/core/useDevicePixelRatio/demo.vue b/packages/core/useDevicePixelRatio/demo.vue index 5e369a57651..fe8e8917801 100644 --- a/packages/core/useDevicePixelRatio/demo.vue +++ b/packages/core/useDevicePixelRatio/demo.vue @@ -10,4 +10,5 @@ const code = stringify(pixelRatio) diff --git a/packages/core/useDevicePixelRatio/index.md b/packages/core/useDevicePixelRatio/index.md index 1dc274689be..c7aaadb50b0 100644 --- a/packages/core/useDevicePixelRatio/index.md +++ b/packages/core/useDevicePixelRatio/index.md @@ -6,7 +6,7 @@ category: Sensors Reactively track [`window.devicePixelRatio`](https://developer.mozilla.org/ru/docs/Web/API/Window/devicePixelRatio) > -> NOTE: there is no event listener for `window.devicePixelRatio` change. So this function uses [`Testing media queries programmatically (window.matchMedia)`](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Testing_media_queries) as described in [this example](https://stackoverflow.com/questions/28905420/window-devicepixelratio-change-listener/29653772#29653772), but unlike the example this function subscribes to **several** pixelRatio scales (taken from [mydevice.io](https://www.mydevice.io/)) to detect any `window.devicePixelRatio` change. +> NOTE: there is no event listener for `window.devicePixelRatio` change. So this function uses [`Testing media queries programmatically (window.matchMedia)`](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Testing_media_queries) applying the same mechanism as described in [this example](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#monitoring_screen_resolution_or_zoom_level_changes). ## Usage diff --git a/packages/core/useDevicePixelRatio/index.ts b/packages/core/useDevicePixelRatio/index.ts index b93b2523bb6..2b650806d3d 100644 --- a/packages/core/useDevicePixelRatio/index.ts +++ b/packages/core/useDevicePixelRatio/index.ts @@ -1,24 +1,7 @@ -import { ref, watch } from 'vue-demi' -import { useEventListener } from '../useEventListener' -import { useMediaQuery } from '../useMediaQuery' -import type { ConfigurableWindow } from '../_configurable' -import { defaultWindow } from '../_configurable' +import { ref } from 'vue-demi' +import { type Fn, tryOnScopeDispose } from '@vueuse/shared' +import { type ConfigurableWindow, defaultWindow } from '../_configurable' -// device pixel ratio statistics from https://www.mydevice.io/ -const DEVICE_PIXEL_RATIO_SCALES = [ - 1, - 1.325, - 1.4, - 1.5, - 1.8, - 2, - 2.4, - 2.5, - 2.75, - 3, - 3.5, - 4, -] /** * Reactively track `window.devicePixelRatio`. * @@ -34,21 +17,17 @@ export function useDevicePixelRatio({ } } - const pixelRatio = ref(window.devicePixelRatio) + const pixelRatio = ref(1) - const handleDevicePixelRatio = () => { + let mqResolution: MediaQueryList + tryOnScopeDispose((function MqResolutionObserve(): Fn { pixelRatio.value = window.devicePixelRatio - } - - useEventListener(window, 'resize', handleDevicePixelRatio, { passive: true }) - - DEVICE_PIXEL_RATIO_SCALES.forEach((dppx) => { - // listen mql events in both sides - const mqlMin = useMediaQuery(`screen and (min-resolution: ${dppx}dppx)`) - const mqlMax = useMediaQuery(`screen and (max-resolution: ${dppx}dppx)`) - - watch([mqlMin, mqlMax], handleDevicePixelRatio) - }) + mqResolution = window.matchMedia(`(resolution: ${pixelRatio.value}dppx)`) + mqResolution.addEventListener('change', MqResolutionObserve, { once: true }) + return () => { + mqResolution.removeEventListener('change', MqResolutionObserve) + } + })()) return { pixelRatio } } From d3998e3df192474b64458ebd08574f02d788ac99 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Mon, 5 Sep 2022 21:54:34 +0800 Subject: [PATCH 2/3] chore: update --- packages/core/useDevicePixelRatio/index.ts | 23 ++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/core/useDevicePixelRatio/index.ts b/packages/core/useDevicePixelRatio/index.ts index 2b650806d3d..9de5550ea54 100644 --- a/packages/core/useDevicePixelRatio/index.ts +++ b/packages/core/useDevicePixelRatio/index.ts @@ -20,14 +20,25 @@ export function useDevicePixelRatio({ const pixelRatio = ref(1) let mqResolution: MediaQueryList - tryOnScopeDispose((function MqResolutionObserve(): Fn { + const cleanups: Fn[] = [] + + const cleanup = () => { + cleanups.map(i => i()) + cleanups.length = 0 + } + + const observe = () => { pixelRatio.value = window.devicePixelRatio + cleanup() mqResolution = window.matchMedia(`(resolution: ${pixelRatio.value}dppx)`) - mqResolution.addEventListener('change', MqResolutionObserve, { once: true }) - return () => { - mqResolution.removeEventListener('change', MqResolutionObserve) - } - })()) + mqResolution.addEventListener('change', observe, { once: true }) + cleanups.push(() => { + mqResolution.removeEventListener('change', observe) + }) + } + + observe() + tryOnScopeDispose(cleanup) return { pixelRatio } } From 697e76c61e4f3c62e1bfaf543abb5055c9056050 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Mon, 5 Sep 2022 21:56:01 +0800 Subject: [PATCH 3/3] chore: update --- packages/core/useDevicePixelRatio/index.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/core/useDevicePixelRatio/index.ts b/packages/core/useDevicePixelRatio/index.ts index 9de5550ea54..b0e6f596864 100644 --- a/packages/core/useDevicePixelRatio/index.ts +++ b/packages/core/useDevicePixelRatio/index.ts @@ -19,7 +19,6 @@ export function useDevicePixelRatio({ const pixelRatio = ref(1) - let mqResolution: MediaQueryList const cleanups: Fn[] = [] const cleanup = () => { @@ -30,10 +29,10 @@ export function useDevicePixelRatio({ const observe = () => { pixelRatio.value = window.devicePixelRatio cleanup() - mqResolution = window.matchMedia(`(resolution: ${pixelRatio.value}dppx)`) - mqResolution.addEventListener('change', observe, { once: true }) + const media = window.matchMedia(`(resolution: ${pixelRatio.value}dppx)`) + media.addEventListener('change', observe, { once: true }) cleanups.push(() => { - mqResolution.removeEventListener('change', observe) + media.removeEventListener('change', observe) }) }