generic-zoom
Version:
Medium zoom like functionality, but working by simply transforming the element. Suited for children that adjust automatically depending on the parent element width - such as gatsby-image. (Note that for use with react, use the generic-medium-zoom-react p
124 lines (118 loc) • 6.57 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var getScrollX = function (elem) {
return elem.getBoundingClientRect().left;
};
var getScrollY = function (elem) {
return elem.getBoundingClientRect().top;
};
var calculateScale = function (outerWidth, outerHeight, innerWidth, innerHeight, margin) {
var scaleX = (outerWidth - 2 * margin.horizontal) / innerWidth;
var scaleY = (outerHeight - 2 * margin.vertical) / innerHeight;
return Math.min(scaleX, scaleY);
};
function calculatePosition(outerElem, targetElem) {
var outerElemRect = outerElem.getBoundingClientRect();
var targetElemRect = targetElem.getBoundingClientRect();
var outerElemCenterX = outerElemRect.width / 2;
var outerElemCenterY = outerElemRect.height / 2;
var targetElemCenterX = targetElemRect.width / 2;
var targetElemCenterY = targetElemRect.height / 2;
var diffOffsetLeft = getScrollX(outerElem) - getScrollX(targetElem); // TODO: Test what if target element is scrolled down from start?
var diffOffsetTop = getScrollY(outerElem) - getScrollY(targetElem); // TODO: Test what if target element is scrolled down from start?
var translateX = outerElemCenterX - targetElemCenterX + diffOffsetLeft;
var translateY = outerElemCenterY - targetElemCenterY + diffOffsetTop;
return { translateX: translateX, translateY: translateY };
}
var GenericZoom = /** @class */ (function () {
function GenericZoom(_a) {
var _this = this;
var _b = _a.transitionDuration, transitionDuration = _b === void 0 ? 300 : _b, outerElem = _a.outerElem, elemToZoom = _a.elemToZoom, elemToZoomWrapper = _a.elemToZoomWrapper, _c = _a.activeZIndex, activeZIndex = _c === void 0 ? 11 : _c, _d = _a.zoomMargin, zoomMargin = _d === void 0 ? { vertical: 50, horizontal: 50 } : _d;
this.isZoomed = false;
this.applyZoom = function () {
var elemToZoomWrapperRect = _this.elemToZoomWrapper.getBoundingClientRect();
var outerElemRect = _this.outerElem.getBoundingClientRect();
var _a = calculatePosition(_this.outerElem, _this.elemToZoomWrapper), translateX = _a.translateX, translateY = _a.translateY;
var scale = calculateScale(outerElemRect.width, outerElemRect.height, elemToZoomWrapperRect.width, elemToZoomWrapperRect.height, _this.zoomMargin);
_this.elemToZoom.style.zIndex = "" + _this.activeZIndex;
_this.elemToZoom.style.transform = "translate3d(\n " + translateX + "px,\n " + translateY + "px,\n 0) scale(" + scale + ")";
};
this.onTransitionEnd = function () {
if (_this.isZoomed)
return;
_this.elemToZoom.style.zIndex = 'inherit';
_this.elemToZoom.removeEventListener('transitionend', _this.onTransitionEnd);
};
this.activeZIndex = activeZIndex;
this.transitionDuration = transitionDuration;
this.outerElem = outerElem;
this.elemToZoomWrapper = elemToZoomWrapper;
this.elemToZoom = elemToZoom;
this.zoomMargin = zoomMargin;
this.elemToZoom.style.position = 'relative';
this.elemToZoom.style.transition = "transform " + this.transitionDuration + "ms";
}
GenericZoom.prototype.zoom = function () {
this.isZoomed = true;
this.applyZoom();
window.addEventListener('resize', this.applyZoom);
};
GenericZoom.prototype.unZoom = function () {
this.isZoomed = false;
window.removeEventListener('resize', this.applyZoom);
if (!this.elemToZoom)
return;
this.elemToZoom.addEventListener('transitionend', this.onTransitionEnd);
this.elemToZoom.style.transform = "translate3d(\n 0px,\n 0px,\n 0) scale(1)";
};
return GenericZoom;
}());
var INACTIVE_ZINDEX = '-1';
var ZoomOverlay = /** @class */ (function () {
function ZoomOverlay(_a) {
var _this = this;
var outerElem = _a.outerElem, overlayElem = _a.overlayElem, _b = _a.transitionDuration, transitionDuration = _b === void 0 ? 300 : _b, _c = _a.backgroundColor, backgroundColor = _c === void 0 ? '#fff' : _c, _d = _a.activeZIndex, activeZIndex = _d === void 0 ? 10 : _d;
this.isZoomed = false;
this.onTransitionEnd = function () {
// in case the use zooms again before the ontransitionend is called
_this.zoomOverlay.removeEventListener('transitionend', _this.onTransitionEnd);
if (_this.isZoomed)
return;
_this.zoomOverlay.style.transform = "translate3d(0px, 0px, 0";
_this.zoomOverlay.style.zIndex = INACTIVE_ZINDEX;
};
this.applyZoom = function () {
// Reset transform so position can be calculated correctly
_this.zoomOverlay.style.transform = "translate3d(0px, 0px, 0";
_this.zoomOverlay.style.width = _this.outerElem.getBoundingClientRect().width + "px";
_this.zoomOverlay.style.height = _this.outerElem.getBoundingClientRect().height + "px";
var _a = calculatePosition(_this.outerElem, _this.zoomOverlay), translateX = _a.translateX, translateY = _a.translateY;
_this.zoomOverlay.style.transform = "translate3d(\n " + translateX + "px,\n " + translateY + "px,\n 0";
_this.zoomOverlay.style.opacity = '1';
_this.zoomOverlay.style.zIndex = "" + _this.activeZIndex;
};
this.activeZIndex = activeZIndex;
this.zoomOverlay = overlayElem;
this.outerElem = outerElem;
overlayElem.style.position = 'absolute';
overlayElem.style.zIndex = INACTIVE_ZINDEX;
overlayElem.style.backgroundColor = backgroundColor;
overlayElem.style.opacity = '0';
overlayElem.style.transition = "opacity " + transitionDuration + "ms";
}
ZoomOverlay.prototype.zoom = function () {
this.isZoomed = true;
this.applyZoom();
window.addEventListener('resize', this.applyZoom);
};
ZoomOverlay.prototype.unZoom = function () {
this.isZoomed = false;
window.removeEventListener('resize', this.applyZoom);
this.zoomOverlay.style.opacity = '0';
this.zoomOverlay.addEventListener('transitionend', this.onTransitionEnd);
};
return ZoomOverlay;
}());
exports.ZoomOverlay = ZoomOverlay;
exports.default = GenericZoom;
//# sourceMappingURL=index.js.map