搜索结果

×

搜索结果将在这里显示。

🛬 顶部横幅倒计时,改代码

{% comment %}
  限时促销横幅:黄底、橙色顶标、双色主标题、蓝色倒计时胶囊 + 底部双层波浪(SVG 平移动画)
{% endcomment %}

{% liquid
  assign pbc_uid = 'pbc-' | append: section.id
  assign end_iso = section.settings.countdown_end | strip
  assign pbc_wave_kf_back = 'pbc-wvb-' | append: section.id | replace: '--', '-' | replace: '__', '-' | handleize
  assign pbc_wave_kf_front = 'pbc-wvf-' | append: section.id | replace: '--', '-' | replace: '__', '-' | handleize
  assign pbc_pulse_kf = 'pbc-pulse-' | append: section.id | replace: '--', '-' | replace: '__', '-' | handleize
  assign pbc_pulse_peak = section.settings.suffix_pulse_peak_pct | default: 112 | times: 0.01
%}

<div class="pbc-section color-{{ section.settings.color_scheme }}" style="
  --pbc-bg: {{ section.settings.bg_color }};
  --pbc-badge-orange: {{ section.settings.badge_orange }};
  --pbc-badge-orange-text: {{ section.settings.badge_orange_text }};
  --pbc-head-blue: {{ section.settings.headline_blue }};
  --pbc-head-red: {{ section.settings.headline_red }};
  --pbc-sub-color: {{ section.settings.subhead_color }};
  --pbc-count-bg: {{ section.settings.countdown_pill_bg }};
  --pbc-count-text: {{ section.settings.countdown_pill_text }};
  --pbc-wave-back: {{ section.settings.wave_color_back }};
  --pbc-wave-front: {{ section.settings.wave_color_front }};
">
  <div class="pbc" id="{{ pbc_uid }}">
    <div class="pbc__inner page-width">
      {% if section.settings.top_badge_text != blank %}
        <div class="pbc__pill pbc__pill--top">
          <span class="pbc__pill-text">{{ section.settings.top_badge_text | escape }}</span>
        </div>
      {% endif %}

      <h2 class="pbc__headline">
        {% if section.settings.headline_prefix != blank %}
          <span class="pbc__headline-part pbc__headline-part--blue">{{ section.settings.headline_prefix | escape }}</span>
        {% endif %}
        {% if section.settings.headline_suffix != blank %}
          <span class="pbc__headline-part pbc__headline-part--red">{{ section.settings.headline_suffix | escape }}</span>
        {% endif %}
      </h2>

      {% if section.settings.subheadline != blank %}
        <p class="pbc__sub">{{ section.settings.subheadline | escape }}</p>
      {% endif %}

      <div
        class="pbc__pill pbc__pill--countdown"
        data-pbc-mode="{{ section.settings.countdown_mode | default: 'fixed_minutes' }}"
        data-pbc-duration-min="{{ section.settings.countdown_minutes | default: 30 }}"
        data-pbc-persist="{% if section.settings.countdown_persist %}true{% else %}false{% endif %}"
        data-pbc-storage-key="pbc-end-{{ section.id }}"
        data-pbc-end="{{ end_iso | escape }}"
      >
        <span class="pbc__count-label">{{ section.settings.countdown_prefix | escape }}</span>
        <strong class="pbc__count-value" data-pbc-display aria-live="polite">——</strong>
      </div>
    </div>

    <div class="pbc__waves" aria-hidden="true">
      <div class="pbc__wave-layer pbc__wave-layer--back">
        <svg class="pbc__wave-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2400 96" preserveAspectRatio="none">
          <path
            fill="var(--pbc-wave-back)"
            d="M0,56 C200,16 400,96 600,56 C800,16 1000,96 1200,56 L1200,96 L0,96 Z"
          />
          <path
            fill="var(--pbc-wave-back)"
            transform="translate(1200, 0)"
            d="M0,56 C200,16 400,96 600,56 C800,16 1000,96 1200,56 L1200,96 L0,96 Z"
          />
        </svg>
      </div>
      <div class="pbc__wave-layer pbc__wave-layer--front">
        <svg class="pbc__wave-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2400 96" preserveAspectRatio="none">
          <path
            fill="var(--pbc-wave-front)"
            d="M0,48 C240,8 480,88 720,48 C960,8 1200,88 1440,48 L1440,96 L0,96 Z"
          />
          <path
            fill="var(--pbc-wave-front)"
            transform="translate(1440, 0)"
            d="M0,48 C240,8 480,88 720,48 C960,8 1200,88 1440,48 L1440,96 L0,96 Z"
          />
        </svg>
      </div>
    </div>
  </div>
</div>

