react-smartpicture
Version:
Crop and center images with a focuspoint
175 lines (144 loc) • 8.92 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* Created by christian.lorenz.hh@gmail.com on 17.09.18.
*/
var SmartPicture = function (_Component) {
_inherits(SmartPicture, _Component);
function SmartPicture(props) {
_classCallCheck(this, SmartPicture);
var _this = _possibleConstructorReturn(this, (SmartPicture.__proto__ || Object.getPrototypeOf(SmartPicture)).call(this, props));
_this.pivotToCenter = props.pivotToCenter ? props.pivotToCenter : false;
_this.position = props.position ? props.position : "relative";
_this.containerElement = _react2.default.createRef();
_this.imgElement = _react2.default.createRef();
_this.currentContainerWidth = _this.currentContainerHeight = 0;
_this.forceResize = false;
_this.startLoop = _this.startLoop.bind(_this);
_this.checkChanges = _this.checkChanges.bind(_this);
return _this;
}
_createClass(SmartPicture, [{
key: 'componentWillUnmount',
value: function componentWillUnmount() {
window.cancelAnimationFrame(this.frameId);
}
}, {
key: 'startLoop',
value: function startLoop() {
this.forceResize = true;
if (!this.frameId) {
this.frameId = window.requestAnimationFrame(this.checkChanges);
}
}
}, {
key: 'checkChanges',
value: function checkChanges() {
var containerWidth = this.containerElement.current.clientWidth;
var containerHeight = this.containerElement.current.clientHeight;
if (this.imgElement.current.complete && (containerWidth !== this.currentContainerWidth || containerHeight !== this.currentContainerHeight || this.forceResize)) {
this.resizeImage();
this.forceResize = false;
this.currentContainerWidth = containerWidth;
this.currentContainerHeight = containerHeight;
}
this.frameId = window.requestAnimationFrame(this.checkChanges);
}
}, {
key: 'resizeImage',
value: function resizeImage() {
var cX = void 0,
cY = void 0,
ratio = void 0,
xOffset = void 0,
yOffset = void 0,
newImageWidth = void 0,
newImageHeight = void 0;
var containerWidth = this.containerElement.current.clientWidth;
var containerHeight = this.containerElement.current.clientHeight;
var imageWidth = this.imgElement.current.clientWidth;
var imageHeight = this.imgElement.current.clientHeight;
var ratioX = containerWidth / imageWidth;
var ratioY = containerHeight / imageHeight;
ratio = ratioX > ratioY ? ratioX : ratioY;
newImageWidth = Math.ceil(imageWidth * ratio);
newImageHeight = Math.ceil(imageHeight * ratio);
if (this.pivotToCenter) {
cX = this.props.focus && this.props.focus.x ? (1 + this.props.focus.x) / 2 : 0.5;
cY = this.props.focus && this.props.focus.y ? (1 - this.props.focus.y) / 2 : 0.5;
} else {
cX = this.props.focus && this.props.focus.x ? this.props.focus.x : 0.5;
cY = this.props.focus && this.props.focus.y ? this.props.focus.y : 0;
}
xOffset = (containerWidth - newImageWidth) * cX;
yOffset = (containerHeight - newImageHeight) * cY;
this.imgElement.current.style.left = xOffset + "px";
this.imgElement.current.style.top = yOffset + "px";
this.imgElement.current.style.width = newImageWidth + "px";
if (this.props.onResize) {
this.props.onResize(this);
}
}
}, {
key: 'render',
value: function render() {
if (this.props.sources) {
return _react2.default.createElement(
'div',
{ ref: this.containerElement, id: this.props.id, className: this.props.containerClassName,
style: { position: this.position, "overflow": "hidden" } },
_react2.default.createElement(
'picture',
null,
this.props.sources.map(function (item, index) {
return _react2.default.createElement('source', { key: index,
media: "(" + item.media + ")",
srcSet: item.srcSet
});
}),
_react2.default.createElement('img', {
style: { position: "absolute", verticalAlign: "top" },
ref: this.imgElement,
src: this.props.src,
alt: this.props.alt,
onLoad: this.startLoop
})
)
);
} else {
return _react2.default.createElement(
'div',
{ ref: this.containerElement, id: this.props.id, style: { position: this.position, "overflow": "hidden" },
className: this.props.containerClassName },
_react2.default.createElement('img', { onLoad: this.startLoop,
ref: this.imgElement,
style: { position: "absolute" },
src: this.props.src,
alt: this.props.alt
})
);
}
}
}]);
return SmartPicture;
}(_react.Component);
SmartPicture.propTypes = {
src: _propTypes2.default.string.isRequired,
alt: _propTypes2.default.string,
position: _propTypes2.default.string,
containerClassName: _propTypes2.default.string,
sources: _propTypes2.default.array,
onResize: _propTypes2.default.func,
pivotToCenter: _propTypes2.default.bool
};
exports.default = SmartPicture;