@@ -80,6 +80,47 @@ function ImageGallery({ images }: Props) {
80
80
</ div >
81
81
) )
82
82
83
+ const loadImage = ( url : string ) => {
84
+ const image = new Image ( )
85
+ image . src = url
86
+ return new Promise < HTMLImageElement > ( ( resolve ) => {
87
+ image . onload = ( ) => resolve ( image )
88
+ } )
89
+ }
90
+
91
+ const determineWrapperDimensions = (
92
+ image : { width : number ; height : number } ,
93
+ carouselPadding : number ,
94
+ ) => {
95
+ const { innerWidth, innerHeight } = window
96
+ const aspectRatio = image . width / image . height
97
+ let wrapperX = 0
98
+ let wrapperY = 0
99
+
100
+ if ( image . height > window . innerHeight && image . width < window . innerWidth ) {
101
+ wrapperY = Math . min ( innerHeight - carouselPadding * 2 , image . height )
102
+ wrapperX = wrapperY * aspectRatio
103
+ } else {
104
+ wrapperX = Math . min ( innerWidth - carouselPadding * 2 , image . width )
105
+ wrapperY = wrapperX / aspectRatio
106
+ }
107
+
108
+ return { wrapperX, wrapperY }
109
+ }
110
+
111
+ function calculateTranslationOffsets (
112
+ wrapperX : number ,
113
+ wrapperY : number ,
114
+ translateX : number ,
115
+ translateY : number ,
116
+ zoomValue : number ,
117
+ ) {
118
+ const removeShift = 1 + 1 / zoomValue
119
+ const offsetX = ( wrapperX / 100 ) * ( translateX - 50 ) * removeShift
120
+ const offsetY = ( wrapperY / 100 ) * ( translateY - 50 ) * removeShift
121
+ return { offsetX, offsetY }
122
+ }
123
+
83
124
return (
84
125
< >
85
126
< Slider
@@ -112,34 +153,29 @@ function ImageGallery({ images }: Props) {
112
153
padding : carouselPadding ,
113
154
} }
114
155
on = { {
115
- entered : ( ) => {
156
+ entered : async ( ) => {
116
157
if ( isOpeningWithZoom ) {
117
- const currentImage = new Image ( )
118
- currentImage . src =
119
- images . find ( ( i ) => i . id === galleryId ) ?. url || ''
120
- currentImage . onload = ( ) => {
121
- // determining the container size for the translate
122
- const wrapperX =
123
- window . innerWidth < currentImage . width
124
- ? window . innerWidth - carouselPadding * 2
125
- : currentImage . width
126
- const wrapperY =
127
- window . innerHeight < currentImage . height
128
- ? window . innerHeight - carouselPadding * 2
129
- : currentImage . height
130
-
131
- // removing shifting in the zoom plagin of the yet-another-react-lightbox
132
- const removeShift = 1 + 1 / zoomValue
158
+ const imageUrl =
159
+ images . find ( ( image ) => image . id === galleryId ) ?. url || ''
160
+ if ( ! imageUrl ) {
161
+ console . error ( 'Image URL not found.' )
162
+ return
163
+ }
133
164
134
- // zoomOffset has top left corner as an origin, but translate will be from center of the screen
135
- const translateX = zoomOffsetX - 50
136
- const translateY = zoomOffsetY - 50
165
+ const currentImage = await loadImage ( imageUrl )
166
+ const { wrapperX, wrapperY } = determineWrapperDimensions (
167
+ currentImage ,
168
+ carouselPadding ,
169
+ )
170
+ const { offsetX, offsetY } = calculateTranslationOffsets (
171
+ wrapperX ,
172
+ wrapperY ,
173
+ zoomOffsetX ,
174
+ zoomOffsetY ,
175
+ zoomValue ,
176
+ )
137
177
138
- // calculating the shift, considering that 'translateX/Y' is in percentages, but the yet-another-react-lightbox deals with pixels
139
- const offsetX = ( wrapperX / 100 ) * translateX * removeShift
140
- const offsetY = ( wrapperY / 100 ) * translateY * removeShift
141
- zoomRef . current ?. changeZoom ( zoomValue , true , offsetX , offsetY )
142
- }
178
+ zoomRef . current ?. changeZoom ( zoomValue , true , offsetX , offsetY )
143
179
}
144
180
setZoom ( 0 , 0 , 0 )
145
181
setIsOpeningWithZoom ( false )
0 commit comments