commit: 56eb5c3f344f0342ac6f26a05748bc21c585a729
parent: 56333cca88325b492861fe218d993d8a56acf575
Author: Eugen Rochko <eugen@zeonfederated.com>
Date: Sun, 11 Mar 2018 15:12:33 +0100
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
Diffstat:
3 files changed, 23 insertions(+), 62 deletions(-)
diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js
@@ -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} />);
}
}
diff --git a/app/javascript/mastodon/features/ui/components/focal_point_modal.js b/app/javascript/mastodon/features/ui/components/focal_point_modal.js
@@ -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')}
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
@@ -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;