<style>
  #shopify-section-{{ section.id }} .pbc__wave-layer--back {
    animation: {{ pbc_wave_kf_back }} 18s linear infinite;
  }
  #shopify-section-{{ section.id }} .pbc__wave-layer--front {
    animation: {{ pbc_wave_kf_front }} 11s linear infinite reverse;
  }
  @keyframes {{ pbc_wave_kf_back }} {
    0% {
      transform: translate3d(0, 0, 0);
    }
    100% {
      transform: translate3d(-50%, 0, 0);
    }
  }
  @keyframes {{ pbc_wave_kf_front }} {
    0% {
      transform: translate3d(0, 0, 0);
    }
    100% {
      transform: translate3d(-50%, 0, 0);
    }
  }
  @media (prefers-reduced-motion: reduce) {
    {% if section.settings.force_wave_motion %}
      #shopify-section-{{ section.id }} .pbc__wave-layer--back {
        animation: {{ pbc_wave_kf_back }} 18s linear infinite !important;
      }
      #shopify-section-{{ section.id }} .pbc__wave-layer--front {
        animation: {{ pbc_wave_kf_front }} 11s linear infinite reverse !important;
      }
    {% else %}
      #shopify-section-{{ section.id }} .pbc__wave-layer--back,
      #shopify-section-{{ section.id }} .pbc__wave-layer--front {
        animation: none !important;
      }
    {% endif %}
  }
  {% if section.settings.enable_suffix_pulse %}
    #shopify-section-{{ section.id }} .pbc__headline-part--red {
      animation: {{ pbc_pulse_kf }} {{ section.settings.suffix_pulse_seconds }}s ease-in-out infinite;
      transform-origin: center center;
      will-change: transform;
    }
    @keyframes {{ pbc_pulse_kf }} {
      0%,
      100% {
        transform: scale(1);
      }
      50% {
        transform: scale({{ pbc_pulse_peak }});
      }
    }
    @media (prefers-reduced-motion: reduce) {
      {% if section.settings.force_suffix_pulse %}
        #shopify-section-{{ section.id }} .pbc__headline-part--red {
          animation: {{ pbc_pulse_kf }} {{ section.settings.suffix_pulse_seconds }}s ease-in-out infinite !important;
        }
      {% else %}
        #shopify-section-{{ section.id }} .pbc__headline-part--red {
          animation: none !important;
        }
      {% endif %}
    }
  {% endif %}
</style>

<script>
  (function () {
    var root = document.getElementById('{{ pbc_uid }}');
    if (!root) return;
    var pill = root.querySelector('.pbc__pill--countdown');
    var el = root.querySelector('[data-pbc-display]');
    if (!pill || !el) return;

    var mode = pill.getAttribute('data-pbc-mode') || 'fixed_minutes';
    var endAttr = pill.getAttribute('data-pbc-end');
    var durationMin = parseInt(pill.getAttribute('data-pbc-duration-min'), 10);
    var persist = pill.getAttribute('data-pbc-persist') === 'true';
    var storageKey = pill.getAttribute('data-pbc-storage-key') || '';

    if (!durationMin || durationMin < 1) durationMin = 30;

    var endMs;

    if (mode === 'end_datetime') {
      endMs = endAttr ? Date.parse(endAttr) : NaN;
    } else {
      var msLeft = durationMin * 60 * 1000;
      var now = Date.now();
      if (persist && storageKey && typeof localStorage !== 'undefined') {
        try {
          var stored = localStorage.getItem(storageKey);
          if (stored) {
            var parsed = parseInt(stored, 10);
            if (!isNaN(parsed) && parsed > now) {
              endMs = parsed;
            } else {
              localStorage.removeItem(storageKey);
            }
          }
        } catch (e) {}
      }
      if (typeof endMs !== 'number' || isNaN(endMs)) {
        endMs = now + msLeft;
        if (persist && storageKey && typeof localStorage !== 'undefined') {
          try {
            localStorage.setItem(storageKey, String(endMs));
          } catch (e) {}
        }
      }
    }

    function pad(n) {
      return (n < 10 ? '0' : '') + n;
    }

    function formatRemain(ms) {
      if (ms <= 0) return '已结束';
      var totalSec = Math.floor(ms / 1000);
      var days = Math.floor(totalSec / 86400);
      totalSec %= 86400;
      var h = Math.floor(totalSec / 3600);
      totalSec %= 3600;
      var m = Math.floor(totalSec / 60);
      var s = totalSec % 60;
      /* 不足 1 小时(且当日小时数为 0)不显示 h;否则显示 h、m、s */
      var msOnly = pad(m) + 'm ' + pad(s) + 's';
      var hms = pad(h) + 'h ' + pad(m) + 'm ' + pad(s) + 's';
      if (days > 0) {
        return h > 0 ? days + 'd ' + hms : days + 'd ' + msOnly;
      }
      return h > 0 ? hms : msOnly;
    }

    function tick() {
      if (mode === 'end_datetime') {
        if (!endAttr || isNaN(endMs)) {
          el.textContent = '请在设置中填写结束时间';
          return;
        }
      }

      var left = endMs - Date.now();
      if (isNaN(left)) {
        el.textContent = '时间格式有误';
        return;
      }
      el.textContent = formatRemain(left);
      if (left <= 0) return;
      setTimeout(tick, 1000);
    }

    tick();
  })();
