/* =========================================================
PALIWEB - LENIS SMOOTH SCROLL + SCROLL TO TOP
========================================================= */
add_action('wp_footer', function () {
// داخل ادمین و ادیتور المنتور اجرا نشود
$el = class_exists('\Elementor\Plugin') ? \Elementor\Plugin::$instance : null;
if (is_admin() || ($el && isset($el->preview) && $el->preview->is_preview_mode())) {
return;
}
?>
<style>
/* Lenis (ضروری) */
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto!important}
.lenis.lenis-smooth [data-lenis-prevent]{overscroll-behavior:contain}
.lenis.lenis-stopped{overflow:hidden}
.lenis.lenis-scrolling iframe{pointer-events:none}
/* اسکرول بار صفحه (نارنجی) - دسکتاپ */
html,body{scrollbar-width:thin;scrollbar-color:#f97316 transparent}
@supports not (scrollbar-color:auto){
html::-webkit-scrollbar,body::-webkit-scrollbar{width:8px;height:8px}
html::-webkit-scrollbar-track,body::-webkit-scrollbar-track{background:transparent}
html::-webkit-scrollbar-thumb,body::-webkit-scrollbar-thumb{background:#f97316;border-radius:8px}
html::-webkit-scrollbar-thumb:hover,body::-webkit-scrollbar-thumb:hover{background:#ea580c}
}
/* اسکرول بار نارنجی اندروید (با JS ساخته میشود) */
html.pw-sb,html.pw-sb body{scrollbar-width:none}
html.pw-sb::-webkit-scrollbar,html.pw-sb body::-webkit-scrollbar{display:none;width:0;height:0}
#paliweb-scrollbar{
position:fixed;
top:0;
inset-inline-end:2px;
z-index:999998;
width:3px;
border-radius:3px;
background:#f97316;
opacity:0;
pointer-events:none;
will-change:transform,opacity;
transition:opacity .3s ease;
}
#paliweb-scrollbar.pw-on{opacity:1}
/* دکمه */
#paliweb-scroll-top{
--pw-orange:#f97316;
--pw-track:inset 0 0 0 3px rgba(40,42,46,.10);
position:fixed;
left:24px;
bottom:24px;
z-index:999999;
display:grid;
place-items:center;
width:52px;
height:52px;
padding:0;
border:0;
border-radius:50%;
background:#f6f4ef;
color:#33363b;
box-shadow:var(--pw-track),0 6px 18px rgba(0,0,0,.18);
cursor:pointer;
-webkit-tap-highlight-color:transparent;
opacity:0;
visibility:hidden;
pointer-events:none;
transform:translateY(12px) scale(.9);
transition:opacity .22s ease,visibility .22s ease,transform .3s cubic-bezier(.2,.8,.2,1),box-shadow .25s ease;
}
#paliweb-scroll-top.paliweb-visible{
opacity:1;
visibility:visible;
pointer-events:auto;
transform:none;
will-change:transform;
}
#paliweb-scroll-top.paliweb-visible:hover{
transform:translateY(-3px) scale(1.05);
box-shadow:var(--pw-track),0 10px 24px rgba(0,0,0,.24);
}
#paliweb-scroll-top.paliweb-visible:active{transform:scale(.94)}
#paliweb-scroll-top:focus-visible{outline:2px solid var(--pw-orange);outline-offset:3px}
/* حلقهی پیشرفت اسکرول */
#paliweb-scroll-top .pw-ring{
position:absolute;
inset:0;
width:100%;
height:100%;
overflow:visible;
transform:rotate(-90deg);
}
#paliweb-scroll-top .pw-ring-bar{
fill:none;
stroke:var(--pw-orange);
stroke-width:3;
stroke-linecap:round;
}
/* فلش */
#paliweb-scroll-top .pw-arrow{
position:relative;
display:block;
width:20px;
height:20px;
transition:transform .25s ease;
}
#paliweb-scroll-top:hover .pw-arrow{transform:translateY(-2px)}
/* ریسپانسیو */
@media (max-width:767px){
#paliweb-scroll-top{left:16px;bottom:16px;width:46px;height:46px}
#paliweb-scroll-top .pw-arrow{width:18px;height:18px}
}
@media (min-width:768px) and (max-width:1024px){
#paliweb-scroll-top{left:20px;bottom:20px}
}
@media (prefers-reduced-motion:reduce){
#paliweb-scroll-top,#paliweb-scroll-top .pw-arrow{transition:none}
}
</style>
<button id="paliweb-scroll-top" type="button" aria-label="بازگشت به بالای صفحه" title="بازگشت به بالا">
<svg class="pw-ring" viewBox="0 0 52 52" aria-hidden="true"><circle class="pw-ring-bar" cx="26" cy="26" r="24.5"/></svg>
<svg class="pw-arrow" viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M6 14L12 8L18 14" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</button>
<script>
(() => {
'use strict';
const button = document.getElementById('paliweb-scroll-top');
if (!button) return;
const is = (query) => window.matchMedia(query).matches;
/* ---------- دکمه + نوار پیشرفت ---------- */
const SHOW_AFTER = 100; // پیکسل؛ کمتر = ظاهر شدن زودتر
const bar = button.querySelector('.pw-ring-bar');
const length = 2 * Math.PI * parseFloat(bar.getAttribute('r'));
let maxScroll = 1;
let progress = -1;
let visible = false;
let barOn = true;
let queued = false;
let viewH = window.innerHeight;
let thumbH = 40;
let thumbOn = false;
let hideTimer;
// اسکرول بار نارنجی برای اندروید (روی آیفون/آیپد ساخته نمیشود)
// (سیستمعامل اجازهی تغییر رنگ اسکرول بار اصلی را نمیدهد)
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
let thumb = null;
if (!isIOS && is('(hover: none), (pointer: coarse)')) {
thumb = document.createElement('div');
thumb.id = 'paliweb-scrollbar';
thumb.setAttribute('aria-hidden', 'true');
document.body.appendChild(thumb);
document.documentElement.classList.add('pw-sb');
}
bar.style.strokeDasharray = length;
bar.style.strokeDashoffset = length;
const measure = () => {
viewH = window.innerHeight;
maxScroll = Math.max(1, document.documentElement.scrollHeight - viewH);
if (thumb) {
thumbH = Math.max(40, Math.min(viewH - 8, viewH * viewH / (maxScroll + viewH)));
thumb.style.height = thumbH + 'px';
}
};
const hideThumb = () => {
thumbOn = false;
thumb.classList.remove('pw-on');
};
const update = () => {
queued = false;
const y = window.scrollY || 0;
const p = Math.min(1, Math.max(0, y / maxScroll));
if (p !== progress) {
const moved = progress >= 0;
progress = p;
bar.style.strokeDashoffset = length * (1 - p);
const on = p > 0.002; // جلوگیری از نقطهی کوچک در حالت صفر
if (on !== barOn) {
barOn = on;
bar.style.opacity = on ? '1' : '0';
}
if (thumb) {
thumb.style.transform = `translateY(${4 + p * (viewH - 8 - thumbH)}px)`;
if (moved) {
if (!thumbOn) {
thumbOn = true;
thumb.classList.add('pw-on');
}
clearTimeout(hideTimer);
hideTimer = setTimeout(hideThumb, 900);
}
}
}
const show = y > SHOW_AFTER;
if (show !== visible) {
visible = show;
button.classList.toggle('paliweb-visible', show);
}
};
window.addEventListener('scroll', () => {
if (queued) return;
queued = true;
requestAnimationFrame(update);
}, { passive: true });
window.addEventListener('resize', measure, { passive: true });
window.addEventListener('load', () => { measure(); update(); });
if ('ResizeObserver' in window) {
new ResizeObserver(measure).observe(document.body);
}
button.addEventListener('click', () => {
if (window.paliwebLenis) {
window.paliwebLenis.scrollTo(0, { duration: 1.3 });
} else {
window.scrollTo({ top: 0, behavior: 'smooth' });
}
});
measure();
update();
/* ---------- Lenis (فقط دسکتاپ با ماوس) ---------- */
if (
!is('(min-width: 768px) and (hover: hover) and (pointer: fine)') ||
is('(prefers-reduced-motion: reduce)') ||
window.paliwebLenis
) {
return;
}
// المنتهایی که اسکرول داخلی خودشان را دارند
const NATIVE = '.elementor-popup-modal,.dialog-widget-content,.select2-container,.woocommerce-mini-cart,.elementor-menu-cart__container';
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/lenis@1.3.17/dist/lenis.min.js';
script.async = true;
script.onload = () => {
if (typeof Lenis === 'undefined' || window.paliwebLenis) return;
window.paliwebLenis = new Lenis({
autoRaf: true,
duration: 1.1, // کمتر = سریعتر
easing: (t) => Math.min(1, 1.001 - 2 ** (-10 * t)), // توقف نرم
smoothWheel: true,
wheelMultiplier: 1,
syncTouch: false,
prevent: (node) => !!node.closest?.(NATIVE)
});
measure();
};
document.head.appendChild(script);
})();
</script>
<?php
});