primevue
Version:
PrimeVue is a premium UI library for Vue featuring a rich set of 90+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeBlock, wh
600 lines (594 loc) • 22.4 kB
JavaScript
import { isElement } from '@primeuix/utils/dom';
import { mergeProps, openBlock, createBlock, resolveDynamicComponent, withCtx, renderSlot, normalizeClass } from 'vue';
import BaseComponent from '@primevue/core/basecomponent';
import GalleryItemStyle from 'primevue/galleryitem/style';
var script$1 = {
name: 'BaseGalleryItem',
"extends": BaseComponent,
props: {
normalScale: {
type: Number,
"default": 1
},
zoomedScale: {
type: Number,
"default": 3
},
as: {
type: [String, Object],
"default": 'DIV'
},
asChild: {
type: Boolean,
"default": false
}
},
style: GalleryItemStyle,
provide: function provide() {
return {
$pcGalleryItem: this,
$parentInstance: this
};
}
};
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var script = {
name: 'GalleryItem',
"extends": script$1,
inheritAttrs: false,
inject: ['$pcGallery'],
itemEl: null,
pointerStart: {
x: 0,
y: 0
},
isPinching: false,
isDragging: false,
dragStart: {
x: 0,
y: 0
},
hasDragged: false,
wheelSyncTimer: null,
rotateTimer: null,
wheelHandler: null,
resizeHandler: null,
data: function data() {
return {
index: -1,
position: {
x: 0,
y: 0
},
scale: 1,
rotation: 0,
isRotating: false,
flip: {
x: 1,
y: 1
}
};
},
created: function created() {
this.pointerData = new Map();
this.initialPinchDistance = 0;
this.initialPinchScale = 1;
this.liveScale = 1;
this.livePosition = {
x: 0,
y: 0
};
},
mounted: function mounted() {
var _this = this;
if (this.$pcGallery) {
var newIndex = this.$pcGallery.registerItem(this.index >= 0 ? this.index : null);
if (newIndex !== this.index) this.index = newIndex;
}
this.bindWheelListener();
this.bindResizeListener();
this.$nextTick(function () {
return _this.calculateItemSize();
});
},
beforeUnmount: function beforeUnmount() {
this.unbindWheelListener();
this.unbindResizeListener();
this.clearTimers();
},
watch: {
scale: function scale(value) {
this.liveScale = value;
if (value <= this.normalScale) {
this.position = {
x: 0,
y: 0
};
this.livePosition = {
x: 0,
y: 0
};
}
this.reportState();
},
position: function position(value) {
this.livePosition = value;
},
rotation: function rotation() {
if (this.active) this.calculateItemSize();
this.reportState();
},
flip: {
handler: function handler() {
this.reportState();
},
deep: true
},
'$pcGallery.d_activeIndex': function $pcGalleryD_activeIndex() {
if (this.active) this.calculateItemSize();
},
'$pcGallery.isFullscreen': function $pcGalleryIsFullscreen() {
if (this.active) this.calculateItemSize();
},
'$pcGallery.pendingAction': function $pcGalleryPendingAction(action) {
var _this$$pcGallery;
if (!action || !this.active) return;
switch (action.type) {
case 'zoom-in':
this.zoomIn();
break;
case 'zoom-out':
this.zoomOut();
break;
case 'rotate-left':
this.rotateLeft();
break;
case 'rotate-right':
this.rotateRight();
break;
case 'flip-x':
this.flipX();
break;
case 'flip-y':
this.flipY();
break;
case 'download':
this.download();
break;
}
(_this$$pcGallery = this.$pcGallery) === null || _this$$pcGallery === void 0 || _this$$pcGallery.clearPendingAction();
},
active: function active(value) {
if (value) this.reportState();
}
},
computed: {
active: function active() {
var _this$$pcGallery$isIt, _this$$pcGallery2;
return this.index >= 0 && ((_this$$pcGallery$isIt = (_this$$pcGallery2 = this.$pcGallery) === null || _this$$pcGallery2 === void 0 ? void 0 : _this$$pcGallery2.isItemActive(this.index)) !== null && _this$$pcGallery$isIt !== void 0 ? _this$$pcGallery$isIt : false);
},
cssVars: function cssVars() {
return {
'--px-position-x': "".concat(this.position.x, "px"),
'--px-position-y': "".concat(this.position.y, "px"),
'--px-scale': "".concat(this.scale),
'--px-rotation': "".concat(this.rotation, "deg"),
'--px-flip-x': this.flip.x,
'--px-flip-y': this.flip.y
};
},
attrs: function attrs() {
return mergeProps(this.a11yAttrs, this.ptmi('root'));
},
a11yAttrs: function a11yAttrs() {
return {
ref: this.setRef,
'data-pc-name': 'galleryitem',
'data-pc-section': 'root',
'data-active': this.active ? '' : undefined,
'data-rotating': this.isRotating ? '' : undefined,
'data-index': this.index,
style: this.cssVars,
onClick: this.onClick,
onPointerdown: this.onPointerDown,
onPointermove: this.onPointerMove,
onPointerup: this.onPointerUp,
onDragstart: this.onDragStartPrevent
};
}
},
methods: {
reportState: function reportState() {
if (!this.active || !this.$pcGallery) return;
this.$pcGallery.reportItemState({
zoomed: this.scale > this.normalScale,
rotated: this.rotation !== 0,
flipped: this.flip.x === -1 || this.flip.y === -1,
scale: this.scale,
rotation: this.rotation,
flip: this.flip
});
},
getEl: function getEl() {
return this.itemEl;
},
setRef: function setRef(el) {
var _el$$el;
var resolved = isElement(el) ? el : (_el$$el = el === null || el === void 0 ? void 0 : el.$el) !== null && _el$$el !== void 0 ? _el$$el : null;
this.itemEl = isElement(resolved) ? resolved : null;
},
onDragStartPrevent: function onDragStartPrevent(event) {
var _event$preventDefault;
event === null || event === void 0 || (_event$preventDefault = event.preventDefault) === null || _event$preventDefault === void 0 || _event$preventDefault.call(event);
},
clearTimers: function clearTimers() {
if (this.wheelSyncTimer) {
clearTimeout(this.wheelSyncTimer);
this.wheelSyncTimer = null;
}
if (this.rotateTimer) {
clearTimeout(this.rotateTimer);
this.rotateTimer = null;
}
},
calculateItemSize: function calculateItemSize() {
var _this$$pcGallery3;
var el = this.itemEl;
var contentEl = (_this$$pcGallery3 = this.$pcGallery) === null || _this$$pcGallery3 === void 0 ? void 0 : _this$$pcGallery3.contentEl;
if (!el || !contentEl) return;
var imageElement = el.firstElementChild;
if (!imageElement) return;
var contentRect = contentEl.getBoundingClientRect();
var naturalWidth = imageElement.naturalWidth || imageElement.offsetWidth;
var naturalHeight = imageElement.naturalHeight || imageElement.offsetHeight;
if (naturalWidth === 0 || naturalHeight === 0) return;
var isRotated = Math.abs(this.rotation) % 180 === 90;
if (isRotated) {
var _ref = [naturalHeight, naturalWidth];
naturalWidth = _ref[0];
naturalHeight = _ref[1];
}
var naturalAspectRatio = naturalWidth / naturalHeight;
var contentAspectRatio = contentRect.width / contentRect.height;
var targetWidth;
var targetHeight;
if (naturalAspectRatio > contentAspectRatio) {
targetWidth = Math.min(contentRect.width * 0.99, naturalWidth);
targetHeight = targetWidth / naturalAspectRatio;
} else {
targetHeight = Math.min(contentRect.height * 0.99, naturalHeight);
targetWidth = targetHeight * naturalAspectRatio;
}
if (isRotated) {
imageElement.style.width = "".concat(targetHeight, "px");
imageElement.style.height = "".concat(targetWidth, "px");
el.style.width = targetHeight > 0 ? "".concat(targetHeight, "px") : 'auto';
el.style.height = targetWidth > 0 ? "".concat(targetWidth, "px") : 'auto';
} else {
imageElement.style.width = "".concat(targetWidth, "px");
imageElement.style.height = "".concat(targetHeight, "px");
el.style.width = targetWidth > 0 ? "".concat(targetWidth, "px") : 'auto';
el.style.height = targetHeight > 0 ? "".concat(targetHeight, "px") : 'auto';
}
el.style.aspectRatio = "".concat(naturalWidth / naturalHeight);
},
calculateConstraints: function calculateConstraints(targetScale) {
var _this$$pcGallery4;
var el = this.itemEl;
var contentEl = (_this$$pcGallery4 = this.$pcGallery) === null || _this$$pcGallery4 === void 0 ? void 0 : _this$$pcGallery4.contentEl;
if (!el || !contentEl) return {
minX: 0,
maxX: 0,
minY: 0,
maxY: 0
};
var itemElement = el.firstElementChild;
if (!itemElement) return {
minX: 0,
maxX: 0,
minY: 0,
maxY: 0
};
var contentRect = contentEl.getBoundingClientRect();
var scaleToUse = targetScale !== undefined ? targetScale : this.liveScale;
var originalWidth = itemElement.offsetWidth;
var originalHeight = itemElement.offsetHeight;
var isRotated = Math.abs(this.rotation) % 180 === 90;
if (isRotated) {
var _ref2 = [originalHeight, originalWidth];
originalWidth = _ref2[0];
originalHeight = _ref2[1];
}
var scaledWidth = originalWidth * scaleToUse;
var scaledHeight = originalHeight * scaleToUse;
var contentCenterX = contentRect.width / 2;
var contentCenterY = contentRect.height / 2;
var halfScaledWidth = scaledWidth / 2;
var halfScaledHeight = scaledHeight / 2;
var maxX = halfScaledWidth > contentCenterX ? halfScaledWidth - contentCenterX : 0;
var minX = halfScaledWidth > contentCenterX ? -(halfScaledWidth - contentCenterX) : 0;
var maxY = halfScaledHeight > contentCenterY ? halfScaledHeight - contentCenterY : 0;
var minY = halfScaledHeight > contentCenterY ? -(halfScaledHeight - contentCenterY) : 0;
return {
minX: minX,
maxX: maxX,
minY: minY,
maxY: maxY
};
},
zoomIn: function zoomIn() {
this.scale = this.zoomedScale;
var el = this.itemEl;
if (el) el.style.cursor = 'zoom-out';
},
zoomOut: function zoomOut() {
this.scale = this.normalScale;
this.position = {
x: 0,
y: 0
};
var el = this.itemEl;
if (el) el.style.cursor = 'zoom-in';
},
rotateLeft: function rotateLeft() {
this.markRotating();
this.rotation -= 90;
},
rotateRight: function rotateRight() {
this.markRotating();
this.rotation += 90;
},
markRotating: function markRotating() {
var _this2 = this;
this.isRotating = true;
var el = this.itemEl;
if (el) el.style.transition = '';
if (this.rotateTimer) clearTimeout(this.rotateTimer);
this.rotateTimer = setTimeout(function () {
_this2.isRotating = false;
_this2.rotateTimer = null;
}, 300);
},
flipX: function flipX() {
this.flip = _objectSpread(_objectSpread({}, this.flip), {}, {
x: Math.sign(this.flip.x) * -1
});
},
flipY: function flipY() {
this.flip = _objectSpread(_objectSpread({}, this.flip), {}, {
y: Math.sign(this.flip.y) * -1
});
},
download: function download() {
var el = this.itemEl;
if (!el) return;
var imageElement = el.querySelector('img');
if (!imageElement || !imageElement.src) return;
var link = document.createElement('a');
link.href = imageElement.src;
var urlParts = imageElement.src.split('/');
link.download = urlParts[urlParts.length - 1] || 'image.jpg';
link.target = '_blank';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
},
onClick: function onClick(e) {
if (this.hasDragged) {
this.hasDragged = false;
return;
}
if (this.liveScale !== this.normalScale) {
this.zoomOut();
return;
}
var el = this.itemEl;
if (el) {
var itemRect = el.getBoundingClientRect();
var itemCenterX = itemRect.width / 2;
var itemCenterY = itemRect.height / 2;
var clickX = e.clientX - itemRect.left;
var clickY = e.clientY - itemRect.top;
var offsetX = itemCenterX - clickX;
var offsetY = itemCenterY - clickY;
var zoomOffsetX = offsetX * (this.zoomedScale - 1);
var zoomOffsetY = offsetY * (this.zoomedScale - 1);
var constraints = this.calculateConstraints(this.zoomedScale);
var constrainedX = Math.max(constraints.minX, Math.min(constraints.maxX, zoomOffsetX));
var constrainedY = Math.max(constraints.minY, Math.min(constraints.maxY, zoomOffsetY));
this.position = {
x: constrainedX,
y: constrainedY
};
}
this.zoomIn();
},
onPointerDown: function onPointerDown(e) {
e.currentTarget.setPointerCapture(e.pointerId);
this.pointerData.set(e.pointerId, {
x: e.clientX,
y: e.clientY
});
this.pointerStart = {
x: e.clientX,
y: e.clientY
};
if (e.pointerType === 'touch' && this.pointerData.size >= 2) {
this.isDragging = false;
this.initialPinchDistance = 0;
this.initialPinchScale = this.liveScale;
} else if (this.liveScale > 1) {
if (e.pointerType === 'mouse' || e.pointerType === 'touch' && this.pointerData.size === 1) {
this.isDragging = true;
this.dragStart = {
x: e.clientX - this.livePosition.x,
y: e.clientY - this.livePosition.y
};
this.hasDragged = false;
}
}
},
onPointerMove: function onPointerMove(e) {
if (!this.pointerData.has(e.pointerId)) return;
var el = this.itemEl;
if (!el) return;
el.style.transition = 'none';
if (e.pointerType === 'mouse' && !el.style.cursor) {
el.style.cursor = this.liveScale > this.normalScale ? 'zoom-out' : 'zoom-in';
}
this.pointerData.set(e.pointerId, {
x: e.clientX,
y: e.clientY
});
var pointers = Array.from(this.pointerData.values());
if (pointers.length === 2) {
var p1 = pointers[0],
p2 = pointers[1];
var distance = Math.hypot(p2.x - p1.x, p2.y - p1.y);
this.isPinching = true;
this.hasDragged = true;
if (this.initialPinchDistance === 0) {
this.initialPinchDistance = distance;
this.initialPinchScale = this.liveScale;
} else {
var ratio = distance / this.initialPinchDistance;
var newScale = Math.max(this.normalScale, Math.min(this.zoomedScale, this.initialPinchScale * ratio));
var constraints = this.calculateConstraints(newScale);
var constrainedX = Math.max(constraints.minX, Math.min(constraints.maxX, this.livePosition.x));
var constrainedY = Math.max(constraints.minY, Math.min(constraints.maxY, this.livePosition.y));
this.liveScale = newScale;
this.livePosition = {
x: constrainedX,
y: constrainedY
};
el.style.setProperty('--px-scale', "".concat(newScale));
el.style.setProperty('--px-position-x', "".concat(constrainedX, "px"));
el.style.setProperty('--px-position-y', "".concat(constrainedY, "px"));
}
} else if (pointers.length === 1 && this.isDragging) {
var pointer = pointers[0];
var newX = pointer.x - this.dragStart.x;
var newY = pointer.y - this.dragStart.y;
var _constraints = this.calculateConstraints(this.liveScale);
var computedX = Math.max(_constraints.minX, Math.min(_constraints.maxX, newX));
var computedY = Math.max(_constraints.minY, Math.min(_constraints.maxY, newY));
this.livePosition = {
x: computedX,
y: computedY
};
el.style.setProperty('--px-position-x', "".concat(computedX, "px"));
el.style.setProperty('--px-position-y', "".concat(computedY, "px"));
var distFromStart = Math.hypot(pointer.x - this.pointerStart.x, pointer.y - this.pointerStart.y);
if (distFromStart > 5) this.hasDragged = true;
}
},
onPointerUp: function onPointerUp(e) {
var _e$currentTarget$hasP, _e$currentTarget;
var el = this.itemEl;
if (!el) return;
el.style.transition = '';
if (e.pointerType === 'mouse') {
el.style.cursor = this.liveScale > this.normalScale ? 'zoom-out' : 'zoom-in';
}
if ((_e$currentTarget$hasP = (_e$currentTarget = e.currentTarget).hasPointerCapture) !== null && _e$currentTarget$hasP !== void 0 && _e$currentTarget$hasP.call(_e$currentTarget, e.pointerId)) {
e.currentTarget.releasePointerCapture(e.pointerId);
}
this.pointerData["delete"](e.pointerId);
if (this.pointerData.size < 2) {
this.initialPinchDistance = 0;
this.initialPinchScale = 1;
this.isPinching = false;
}
if (this.pointerData.size === 0) {
this.isDragging = false;
this.scale = this.liveScale;
this.position = this.livePosition;
}
},
bindWheelListener: function bindWheelListener() {
var _this3 = this;
var el = this.itemEl;
if (!el) return;
this.wheelHandler = function (e) {
if (!e.ctrlKey || !_this3.active) return;
e.preventDefault();
var itemEl = _this3.itemEl;
if (!itemEl) return;
itemEl.style.transition = 'none';
var delta = -e.deltaY;
var scaleFactor = 1 + delta * 0.01;
var newScale = Math.max(_this3.normalScale, Math.min(_this3.zoomedScale, _this3.liveScale * scaleFactor));
var constraints = _this3.calculateConstraints(newScale);
var constrainedX = Math.max(constraints.minX, Math.min(constraints.maxX, _this3.livePosition.x));
var constrainedY = Math.max(constraints.minY, Math.min(constraints.maxY, _this3.livePosition.y));
_this3.liveScale = newScale;
_this3.livePosition = {
x: constrainedX,
y: constrainedY
};
itemEl.style.setProperty('--px-scale', "".concat(newScale));
itemEl.style.setProperty('--px-position-x', "".concat(constrainedX, "px"));
itemEl.style.setProperty('--px-position-y', "".concat(constrainedY, "px"));
if (_this3.wheelSyncTimer) clearTimeout(_this3.wheelSyncTimer);
_this3.wheelSyncTimer = setTimeout(function () {
var finalEl = _this3.itemEl;
if (finalEl) {
finalEl.style.transition = '';
finalEl.style.cursor = _this3.liveScale > _this3.normalScale ? 'zoom-out' : 'zoom-in';
}
_this3.scale = _this3.liveScale;
_this3.position = _this3.livePosition;
_this3.wheelSyncTimer = null;
}, 150);
};
el.addEventListener('wheel', this.wheelHandler, {
passive: false
});
},
unbindWheelListener: function unbindWheelListener() {
var el = this.itemEl;
if (el && this.wheelHandler) el.removeEventListener('wheel', this.wheelHandler);
this.wheelHandler = null;
},
bindResizeListener: function bindResizeListener() {
var _this4 = this;
this.resizeHandler = function () {
if (_this4.active) _this4.calculateItemSize();
};
window.addEventListener('resize', this.resizeHandler);
},
unbindResizeListener: function unbindResizeListener() {
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
}
}
};
function render(_ctx, _cache, $props, $setup, $data, $options) {
return !_ctx.asChild ? (openBlock(), createBlock(resolveDynamicComponent(_ctx.as), mergeProps({
key: 0,
"class": _ctx.cx('root')
}, $options.attrs), {
"default": withCtx(function () {
return [renderSlot(_ctx.$slots, "default", {
index: $data.index,
active: $options.active
})];
}),
_: 3
}, 16, ["class"])) : renderSlot(_ctx.$slots, "default", {
key: 1,
"class": normalizeClass(_ctx.cx('root')),
a11yAttrs: $options.a11yAttrs,
index: $data.index,
active: $options.active
});
}
script.render = render;
export { script as default };