From 174cbb42e52419f856dd6802255aba38f7e0b4d0 Mon Sep 17 00:00:00 2001 From: Timmy Willison <4timmywil@gmail.com> Date: Mon, 20 Dec 2021 16:37:31 -0500 Subject: [PATCH] fix(roundpixels): roundPixels should affect x/y in constrain --- README.md | 115 +++++++++++++++++++++----------------- src/css.ts | 4 -- src/panzoom.ts | 6 ++ src/types.ts | 11 +++- test/unit/css.test.ts | 13 +---- test/unit/panzoom.test.ts | 58 +++++++++++-------- 6 files changed, 118 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index eb2e23ef..55a454dd 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ Add `text-rendering="geometricPrecision"` to your `` elements. #### Defined in -[panzoom.ts:58](https://github.com/timmywil/panzoom/blob/1d28755/src/panzoom.ts#L58) +[panzoom.ts:58](https://github.com/timmywil/panzoom/blob/41498a7/src/panzoom.ts#L58) ## `PanzoomOptions` @@ -182,7 +182,7 @@ Whether to animate transitions #### Defined in -[types.ts:21](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L21) +[types.ts:21](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L21) ### canvas @@ -199,7 +199,7 @@ where the `cursor` style is applied (i.e. the parent). #### Defined in -[types.ts:32](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L32) +[types.ts:32](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L32) ### duration @@ -209,7 +209,7 @@ Duration of the transition (ms) #### Defined in -[types.ts:34](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L34) +[types.ts:34](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L34) ### easing @@ -219,7 +219,7 @@ CSS Easing used for transitions #### Defined in -[types.ts:36](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L36) +[types.ts:36](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L36) ### exclude @@ -232,7 +232,7 @@ e.g. links and buttons that should not propagate the click event. #### Defined in -[types.ts:43](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L43) +[types.ts:43](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L43) ### excludeClass @@ -245,7 +245,7 @@ e.g. links and buttons that should not propagate the click event. #### Defined in -[types.ts:50](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L50) +[types.ts:50](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L50) ### force @@ -267,7 +267,7 @@ panzoom.zoom(1, { force: true }) #### Defined in -[types.ts:66](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L66) +[types.ts:66](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L66) ### noBind @@ -277,7 +277,7 @@ Skip binding the default Panzoom event listeners #### Defined in -[types.ts:95](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L95) +[types.ts:95](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L95) ### origin @@ -297,7 +297,7 @@ And again, changing this for SVG in IE doesn't work at all. #### Defined in -[types.ts:109](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L109) +[types.ts:109](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L109) ### overflow @@ -307,7 +307,7 @@ The overflow CSS value for the parent. Defaults to 'hidden' #### Defined in -[types.ts:111](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L111) +[types.ts:111](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L111) ### setTransform @@ -345,7 +345,7 @@ const panzoom = Panzoom(elem, { #### Defined in -[types.ts:115](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L115) +[types.ts:115](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L115) ### silent @@ -355,7 +355,7 @@ Silence all events #### Defined in -[types.ts:117](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L117) +[types.ts:117](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L117) ### startScale @@ -365,7 +365,7 @@ Scale used to set the beginning transform #### Defined in -[types.ts:123](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L123) +[types.ts:123](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L123) ### startX @@ -375,7 +375,7 @@ X Value used to set the beginning transform #### Defined in -[types.ts:119](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L119) +[types.ts:119](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L119) ### startY @@ -385,7 +385,7 @@ Y Value used to set the beginning transform #### Defined in -[types.ts:121](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L121) +[types.ts:121](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L121) ### touchAction @@ -401,7 +401,7 @@ cannot work at the same time. #### Defined in -[types.ts:133](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L133) +[types.ts:133](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L133) ## Methods @@ -444,7 +444,7 @@ Panzoom(elem, { #### Defined in -[types.ts:91](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L91) +[types.ts:91](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L91) ## PanOptions (includes MiscOptions) @@ -466,7 +466,7 @@ empty space around the element will be shown. #### Defined in -[types.ts:152](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L152) +[types.ts:152](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L152) ### cursor @@ -476,7 +476,7 @@ The cursor style to set on the panzoom element #### Defined in -[types.ts:154](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L154) +[types.ts:154](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L154) ### disablePan @@ -488,7 +488,7 @@ The element will still pan accordingly. #### Defined in -[types.ts:160](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L160) +[types.ts:160](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L160) ### disableXAxis @@ -498,7 +498,7 @@ Pan only on the Y axis #### Defined in -[types.ts:162](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L162) +[types.ts:162](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L162) ### disableYAxis @@ -508,7 +508,7 @@ Pan only on the X axis #### Defined in -[types.ts:164](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L164) +[types.ts:164](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L164) ### panOnlyWhenZoomed @@ -518,7 +518,7 @@ Disable panning while the scale is equal to the starting value #### Defined in -[types.ts:168](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L168) +[types.ts:168](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L168) ### relative @@ -528,7 +528,22 @@ When passing x and y values to .pan(), treat the values as relative to their cur #### Defined in -[types.ts:166](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L166) +[types.ts:166](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L166) + +### roundPixels + +• `Optional` **roundPixels**: `boolean` + +Round x and y values to whole numbers. +This can help prevent images and text from looking blurry, +but the higher the scale, the more it becomes +necessary to use fractional pixels. +Use your own judgment on how much to limit +zooming in when using this option. + +#### Defined in + +[types.ts:177](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L177) ## ZoomOptions (includes MiscOptions) @@ -540,7 +555,7 @@ Disable zooming functionality #### Defined in -[types.ts:173](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L173) +[types.ts:182](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L182) ### focal @@ -560,7 +575,7 @@ to the parent dimensions. #### Defined in -[types.ts:180](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L180) +[types.ts:189](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L189) ### maxScale @@ -570,7 +585,7 @@ The maximum scale when zooming #### Defined in -[types.ts:184](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L184) +[types.ts:193](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L193) ### minScale @@ -580,7 +595,7 @@ The minimum scale when zooming #### Defined in -[types.ts:182](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L182) +[types.ts:191](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L191) ### step @@ -590,7 +605,7 @@ The step affects zoom calculation when zooming with a mouse wheel, when pinch zo #### Defined in -[types.ts:186](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L186) +[types.ts:195](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L195) ## PanzoomObject @@ -614,7 +629,7 @@ Pointer or Touch events. #### Defined in -[types.ts:221](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L221) +[types.ts:230](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L230) ## Methods @@ -639,7 +654,7 @@ panzoom.bind() #### Defined in -[types.ts:213](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L213) +[types.ts:222](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L222) ### destroy @@ -653,7 +668,7 @@ Remove all event listeners bound to the the Panzoom element #### Defined in -[types.ts:215](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L215) +[types.ts:224](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L224) ### getOptions @@ -667,7 +682,7 @@ Returns a _copy_ of the current options object #### Defined in -[types.ts:227](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L227) +[types.ts:236](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L236) ### getPan @@ -686,7 +701,7 @@ Get the current x/y translation #### Defined in -[types.ts:223](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L223) +[types.ts:232](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L232) ### getScale @@ -700,7 +715,7 @@ Get the current scale #### Defined in -[types.ts:225](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L225) +[types.ts:234](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L234) ### pan @@ -729,7 +744,7 @@ panzoom.pan(10, 10, { relative: true }) #### Defined in -[types.ts:238](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L238) +[types.ts:247](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L247) ### reset @@ -758,7 +773,7 @@ panzoom.reset({ animate: false }) #### Defined in -[types.ts:251](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L251) +[types.ts:260](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L260) ### resetStyle @@ -777,7 +792,7 @@ panzoom.resetStyle() #### Defined in -[types.ts:260](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L260) +[types.ts:269](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L269) ### setOptions @@ -806,7 +821,7 @@ panzoom.setOptions({ cursor: 'default' }) #### Defined in -[types.ts:273](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L273) +[types.ts:282](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L282) ### setStyle @@ -827,7 +842,7 @@ A convenience method for setting prefixed styles on the Panzoom element #### Defined in -[types.ts:275](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L275) +[types.ts:284](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L284) ### zoom @@ -853,7 +868,7 @@ panzoom.zoom(2.2, { animate: true }) #### Defined in -[types.ts:284](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L284) +[types.ts:293](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L293) ### zoomIn @@ -880,7 +895,7 @@ panzoom.zoomIn({ animate: false }) #### Defined in -[types.ts:295](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L295) +[types.ts:304](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L304) ### zoomOut @@ -907,7 +922,7 @@ panzoom.zoomOut({ animate: false }) #### Defined in -[types.ts:306](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L306) +[types.ts:315](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L315) ### zoomToPoint @@ -938,7 +953,7 @@ panzoom.zoomToPoint(1.2, pointerEvent) #### Defined in -[types.ts:317](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L317) +[types.ts:326](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L326) ### zoomWithWheel @@ -984,7 +999,7 @@ elem.parentElement.addEventListener('wheel', function (event) { #### Defined in -[types.ts:350](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L350) +[types.ts:359](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L359) ## CurrentValues @@ -994,7 +1009,7 @@ elem.parentElement.addEventListener('wheel', function (event) { #### Defined in -[types.ts:197](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L197) +[types.ts:206](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L206) ### scale @@ -1002,7 +1017,7 @@ elem.parentElement.addEventListener('wheel', function (event) { #### Defined in -[types.ts:196](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L196) +[types.ts:205](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L205) ### x @@ -1010,7 +1025,7 @@ elem.parentElement.addEventListener('wheel', function (event) { #### Defined in -[types.ts:194](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L194) +[types.ts:203](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L203) ### y @@ -1018,7 +1033,7 @@ elem.parentElement.addEventListener('wheel', function (event) { #### Defined in -[types.ts:195](https://github.com/timmywil/panzoom/blob/1d28755/src/types.ts#L195) +[types.ts:204](https://github.com/timmywil/panzoom/blob/41498a7/src/types.ts#L204) ## Events diff --git a/src/css.ts b/src/css.ts index 8bc5546f..66d41621 100644 --- a/src/css.ts +++ b/src/css.ts @@ -100,10 +100,6 @@ export function setTransform( { x, y, scale, isSVG }: CurrentValues, _options?: PanzoomOptions ) { - if (_options !== undefined && _options.roundToPixels) { - x = Math.round(x) - y = Math.round(y) - } setStyle(elem, 'transform', `scale(${scale}) translate(${x}px, ${y}px)`) if (isSVG && isIE) { const matrixValue = window.getComputedStyle(elem).getPropertyValue('transform') diff --git a/src/panzoom.ts b/src/panzoom.ts index 917dfa11..2eabdc81 100644 --- a/src/panzoom.ts +++ b/src/panzoom.ts @@ -271,6 +271,12 @@ function Panzoom( result.y = Math.max(Math.min(result.y, maxY), minY) } } + + if (opts.roundPixels) { + result.x = Math.round(result.x) + result.y = Math.round(result.y) + } + return result } diff --git a/src/types.ts b/src/types.ts index 2e402943..d130188e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -166,8 +166,15 @@ export interface PanOnlyOptions { relative?: boolean /** Disable panning while the scale is equal to the starting value */ panOnlyWhenZoomed?: boolean - /** Round transform-translate x and values to whole pixels. (Prevents images getting blurry) */ - roundToPixels?: boolean + /** + * Round x and y values to whole numbers. + * This can help prevent images and text from looking blurry, + * but the higher the scale, the more it becomes + * necessary to use fractional pixels. + * Use your own judgment on how much to limit + * zooming in when using this option. + */ + roundPixels?: boolean } export interface ZoomOnlyOptions { diff --git a/test/unit/css.test.ts b/test/unit/css.test.ts index bbd69191..1dce613e 100644 --- a/test/unit/css.test.ts +++ b/test/unit/css.test.ts @@ -1,6 +1,7 @@ -import { strict as assert } from 'assert' import { setStyle, setTransform } from '../../src/css' +import { strict as assert } from 'assert' + function assertStyle(elem: HTMLElement | SVGElement, name: string, value: string) { const capName = name[0].toUpperCase() + name.slice(1) const style: any = elem.style @@ -42,15 +43,5 @@ describe('css', () => { setTransform(elem, { x: 1, y: 1, scale: 1 }) assertStyle(elem, 'transform', 'scale(1) translate(1px, 1px)') }) - it('sets the default transform-origin property with roundToPixels = true for HTML', () => { - const elem = document.createElement('div') - setTransform(elem, { x: 1.25, y: 1.75, scale: 1 }, { roundToPixels: true }) - assertStyle(elem, 'transform', 'scale(1) translate(1px, 2px)') - }) - it('sets the default transform-origin property with roundToPixels = true for SCG', () => { - const elem = document.createElementNS('http://www.w3.org/2000/svg', 'g') - setTransform(elem, { x: 1.25, y: 1.75, scale: 1 }, { roundToPixels: true }) - assertStyle(elem, 'transform', 'scale(1) translate(1px, 2px)') - }) }) }) diff --git a/test/unit/panzoom.test.ts b/test/unit/panzoom.test.ts index 6382a07d..3524242a 100644 --- a/test/unit/panzoom.test.ts +++ b/test/unit/panzoom.test.ts @@ -370,27 +370,41 @@ describe('Panzoom', () => { }) }) describe('noBind option', () => { - const div = document.createElement('div') - document.body.appendChild(div) - const events: any = {} // eslint-disable-line - const addEvent = Element.prototype.addEventListener - const removeEvent = Element.prototype.removeEventListener - // eslint-disable-next-line - Element.prototype.addEventListener = function (event: any, fn: any, options: any) { - events[event] = fn - addEvent.call(this, event, fn, options) - } - // eslint-disable-next-line - Element.prototype.removeEventListener = function (event: any, fn: any, options: any) { - delete events[event] - removeEvent.call(this, event, fn, options) - } - const panzoom = Panzoom(div, { noBind: true }) - assert(Object.keys(events).length === 0) - panzoom.bind() - assert(Object.keys(events).length > 0) - Element.prototype.addEventListener = addEvent - Element.prototype.removeEventListener = removeEvent - document.body.removeChild(div) + it('does not bind event handlers', () => { + const div = document.createElement('div') + document.body.appendChild(div) + const events: any = {} // eslint-disable-line + const addEvent = Element.prototype.addEventListener + const removeEvent = Element.prototype.removeEventListener + // eslint-disable-next-line + Element.prototype.addEventListener = function (event: any, fn: any, options: any) { + events[event] = fn + addEvent.call(this, event, fn, options) + } + // eslint-disable-next-line + Element.prototype.removeEventListener = function (event: any, fn: any, options: any) { + delete events[event] + removeEvent.call(this, event, fn, options) + } + const panzoom = Panzoom(div, { noBind: true }) + assert(Object.keys(events).length === 0) + panzoom.bind() + assert(Object.keys(events).length > 0) + Element.prototype.addEventListener = addEvent + Element.prototype.removeEventListener = removeEvent + document.body.removeChild(div) + }) + }) + describe('roundPixels option', () => { + it('rounds x and y', () => { + const div = document.createElement('div') + document.body.appendChild(div) + const panzoom = Panzoom(div, { roundPixels: true }) + panzoom.pan(1.25, 1.25) + const pan = panzoom.getPan() + assert.strictEqual(pan.x, 1) + assert.strictEqual(pan.y, 1) + document.body.removeChild(div) + }) }) })