media assets: refactor media asset component.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<div class="media-asset-container media-asset-container-fit-height flex flex-col <%= outer_classes %>" data-dynamic-height="<%= dynamic_height %>" style="--header-visible-height: 0px; --media-asset-width: <%= image_width %>; --media-asset-height: <%= image_height %>;">
|
<div class="media-asset-component media-asset-component-fit-height media-asset-component-fit-width flex flex-col <%= outer_classes %>" data-dynamic-height="<%= dynamic_height %>" style="--header-visible-height: 0px; --media-asset-width: <%= image_width %>; --media-asset-height: <%= image_height %>;">
|
||||||
<%= header %>
|
<%= header %>
|
||||||
|
|
||||||
<div class="media-asset-component relative max-h-inherit overflow-hidden <%= inner_classes %>">
|
<div class="media-asset-container relative max-h-inherit overflow-hidden <%= inner_classes %>">
|
||||||
<div class="media-asset-zoom-level hidden absolute top-0.5 left-0.5 p-1 m-0.5 leading-none rounded text-xs font-arial font-bold pointer-events-none transition-opacity">
|
<div class="media-asset-zoom-level hidden absolute top-0.5 left-0.5 p-1 m-0.5 leading-none rounded text-xs font-arial font-bold pointer-events-none transition-opacity">
|
||||||
100%
|
100%
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.media-asset-component:not(:hover) .media-asset-zoom-level {
|
.media-asset-container:not(:hover) .media-asset-zoom-level {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7,8 +7,8 @@
|
|||||||
background: var(--preview-icon-background);
|
background: var(--preview-icon-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-asset-container {
|
.media-asset-component {
|
||||||
&:not(.media-asset-container-fit-height) .paginator {
|
&:not(.media-asset-component-fit-height) .paginator {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,19 +37,24 @@
|
|||||||
.media-asset-image {
|
.media-asset-image {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
width: auto;
|
width: auto;
|
||||||
height: auto;
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: inherit;
|
max-height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.media-asset-container-fit-height {
|
&.media-asset-component-fit-height {
|
||||||
max-height: calc(100vh - var(--header-visible-height));
|
max-height: calc(100vh - var(--header-visible-height));
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.media-asset-component {
|
.media-asset-container {
|
||||||
aspect-ratio: var(--media-asset-width) / var(--media-asset-height);
|
aspect-ratio: var(--media-asset-width) / var(--media-asset-height);
|
||||||
height: max-content;
|
height: max-content;
|
||||||
height: intrinsic; // XXX Safari-only hack to make images correct height on upload page. I have no idea how this works.
|
height: intrinsic; // XXX Safari-only hack to make images correct height on upload page. I have no idea how this works.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.media-asset-component-fit-width {
|
||||||
|
.media-asset-image {
|
||||||
|
height: auto;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
export default class MediaAssetComponent {
|
export default class MediaAssetComponent {
|
||||||
static initialize() {
|
static initialize() {
|
||||||
$(".media-asset-container").toArray().forEach(element => {
|
$(".media-asset-component").toArray().forEach(element => {
|
||||||
new MediaAssetComponent(element);
|
new MediaAssetComponent(element);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(element) {
|
constructor(element) {
|
||||||
this.$container = $(element);
|
this.$component = $(element);
|
||||||
this.$component = this.$container.find(".media-asset-component");
|
this.$container = this.$component.find(".media-asset-container");
|
||||||
|
this.$image = this.$component.find(".media-asset-image");
|
||||||
|
this.$zoomLevel = this.$component.find(".media-asset-zoom-level");
|
||||||
|
|
||||||
if (this.$container.attr("data-dynamic-height") === "true") {
|
if (this.$component.attr("data-dynamic-height") === "true") {
|
||||||
this.updateHeight();
|
this.updateHeight();
|
||||||
$(window).on("scroll.danbooru", element => {
|
$(window).on("scroll.danbooru", e => this.updateHeight());
|
||||||
this.updateHeight();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.$image.length) {
|
if (this.$image.length) {
|
||||||
@@ -26,8 +26,10 @@ export default class MediaAssetComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggleFit() {
|
toggleFit() {
|
||||||
if (this.canZoom) {
|
if (this.canZoomOut) {
|
||||||
this.$container.toggleClass("media-asset-container-fit-height");
|
this.$component.addClass("media-asset-component-fit-height media-asset-component-fit-width");
|
||||||
|
} else if (this.canZoomHeight) {
|
||||||
|
this.$component.removeClass("media-asset-component-fit-height");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateZoom();
|
this.updateZoom();
|
||||||
@@ -46,19 +48,19 @@ export default class MediaAssetComponent {
|
|||||||
|
|
||||||
updateHeight() {
|
updateHeight() {
|
||||||
// XXX 115 = header height (hardcoded to prevent height glitches as page loads)
|
// XXX 115 = header height (hardcoded to prevent height glitches as page loads)
|
||||||
this.$container.css("--header-visible-height", Math.min(115, Math.max(0, this.$container.offset().top - $(window).scrollTop())) + "px");
|
this.$component.css("--header-visible-height", Math.min(115, Math.max(0, this.$component.offset().top - $(window).scrollTop())) + "px");
|
||||||
}
|
}
|
||||||
|
|
||||||
get zoomLevel() {
|
get zoomLevel() {
|
||||||
return this.$image.width() / Number(this.$image.attr("width"));
|
return this.$image.width() / Number(this.$image.attr("width"));
|
||||||
}
|
}
|
||||||
|
|
||||||
get canZoom() {
|
get canZoomIn() {
|
||||||
return this.canZoomIn || this.canZoomOut;
|
return this.canZoomHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
get canZoomIn() {
|
get canZoomHeight() {
|
||||||
return !this.isZoomed && this.$image.height() < this.$image.get(0).naturalHeight && Math.round(this.$image.width()) < Math.round(this.$container.width());
|
return !this.isZoomed && this.$image.height() < this.$image.get(0).naturalHeight && Math.round(this.$image.width()) < Math.round(this.$component.width());
|
||||||
}
|
}
|
||||||
|
|
||||||
get canZoomOut() {
|
get canZoomOut() {
|
||||||
@@ -66,15 +68,7 @@ export default class MediaAssetComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get isZoomed() {
|
get isZoomed() {
|
||||||
return !this.$container.is(".media-asset-container-fit-height");
|
return !this.$component.is(".media-asset-component-fit-height.media-asset-component-fit-width");
|
||||||
}
|
|
||||||
|
|
||||||
get $image() {
|
|
||||||
return this.$component.find(".media-asset-image");
|
|
||||||
}
|
|
||||||
|
|
||||||
get $zoomLevel() {
|
|
||||||
return this.$component.find(".media-asset-zoom-level");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ $spacer: 0.25rem; /* 4px */
|
|||||||
|
|
||||||
.overflow-auto { overflow: auto; }
|
.overflow-auto { overflow: auto; }
|
||||||
.overflow-hidden { overflow: hidden; }
|
.overflow-hidden { overflow: hidden; }
|
||||||
|
.overflow-x-hidden { overflow-x: hidden; }
|
||||||
|
|
||||||
.break-all { word-break: break-all; overflow-wrap: anywhere; }
|
.break-all { word-break: break-all; overflow-wrap: anywhere; }
|
||||||
.break-words { word-break: break-word; overflow-wrap: anywhere; }
|
.break-words { word-break: break-word; overflow-wrap: anywhere; }
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<div id="c-media-assets">
|
<div id="c-media-assets">
|
||||||
<div id="a-show">
|
<div id="a-show">
|
||||||
<div class="md:flex flex-row gap-4">
|
<div class="md:flex flex-row gap-4">
|
||||||
<div class="flex-1 w-full">
|
<div class="flex-1 w-full min-w-0">
|
||||||
<%= render MediaAssetComponent.new(media_asset: @media_asset, current_user: CurrentUser.user, outer_classes: "sticky h-full relative top-0", inner_classes: "mx-auto", dynamic_height: true) do |component| %>
|
<%= render MediaAssetComponent.new(media_asset: @media_asset, current_user: CurrentUser.user, outer_classes: "sticky h-full relative top-0", inner_classes: "mx-auto", dynamic_height: true) do |component| %>
|
||||||
<% component.with_header do %>
|
<% component.with_header do %>
|
||||||
<div class="paginator top-0 w-full z-10">
|
<div class="paginator top-0 w-full z-10">
|
||||||
|
|||||||
Reference in New Issue
Block a user