</script>

{% stylesheet %}
  .pbc-section {
    position: relative;
    overflow: hidden;
  }

  .pbc {
    position: relative;
    background: var(--pbc-bg, #fff176);
    padding: clamp(1.25rem, 4vw, 2rem) 0 clamp(3.25rem, 8vw, 4.5rem);
    font-family: Impact, Haettenschweiler, 'Arial Narrow Bold', 'Segoe UI', sans-serif;
  }

  .pbc__inner {
    position: relative;
    z-index: 2;
    text-align: center;
    max-width: 52rem;
    margin: 0 auto;
    padding-inline: 0.75rem;
  }

  .pbc__pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    font-weight: 700;
    font-style: italic;
    letter-spacing: 0.02em;
  }

  .pbc__pill--top {
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-style: normal;
    font-weight: 800;
    background: var(--pbc-badge-orange, #c2410c);
    color: var(--pbc-badge-orange-text, #ffffff);
    padding: 0.5rem 1.25rem;
    font-size: clamp(0.9rem, 3vw, 1.1rem);
    margin-bottom: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    line-height: 1.25;
    border: 1px solid rgba(0, 0, 0, 0.2);
    box-shadow: none;
    text-shadow: none;
    -webkit-font-smoothing: antialiased;
  }

  .pbc__pill-text {
    white-space: nowrap;
  }

  .pbc__headline {
    margin: 0 0 0.35rem;
    font-size: clamp(2rem, 8vw, 3.75rem);
    line-height: 1.05;
    font-weight: 700;
    font-style: italic;
    letter-spacing: -0.02em;
  }

  .pbc__headline-part {
    display: inline-block;
    margin: 0 0.15em;
  }

  .pbc__headline-part--blue {
    color: var(--pbc-head-blue, #1e3a8a);
    text-shadow: none;
  }

  .pbc__headline-part--red {
    color: var(--pbc-head-red, #b91c1c);
    text-shadow: none;
  }

  .pbc__sub {
    margin: 0 0 0.85rem;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: clamp(0.78rem, 2.4vw, 1.05rem);
    font-weight: 800;
    font-style: normal;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--pbc-sub-color, #0f172a);
    text-shadow: none;
    line-height: 1.35;
  }

  .pbc__pill--countdown {
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-style: normal;
    background: var(--pbc-count-bg, #172554);
    color: var(--pbc-count-text, #ffffff);
    padding: 0.65rem 1.3rem;
    font-size: clamp(1rem, 3.2vw, 1.25rem);
    gap: 0.45rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
    flex-wrap: wrap;
    justify-content: center;
    max-width: 100%;
    text-shadow: none;
    line-height: 1.35;
    border: 1px solid rgba(255, 255, 255, 0.12);
    -webkit-font-smoothing: antialiased;
  }

  .pbc__count-label {
    font-style: normal;
    font-weight: 800;
    letter-spacing: 0.04em;
    flex-shrink: 0;
    text-transform: uppercase;
    opacity: 1;
  }

  .pbc__count-value {
    font-style: normal;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    word-break: keep-all;
    letter-spacing: 0.02em;
  }

  .pbc__waves {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: clamp(52px, 12vw, 72px);
    pointer-events: none;
    z-index: 1;
  }

  .pbc__wave-layer {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 200%;
    height: 100%;
    margin: 0;
    will-change: transform;
    backface-visibility: hidden;
  }

  .pbc__wave-layer--back {
    opacity: 0.45;
    z-index: 1;
  }

  .pbc__wave-layer--front {
    opacity: 1;
    z-index: 2;
  }

  .pbc__wave-svg {
    display: block;
    width: 100%;
    height: clamp(52px, 12vw, 72px);
    vertical-align: bottom;
  }
{% endstylesheet %}

{% schema %}
{
  "name": "促销横幅倒计时",
  "tag": "section",
  "class": "section-promo-banner-countdown",
  "settings": [
    {
      "type": "color_scheme",
      "id": "color_scheme",
      "label": "配色方案",
      "default": "scheme-1"
    },
    {
      "type": "header",
      "content": "背景与文字颜色"
    },
    {
      "type": "color",
      "id": "bg_color",
      "label": "横幅背景",
      "default": "#FFF176"
    },
    {
      "type": "color",
      "id": "badge_orange",
      "label": "顶部橙色胶囊背景",
      "info": "偏深的橙色配白字对比更清晰;可按品牌再调",
      "default": "#C2410C"
    },
    {
      "type": "color",
      "id": "badge_orange_text",
      "label": "顶部胶囊文字",
      "default": "#FFFFFF"
    },
    {
      "type": "color",
      "id": "headline_blue",
      "label": "主标题前半(蓝)",
      "default": "#1E3A8A"
    },
    {
      "type": "color",
      "id": "headline_red",
      "label": "主标题后半(红)",
      "default": "#B91C1C"
    },
    {
      "type": "color",
      "id": "subhead_color",
      "label": "副标题文字",
      "default": "#0F172A"
    },
    {
      "type": "color",
      "id": "countdown_pill_bg",
      "label": "倒计时胶囊背景",
      "info": "默认略加深,「ENDS IN」等字与白字对比更明显",
      "default": "#172554"
    },
    {
      "type": "color",
      "id": "countdown_pill_text",
      "label": "倒计时胶囊文字",
      "default": "#FFFFFF"
    },
    {
      "type": "color",
      "id": "wave_color_front",
      "label": "波浪前景(深蓝)",
      "default": "#1E3A8A"
    },
    {
      "type": "color",
      "id": "wave_color_back",
      "label": "波浪后层(浅蓝叠在后方)",
      "default": "#93C5FD"
    },
    {
      "type": "checkbox",
      "id": "force_wave_motion",
      "label": "系统开启「减少动态效果」时仍播放波浪动画",
      "info": "若波浪静止不动,可勾选此项(无障碍场景请按需关闭)",
      "default": true
    },
    {
      "type": "header",
      "content": "主标题红色字动画(如 80% OFF)"
    },
    {
      "type": "checkbox",
      "id": "enable_suffix_pulse",
      "label": "红色部分呼吸缩放(变大变小)",
      "info": "默认关闭,避免动态缩放导致文字发糊、不易辨认",
      "default": false
    },
    {
      "type": "range",
      "id": "suffix_pulse_seconds",
      "min": 0.8,
      "max": 2.5,
      "step": 0.1,
      "unit": "s",
      "label": "呼吸周期(越大越慢)",
      "default": 1.2
    },
    {
      "type": "range",
      "id": "suffix_pulse_peak_pct",
      "min": 104,
      "max": 125,
      "step": 1,
      "unit": "%",
      "label": "最大放大比例(相对原始字号)",
      "info": "112 表示峰值约为原来的 1.12 倍",
      "default": 112
    },
    {
      "type": "checkbox",
      "id": "force_suffix_pulse",
      "label": "系统开启「减少动态效果」时仍播放红色字缩放",
      "default": true
    },
    {
      "type": "header",
      "content": "文案"
    },
    {
      "type": "text",
      "id": "top_badge_text",
      "label": "顶部橙色胶囊文案",
      "default": "⚡ LIMITED-TIME MEGA SALE ⚡"
    },
    {
      "type": "text",
      "id": "headline_prefix",
      "label": "主标题前半(蓝色)",
      "default": "UP TO"
    },
    {
      "type": "text",
      "id": "headline_suffix",
      "label": "主标题后半(红色)",
      "default": "80% OFF"
    },
    {
      "type": "text",
      "id": "subheadline",
      "label": "副标题(大写)",
      "default": "EVERYTHING MUST GO! LIMITED STOCK!"
    },
    {
      "type": "text",
      "id": "countdown_prefix",
      "label": "倒计时前缀",
      "default": "距离结束还剩"
    },
    {
      "type": "header",
      "content": "倒计时规则"
    },
    {
      "type": "select",
      "id": "countdown_mode",
      "label": "倒计时方式",
      "options": [
        {
          "value": "fixed_minutes",
          "label": "固定多少分钟(从打开页面起算)"
        },
        {
          "value": "end_datetime",
          "label": "固定结束日期与时间(ISO)"
        }
      ],
      "default": "fixed_minutes"
    },
    {
      "type": "range",
      "id": "countdown_minutes",
      "min": 5,
      "max": 180,
      "step": 5,
      "unit": "min",
      "label": "倒计时时长(分钟)",
      "info": "仅在「固定多少分钟」模式下使用,例如 20、25、30",
      "default": 30
    },
    {
      "type": "checkbox",
      "id": "countdown_persist",
      "label": "刷新页面后倒计时继续(同一浏览器记住结束时刻)",
      "info": "关闭则每次打开页面重新从设定分钟数开始",
      "default": false
    },
    {
      "type": "text",
      "id": "countdown_end",
      "label": "倒计时结束时间(ISO 8601)",
      "info": "仅在「固定结束日期与时间」模式下使用。示例:2026-12-31T23:59:59 或 2026-12-31T23:59:59+08:00",
      "default": "2026-12-31T23:59:59"
    }
  ],
  "presets": [
    {
      "name": "促销横幅倒计时"
    }
  ]
}
{% endschema %}
发布时间: