Fix focal point cropping in MediaGallery, fix focal point modal (#6740)
* Use object-position with object-fit instead of JS top/left * Fix focal point modal
This commit is contained in:
		
							parent
							
								
									56333cca88
								
							
						
					
					
						commit
						56eb5c3f34
					
				
					 3 changed files with 23 additions and 62 deletions
				
			
		|  | @ -12,26 +12,6 @@ const messages = defineMessages({ | |||
|   toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Toggle visibility' }, | ||||
| }); | ||||
| 
 | ||||
| const shiftToPoint = (containerToImageRatio, containerSize, imageSize, focusSize, toMinus) => { | ||||
|   const containerCenter = Math.floor(containerSize / 2); | ||||
|   const focusFactor     = (focusSize + 1) / 2; | ||||
|   const scaledImage     = Math.floor(imageSize / containerToImageRatio); | ||||
| 
 | ||||
|   let focus = Math.floor(focusFactor * scaledImage); | ||||
| 
 | ||||
|   if (toMinus) focus = scaledImage - focus; | ||||
| 
 | ||||
|   let focusOffset = focus - containerCenter; | ||||
| 
 | ||||
|   const remainder = scaledImage - focus; | ||||
|   const containerRemainder = containerSize - containerCenter; | ||||
| 
 | ||||
|   if (remainder < containerRemainder) focusOffset -= containerRemainder - remainder; | ||||
|   if (focusOffset < 0) focusOffset = 0; | ||||
| 
 | ||||
|   return (focusOffset * -100 / containerSize) + '%'; | ||||
| }; | ||||
| 
 | ||||
| class Item extends React.PureComponent { | ||||
| 
 | ||||
|   static contextTypes = { | ||||
|  | @ -44,8 +24,6 @@ class Item extends React.PureComponent { | |||
|     index: PropTypes.number.isRequired, | ||||
|     size: PropTypes.number.isRequired, | ||||
|     onClick: PropTypes.func.isRequired, | ||||
|     containerWidth: PropTypes.number, | ||||
|     containerHeight: PropTypes.number, | ||||
|   }; | ||||
| 
 | ||||
|   static defaultProps = { | ||||
|  | @ -84,7 +62,7 @@ class Item extends React.PureComponent { | |||
|   } | ||||
| 
 | ||||
|   render () { | ||||
|     const { attachment, index, size, standalone, containerWidth, containerHeight } = this.props; | ||||
|     const { attachment, index, size, standalone } = this.props; | ||||
| 
 | ||||
|     let width  = 50; | ||||
|     let height = 100; | ||||
|  | @ -143,45 +121,16 @@ class Item extends React.PureComponent { | |||
| 
 | ||||
|       const originalUrl    = attachment.get('url'); | ||||
|       const originalWidth  = attachment.getIn(['meta', 'original', 'width']); | ||||
|       const originalHeight = attachment.getIn(['meta', 'original', 'height']); | ||||
| 
 | ||||
|       const hasSize = typeof originalWidth === 'number' && typeof previewWidth === 'number'; | ||||
| 
 | ||||
|       const srcSet = hasSize ? `${originalUrl} ${originalWidth}w, ${previewUrl} ${previewWidth}w` : null; | ||||
|       const sizes  = hasSize ? `(min-width: 1025px) ${320 * (width / 100)}px, ${width}vw` : null; | ||||
| 
 | ||||
|       const focusX     = attachment.getIn(['meta', 'focus', 'x']); | ||||
|       const focusY     = attachment.getIn(['meta', 'focus', 'y']); | ||||
|       const imageStyle = {}; | ||||
| 
 | ||||
|       if (originalWidth && originalHeight && containerWidth && containerHeight && focusX && focusY) { | ||||
|         const widthRatio  = originalWidth / (containerWidth * (width / 100)); | ||||
|         const heightRatio = originalHeight / (containerHeight * (height / 100)); | ||||
| 
 | ||||
|         let hShift = 0; | ||||
|         let vShift = 0; | ||||
| 
 | ||||
|         if (widthRatio > heightRatio) { | ||||
|           hShift = shiftToPoint(heightRatio, (containerWidth * (width / 100)), originalWidth, focusX); | ||||
|         } else if(widthRatio < heightRatio) { | ||||
|           vShift = shiftToPoint(widthRatio, (containerHeight * (height / 100)), originalHeight, focusY, true); | ||||
|         } | ||||
| 
 | ||||
|         if (originalWidth > originalHeight) { | ||||
|           imageStyle.height   = '100%'; | ||||
|           imageStyle.width    = 'auto'; | ||||
|           imageStyle.minWidth = '100%'; | ||||
|         } else { | ||||
|           imageStyle.height    = 'auto'; | ||||
|           imageStyle.width     = '100%'; | ||||
|           imageStyle.minHeight = '100%'; | ||||
|         } | ||||
| 
 | ||||
|         imageStyle.top  = vShift; | ||||
|         imageStyle.left = hShift; | ||||
|       } else { | ||||
|         imageStyle.height = '100%'; | ||||
|       } | ||||
|       const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0; | ||||
|       const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0; | ||||
|       const x      = ((focusX /  2) + .5) * 100; | ||||
|       const y      = ((focusY / -2) + .5) * 100; | ||||
| 
 | ||||
|       thumbnail = ( | ||||
|         <a | ||||
|  | @ -196,7 +145,7 @@ class Item extends React.PureComponent { | |||
|             sizes={sizes} | ||||
|             alt={attachment.get('description')} | ||||
|             title={attachment.get('description')} | ||||
|             style={imageStyle} | ||||
|             style={{ objectPosition: `${x}% ${y}%` }} | ||||
|           /> | ||||
|         </a> | ||||
|       ); | ||||
|  | @ -320,7 +269,7 @@ export default class MediaGallery extends React.PureComponent { | |||
|       if (this.isStandaloneEligible()) { | ||||
|         children = <Item standalone onClick={this.handleClick} attachment={media.get(0)} />; | ||||
|       } else { | ||||
|         children = media.take(4).map((attachment, i) => <Item key={attachment.get('id')} onClick={this.handleClick} attachment={attachment} index={i} size={size} containerWidth={width} containerHeight={style.height} />); | ||||
|         children = media.take(4).map((attachment, i) => <Item key={attachment.get('id')} onClick={this.handleClick} attachment={attachment} index={i} size={size} />); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -103,7 +103,7 @@ export default class FocalPointModal extends ImmutablePureComponent { | |||
|     const height = media.getIn(['meta', 'original', 'height']) || null; | ||||
| 
 | ||||
|     return ( | ||||
|       <div className='modal-root__modal video-modal'> | ||||
|       <div className='modal-root__modal video-modal focal-point-modal'> | ||||
|         <div className={classNames('focal-point', { dragging })} ref={this.setRef}> | ||||
|           <ImageLoader | ||||
|             previewSrc={media.get('preview_url')} | ||||
|  |  | |||
|  | @ -4315,18 +4315,16 @@ a.status-card { | |||
|   display: block; | ||||
|   text-decoration: none; | ||||
|   color: $ui-secondary-color; | ||||
|   height: 100%; | ||||
|   line-height: 0; | ||||
| 
 | ||||
|   &, | ||||
|   img { | ||||
|     height: 100%; | ||||
|     width: 100%; | ||||
|   } | ||||
| 
 | ||||
|   img { | ||||
|     position: relative; | ||||
|     object-fit: cover; | ||||
|     height: auto; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -5076,6 +5074,12 @@ noscript { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| .focal-point-modal { | ||||
|   max-width: 80vw; | ||||
|   max-height: 80vh; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .focal-point { | ||||
|   position: relative; | ||||
|   cursor: pointer; | ||||
|  | @ -5085,6 +5089,14 @@ noscript { | |||
|     cursor: move; | ||||
|   } | ||||
| 
 | ||||
|   img { | ||||
|     max-width: 80vw; | ||||
|     max-height: 80vh; | ||||
|     width: auto; | ||||
|     height: auto; | ||||
|     margin: auto; | ||||
|   } | ||||
| 
 | ||||
|   &__reticle { | ||||
|     position: absolute; | ||||
|     width: 100px; | ||||
|  |  | |||
		Reference in a new issue