refactor: apply image loading shimmer effect to the container element instead of the image itself.

This commit is contained in:
Suherdy Yacob 2026-03-16 14:33:45 +07:00
parent b3f23fbc44
commit 8871c1399c
3 changed files with 14 additions and 8 deletions

View File

@ -51,17 +51,22 @@ body div.o_sign_sign_item.o_sign_image_item span.o_placeholder {
position: relative; position: relative;
} }
.o_sign_image_loading { .o_sign_image_item.o_sign_image_loading_container {
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%); background: #f6f7f8;
background-size: 200% 100%; background: linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
animation: o_sign_image_shimmer 1.5s infinite linear; background-size: 800px 104px;
animation: o_sign_image_shimmer 1.2s forwards infinite linear;
} }
@keyframes o_sign_image_shimmer { @keyframes o_sign_image_shimmer {
0% { background-position: 200% 0; } 0% { background-position: -468px 0; }
100% { background-position: -200% 0; } 100% { background-position: 468px 0; }
} }
.o_sign_image_lazy { .o_sign_image_lazy {
transition: opacity 0.5s ease-in-out; transition: opacity 0.5s ease-in-out;
} }
.o_sign_image_lazy:not(.o_sign_image_loading) {
opacity: 1 !important;
}

View File

@ -139,6 +139,7 @@ patch(PDFIframe.prototype, {
lazyImg.src = lazyImg.dataset.src; lazyImg.src = lazyImg.dataset.src;
lazyImg.onload = () => { lazyImg.onload = () => {
lazyImg.classList.remove('o_sign_image_loading'); lazyImg.classList.remove('o_sign_image_loading');
el.classList.remove('o_sign_image_loading_container');
lazyImg.style.opacity = 1; lazyImg.style.opacity = 1;
}; };
} }

View File

@ -5,7 +5,7 @@
<t t-if="type == 'image'" t-call="sign.imageSignItem"/> <t t-if="type == 'image'" t-call="sign.imageSignItem"/>
</xpath> </xpath>
<xpath expr="//div[@t-if=&quot;type == 'selection'&quot;]" position="after"> <xpath expr="//div[@t-if=&quot;type == 'selection'&quot;]" position="after">
<div t-if="type == 'image'" t-att-data-id="id" t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item o_sign_image_item" t-att-style="style" t-att-data-value="value" t-att-data-type="'image'" style="text-align:center; display:flex; align-items:center; justify-content:center;"> <div t-if="type == 'image'" t-att-data-id="id" t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item o_sign_image_item {{value ? 'o_sign_image_loading_container' : ''}}" t-att-style="style" t-att-data-value="value" t-att-data-type="'image'" style="text-align:center; display:flex; align-items:center; justify-content:center;">
<input type="file" accept="image/*" class="o_sign_image_upload_input" style="display:none"/> <input type="file" accept="image/*" class="o_sign_image_upload_input" style="display:none"/>
<t t-if="value"> <t t-if="value">
<img t-att-data-src="value" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="o_sign_image_lazy o_sign_image_loading" style="max-width:100%; max-height:100%; object-fit:contain; opacity: 0; transition: opacity 0.3s;"/> <img t-att-data-src="value" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="o_sign_image_lazy o_sign_image_loading" style="max-width:100%; max-height:100%; object-fit:contain; opacity: 0; transition: opacity 0.3s;"/>
@ -21,7 +21,7 @@
</t> </t>
<t t-name="sign.imageSignItem"> <t t-name="sign.imageSignItem">
<div t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item o_sign_image_item" t-att-data-id="id" t-att-style="style" t-att-data-type="'image'" style="text-align:center; display:flex; align-items:center; justify-content:center;"> <div t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item o_sign_image_item {{value ? 'o_sign_image_loading_container' : ''}}" t-att-data-id="id" t-att-style="style" t-att-data-type="'image'" style="text-align:center; display:flex; align-items:center; justify-content:center;">
<div class="sign_item_body"> <div class="sign_item_body">
<t t-if="value"> <t t-if="value">
<img t-att-data-src="value" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="o_sign_image_lazy o_sign_image_loading" style="max-width:100%; max-height:100%; object-fit:contain; opacity: 0; transition: opacity 0.3s;"/> <img t-att-data-src="value" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="o_sign_image_lazy o_sign_image_loading" style="max-width:100%; max-height:100%; object-fit:contain; opacity: 0; transition: opacity 0.3s;"/>