BC Floating Sticker
Decorative
← Back to Sections

BC Floating Sticker

A versatile section that creates eye-catching floating images with smooth animations, perfect for adding visual flair and personality to any page. Whether you want a subtle decorative element or an attention-grabbing animated sticker, this section delivers professional results with complete creative control.

Key Features:

  • Position images anywhere on screen with precise X/Y coordinate controls
  • Five animation types: spinning, bouncing, swinging, growing, and floating effects
  • Scroll-triggered animations that respond to user interaction as they browse
  • Extensive image styling: 14 clip-path shapes, opacity controls, rotation, and object-fit options
  • Optional overlay text with responsive typography and rich text formatting
  • Smart responsive controls - hide on tablet/mobile to prevent layout interference
  • Complete color customization or seamless theme integration via Dawn color schemes

Perfect for: Brand logos, decorative elements, call-to-action stickers, seasonal graphics, product highlights, or any visual element that needs to stand out from the standard page flow without disrupting the user experience.

{%- style -%}
  .section-{{ section.id }} {
    {% if section.settings.use_custom_colors %}
      background-color: {{ section.settings.background_color }};
      color: {{ section.settings.text_color }};
    {% else %}
      color: rgb(var(--color-foreground));
    {% endif %}
  }

  .section-{{ section.id }} .bc-floating-image-container {
    position: relative;
    height: 0px;
  }

  .section-{{ section.id }} .bc-floating-image {
    position: absolute;
    z-index: {{ section.settings.z_index }};
    width: {{ section.settings.image_width }}px;
    height: {{ section.settings.image_height }}px;
    left: {{ section.settings.x_axis }}%;
    top: {{ section.settings.y_axis }}px;
    object-fit: {{ section.settings.image_object_fit }};
    opacity: {{ section.settings.image_opacity }}%;
    --rotation-degree: {{ section.settings.image_rotation }}deg;
    transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) rotate(var(--rotation-degree));
    transform-origin: center;
    {% if section.settings.animation_type == 'spinning' %}
      {% if section.settings.spin_on_scroll %}
        animation: none;
      {% else %}
        animation: bc-spin-{{ section.settings.spin_direction }}-{{ section.id }} {{ section.settings.spin_speed }}s linear infinite;
      {% endif %}
    {% elsif section.settings.animation_type == 'bouncing' %}
      {% if section.settings.bounce_on_scroll %}
        animation: none;
      {% else %}
        animation: bc-bounce-{{ section.id }} {{ section.settings.bounce_speed }}s linear infinite;
      {% endif %}
    {% elsif section.settings.animation_type == 'swinging' %}
      {% if section.settings.swing_on_scroll %}
        animation: none;
        transform-origin: top center;
      {% else %}
        animation: bc-swing-{{ section.id }} {{ section.settings.swing_speed }}s linear infinite;
        transform-origin: top center;
      {% endif %}
    {% elsif section.settings.animation_type == 'growing' %}
      {% if section.settings.grow_on_scroll %}
        animation: none;
      {% else %}
        animation: bc-grow-{{ section.id }} {{ section.settings.grow_duration }}s ease-out forwards;
      {% endif %}
    {% elsif section.settings.animation_type == 'floating' %}
      {% if section.settings.float_on_scroll %}
        animation: none;
      {% else %}
        animation: bc-float-{{ section.id }} {{ section.settings.float_duration }}s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
      {% endif %}
    {% endif %}
  }

  {% if section.settings.animation_type == 'spinning' and section.settings.spin_on_scroll %}
  .section-{{ section.id }} .bc-floating-image {
    animation: none;
    transition: transform 0.1s ease-out;
  }

  .section-{{ section.id }} .bc-floating-image.bc-scroll-spinning {
    transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) rotate(calc(var(--rotation-degree) + var(--scroll-rotation, 0deg)));
  }
  {% endif %}

  {% if section.settings.animation_type == 'bouncing' and section.settings.bounce_on_scroll %}
  .section-{{ section.id }} .bc-floating-image {
    animation: none;
    transition: transform 0.1s ease-out;
  }

  .section-{{ section.id }} .bc-floating-image.bc-scroll-bouncing {
    transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) translateY(var(--scroll-bounce, 0px)) rotate(var(--rotation-degree));
  }
  {% endif %}

  {% if section.settings.animation_type == 'swinging' and section.settings.swing_on_scroll %}
  .section-{{ section.id }} .bc-floating-image {
    animation: none;
    transform-origin: top center;
    transition: transform 0.1s ease-out;
  }

  .section-{{ section.id }} .bc-floating-image.bc-scroll-swinging {
    transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) rotate(calc(var(--rotation-degree) + var(--scroll-swing, 0deg)));
  }
  {% endif %}

  {% if section.settings.animation_type == 'growing' and section.settings.grow_on_scroll %}
  .section-{{ section.id }} .bc-floating-image {
    animation: none;
    transition: transform 0.1s ease-out;
  }

  .section-{{ section.id }} .bc-floating-image.bc-scroll-growing {
    transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) rotate(var(--rotation-degree)) scale(var(--scroll-scale, 1));
  }
  {% endif %}

  {% if section.settings.animation_type == 'floating' and section.settings.float_on_scroll %}
  .section-{{ section.id }} .bc-floating-image {
    animation: none;
    transition: transform 0.1s ease-out;
  }

  .section-{{ section.id }} .bc-floating-image.bc-scroll-floating {
    transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) translateY(var(--scroll-float, 0px)) rotate(var(--rotation-degree));
  }
  {% endif %}

  @keyframes bc-spin-clockwise-{{ section.id }} {
    from {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) rotate(var(--rotation-degree));
    }
    to {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) rotate(calc(var(--rotation-degree) + 360deg));
    }
  }

  @keyframes bc-spin-counterclockwise-{{ section.id }} {
    from {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) rotate(var(--rotation-degree));
    }
    to {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) rotate(calc(var(--rotation-degree) - 360deg));
    }
  }

  @keyframes bc-bounce-{{ section.id }} {
    0% {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) translateY(0) rotate(var(--rotation-degree));
    }
    50% {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) translateY(-{{ section.settings.bounce_height }}px) rotate(var(--rotation-degree));
    }
    100% {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) translateY(0) rotate(var(--rotation-degree));
    }
  }

  @keyframes bc-swing-{{ section.id }} {
    0% {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) rotate(calc(var(--rotation-degree) - {{ section.settings.swing_angle }}deg));
    }
    50% {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) rotate(calc(var(--rotation-degree) + {{ section.settings.swing_angle }}deg));
    }
    100% {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) rotate(calc(var(--rotation-degree) - {{ section.settings.swing_angle }}deg));
    }
  }

  @keyframes bc-grow-{{ section.id }} {
    0% {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) rotate(var(--rotation-degree)) scale({{ section.settings.grow_start_size | divided_by: 100.0 }});
    }
    100% {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) rotate(var(--rotation-degree)) scale({{ section.settings.grow_end_size | divided_by: 100.0 }});
    }
  }

  @keyframes bc-float-{{ section.id }} {
    0% {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) translateY({{ section.settings.float_start_offset }}px) rotate(var(--rotation-degree));
    }
    100% {
      transform: translateX({% if section.settings.center_horizontally %}-50%{% else %}0%{% endif %}) translateY(0) rotate(var(--rotation-degree));
    }
  }

  .section-{{ section.id }} .bc-floating-text * {
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 3;
    transform: translate(-50%, -50%);
    text-align: center;
    font-size: clamp({{ section.settings.text_size | times: section.settings.text_mobile_scale_ratio }}rem, 4vw, {{ section.settings.text_size }}rem) !important;
    line-height: {{ section.settings.text_line_height }};
    max-width: {{ section.settings.text_max_width }}ch;
  }

  {% if section.settings.hide_tablet %}
  @media screen and (max-width: 991px) {
    .section-{{ section.id }} .bc-floating-image {
      display: none;
    }
  }
  {% endif %}

  {% if section.settings.hide_mobile %}
  @media screen and (max-width: 767px) {
    .section-{{ section.id }} .bc-floating-image {
      display: none;
    }
  }
  {% endif %}

  {% if section.settings.image_clipping == 'circle' %}
  .section-{{ section.id }} .bc-floating-image {
    clip-path: circle(50% at 50% 50%);
  }
  {% endif %}

  {% if section.settings.image_clipping == 'parallelogram' %}
  .section-{{ section.id }} .bc-floating-image {
    clip-path: polygon(25% 0%, 100% 0%, 75% 100%, 0% 100%);
  }
  {% endif %}

  {% if section.settings.image_clipping == 'diamond' %}
  .section-{{ section.id }} .bc-floating-image {
    clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  }
  {% endif %}

  {% if section.settings.image_clipping == 'hexagon' %}
  .section-{{ section.id }} .bc-floating-image {
    clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
  }
  {% endif %}

  {% if section.settings.image_clipping == 'octagon' %}
  .section-{{ section.id }} .bc-floating-image {
    clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
  }
  {% endif %}

  {% if section.settings.image_clipping == 'bevel' %}
  .section-{{ section.id }} .bc-floating-image {
    clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);
  }
  {% endif %}

  {% if section.settings.image_clipping == 'rabbet' %}
  .section-{{ section.id }} .bc-floating-image {
    clip-path: polygon(0% 15%, 15% 15%, 15% 0%, 85% 0%, 85% 15%, 100% 15%, 100% 85%, 85% 85%, 85% 100%, 15% 100%, 15% 85%, 0% 85%);
  }
  {% endif %}

  {% if section.settings.image_clipping == 'left-point' %}
  .section-{{ section.id }} .bc-floating-image {
    clip-path: polygon(25% 0%, 100% 0%, 100% 100%, 25% 100%, 0% 50%);
  }
  {% endif %}

  {% if section.settings.image_clipping == 'right-point' %}
  .section-{{ section.id }} .bc-floating-image {
    clip-path: polygon(0% 0%, 75% 0%, 100% 50%, 75% 100%, 0% 100%);
  }
  {% endif %}

  {% if section.settings.image_clipping == 'left-chevron' %}
  .section-{{ section.id }} .bc-floating-image {
    clip-path: polygon(100% 0%, 75% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
  }
  {% endif %}

  {% if section.settings.image_clipping == 'right-chevron' %}
  .section-{{ section.id }} .bc-floating-image {
    clip-path: polygon(75% 0%, 100% 50%, 75% 100%, 0% 100%, 25% 50%, 0% 0%);
  }
  {% endif %}

  {% if section.settings.image_clipping == 'star' %}
  .section-{{ section.id }} .bc-floating-image {
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
  }
  {% endif %}

  {% if section.settings.image_clipping == 'arch' %}
  .section-{{ section.id }} .bc-floating-image {
    border-top-left-radius: 100%;
    border-top-right-radius: 100%;
  }
  {% endif %}
{%- endstyle -%}

<section class="section-{{ section.id }}{% unless section.settings.use_custom_colors %} color-{{ section.settings.color_scheme }}{% endunless %}">
  <div class="bc-floating-image-container">
    {% if section.settings.show_text and section.settings.text_content != blank %}
      <div class="bc-floating-text">{{ section.settings.text_content }}</div>
    {% endif %}
    {% if section.settings.image != blank %}
      <img
        src="{{ section.settings.image | img_url: width: 500 }}"
        alt="{{ section.settings.image_alt | default: 'Floating image' }}"
        loading="{{ section.settings.image_loading }}"
        class="bc-floating-image{% if section.settings.animation_type == 'spinning' and section.settings.spin_on_scroll %} bc-scroll-spinning{% endif %}{% if section.settings.animation_type == 'bouncing' and section.settings.bounce_on_scroll %} bc-scroll-bouncing{% endif %}{% if section.settings.animation_type == 'swinging' and section.settings.swing_on_scroll %} bc-scroll-swinging{% endif %}{% if section.settings.animation_type == 'growing' and section.settings.grow_on_scroll %} bc-scroll-growing{% endif %}{% if section.settings.animation_type == 'floating' and section.settings.float_on_scroll %} bc-scroll-floating{% endif %}"
        {% if section.settings.animation_type == 'spinning' and section.settings.spin_on_scroll %}
          data-spin-direction="{{ section.settings.spin_direction }}"
          data-spin-speed="{{ section.settings.spin_speed }}"
        {% endif %}
        {% if section.settings.animation_type == 'bouncing' and section.settings.bounce_on_scroll %}
          data-bounce-height="{{ section.settings.bounce_height }}"
        {% endif %}
        {% if section.settings.animation_type == 'swinging' and section.settings.swing_on_scroll %}
          data-swing-angle="{{ section.settings.swing_angle }}"
        {% endif %}
        {% if section.settings.animation_type == 'growing' and section.settings.grow_on_scroll %}
          data-grow-start="{{ section.settings.grow_start_size }}"
          data-grow-end="{{ section.settings.grow_end_size }}"
        {% endif %}
        {% if section.settings.animation_type == 'floating' and section.settings.float_on_scroll %}
          data-float-offset="{{ section.settings.float_start_offset }}"
        {% endif %}
      >
    {% endif %}
  </div>

  {% comment %} Designed and Developed by Bungalow Creative. Get sections like these at The Section Studio https://bungalowcreative.co/pages/the-section-studio {% endcomment %}
</section>

{% comment %} Replace all the individual animation script blocks with this single consolidated block {% endcomment %}

{% if section.settings.animation_type == 'spinning' and section.settings.spin_on_scroll %}
  <script>
    (function () {
      const sectionId = '{{ section.id }}';
      const namespace = `bcFloatingSpinning_${sectionId}`;

      document.addEventListener('DOMContentLoaded', function () {
        const spinningImages = document.querySelectorAll('.section-{{ section.id }} .bc-scroll-spinning');

        window[namespace] = {
          elements: spinningImages,
          updateSpinRotation: function () {
            this.elements.forEach((img) => {
              const rect = img.getBoundingClientRect();
              const windowHeight = window.innerHeight;
              const imgTop = rect.top;
              const scrollProgress = -imgTop / windowHeight;
              const direction = img.dataset.spinDirection === 'counterclockwise' ? -1 : 1;
              const rotation = scrollProgress * 360 * direction;
              img.style.setProperty('--scroll-rotation', rotation + 'deg');
            });
          },
        };

        let ticking = false;
        function handleScroll() {
          if (!ticking) {
            requestAnimationFrame(function () {
              window[namespace].updateSpinRotation();
              ticking = false;
            });
            ticking = true;
          }
        }

        window.addEventListener('scroll', handleScroll, { passive: true });
        window[namespace].updateSpinRotation(); // Initial call
      });
    })();
  </script>
{% endif %}

{% if section.settings.animation_type == 'bouncing' and section.settings.bounce_on_scroll %}
  <script>
    (function () {
      const sectionId = '{{ section.id }}';
      const namespace = `bcFloatingBouncing_${sectionId}`;

      document.addEventListener('DOMContentLoaded', function () {
        const bouncingImages = document.querySelectorAll('.section-{{ section.id }} .bc-scroll-bouncing');

        window[namespace] = {
          elements: bouncingImages,
          updateBouncePosition: function () {
            this.elements.forEach((img) => {
              const rect = img.getBoundingClientRect();
              const windowHeight = window.innerHeight;
              const imgCenter = rect.top + rect.height / 2;
              const viewportCenter = windowHeight / 2;
              const distanceFromCenter = (viewportCenter - imgCenter) / (windowHeight / 2);
              const bounceHeight = img.dataset.bounceHeight || 35;
              const bounceOffset = Math.sin(Math.abs(distanceFromCenter) * Math.PI) * bounceHeight;
              img.style.setProperty('--scroll-bounce', -bounceOffset + 'px');
            });
          },
        };

        let ticking = false;
        function handleScroll() {
          if (!ticking) {
            requestAnimationFrame(function () {
              window[namespace].updateBouncePosition();
              ticking = false;
            });
            ticking = true;
          }
        }

        window.addEventListener('scroll', handleScroll, { passive: true });
        window[namespace].updateBouncePosition(); // Initial call
      });
    })();
  </script>
{% endif %}

{% if section.settings.animation_type == 'swinging' and section.settings.swing_on_scroll %}
  <script>
    (function () {
      const sectionId = '{{ section.id }}';
      const namespace = `bcFloatingSwinging_${sectionId}`;

      document.addEventListener('DOMContentLoaded', function () {
        const swingingImages = document.querySelectorAll('.section-{{ section.id }} .bc-scroll-swinging');

        window[namespace] = {
          elements: swingingImages,
          updateSwingPosition: function () {
            this.elements.forEach((img) => {
              const rect = img.getBoundingClientRect();
              const windowHeight = window.innerHeight;
              const imgCenter = rect.top + rect.height / 2;
              const viewportCenter = windowHeight / 2;
              const distanceFromCenter = (viewportCenter - imgCenter) / (windowHeight / 2);
              const swingAngle = img.dataset.swingAngle || 20;
              const swingOffset = Math.sin(distanceFromCenter * Math.PI) * swingAngle;
              img.style.setProperty('--scroll-swing', swingOffset + 'deg');
            });
          },
        };

        let ticking = false;
        function handleScroll() {
          if (!ticking) {
            requestAnimationFrame(function () {
              window[namespace].updateSwingPosition();
              ticking = false;
            });
            ticking = true;
          }
        }

        window.addEventListener('scroll', handleScroll, { passive: true });
        window[namespace].updateSwingPosition(); // Initial call
      });
    })();
  </script>
{% endif %}

{% if section.settings.animation_type == 'growing' and section.settings.grow_on_scroll %}
  <script>
    (function () {
      const sectionId = '{{ section.id }}';
      const namespace = `bcFloatingGrowing_${sectionId}`;

      document.addEventListener('DOMContentLoaded', function () {
        const growingImages = document.querySelectorAll('.section-{{ section.id }} .bc-scroll-growing');

        window[namespace] = {
          elements: growingImages,
          updateGrowScale: function () {
            this.elements.forEach((img) => {
              const rect = img.getBoundingClientRect();
              const windowHeight = window.innerHeight;
              const imgCenter = rect.top + rect.height / 2;
              const visibilityProgress = Math.max(0, Math.min(1, (windowHeight - imgCenter) / windowHeight));
              const startSize = parseFloat(img.dataset.growStart || 75) / 100;
              const endSize = parseFloat(img.dataset.growEnd || 100) / 100;
              const currentScale = startSize + (endSize - startSize) * visibilityProgress;
              img.style.setProperty('--scroll-scale', currentScale);
            });
          },
        };

        let ticking = false;
        function handleScroll() {
          if (!ticking) {
            requestAnimationFrame(function () {
              window[namespace].updateGrowScale();
              ticking = false;
            });
            ticking = true;
          }
        }

        window.addEventListener('scroll', handleScroll, { passive: true });
        window[namespace].updateGrowScale(); // Initial call
      });
    })();
  </script>
{% endif %}

{% if section.settings.animation_type == 'floating' and section.settings.float_on_scroll %}
  <script>
    (function () {
      const sectionId = '{{ section.id }}';
      const namespace = `bcFloatingFloat_${sectionId}`;

      document.addEventListener('DOMContentLoaded', function () {
        const floatingImages = document.querySelectorAll('.section-{{ section.id }} .bc-scroll-floating');

        window[namespace] = {
          elements: floatingImages,
          updateFloatPosition: function () {
            this.elements.forEach((img) => {
              const rect = img.getBoundingClientRect();
              const windowHeight = window.innerHeight;
              const imgCenter = rect.top + rect.height / 2;
              const visibilityProgress = Math.max(0, Math.min(1, (windowHeight - imgCenter) / windowHeight));
              const floatOffset = parseFloat(img.dataset.floatOffset || 80);
              const currentOffset = floatOffset * (1 - visibilityProgress);
              img.style.setProperty('--scroll-float', currentOffset + 'px');
            });
          },
        };

        let ticking = false;
        function handleScroll() {
          if (!ticking) {
            requestAnimationFrame(function () {
              window[namespace].updateFloatPosition();
              ticking = false;
            });
            ticking = true;
          }
        }

        window.addEventListener('scroll', handleScroll, { passive: true });
        window[namespace].updateFloatPosition(); // Initial call
      });
    })();
  </script>
{% endif %}

{% comment %} Designed and Developed by Bungalow Creative. Get sections like these at The Section Studio https://bungalowcreative.co/pages/the-section-studio {% endcomment %}

{% schema %}
{
  "name": "BC Floating Image",
  "settings": [
    {
      "type": "header",
      "content": "Colors"
    },
    {
      "type": "color_scheme",
      "id": "color_scheme",
      "label": "Color Scheme",
      "default": "scheme-1"
    },
    {
      "type": "checkbox",
      "id": "use_custom_colors",
      "label": "Use custom colors instead of a Dawn color scheme",
      "default": false
    },
    {
      "type": "color",
      "id": "background_color",
      "label": "Background Color",
      "default": "#ffffff"
    },
    {
      "type": "color",
      "id": "text_color",
      "label": "Text Color",
      "default": "#000000"
    },
    {
      "type": "header",
      "content": "Section Settings"
    },
    {
      "type": "range",
      "id": "horizontal_padding_desktop",
      "label": "Horizontal Padding - Desktop",
      "min": 0,
      "max": 150,
      "step": 5,
      "default": 50,
      "unit": "px"
    },
    {
      "type": "range",
      "id": "horizontal_padding_tablet",
      "label": "Horizontal Padding - Tablet",
      "min": 0,
      "max": 150,
      "step": 5,
      "default": 40,
      "unit": "px"
    },
    {
      "type": "range",
      "id": "horizontal_padding_mobile",
      "label": "Horizontal Padding - Mobile",
      "min": 0,
      "max": 150,
      "step": 5,
      "default": 10,
      "unit": "px"
    },
    {
      "type": "range",
      "id": "top_padding",
      "label": "Top Padding",
      "min": 0,
      "max": 150,
      "step": 5,
      "default": 0,
      "unit": "px"
    },
    {
      "type": "range",
      "id": "bottom_padding",
      "label": "Bottom Padding",
      "min": 0,
      "max": 150,
      "step": 5,
      "default": 0,
      "unit": "px"
    },
    {
      "type": "range",
      "id": "top_border_thickness",
      "label": "Top Border Thickness",
      "min": 0,
      "max": 20,
      "step": 1,
      "default": 0,
      "unit": "px"
    },
    {
      "type": "range",
      "id": "bottom_border_thickness",
      "label": "Bottom Border Thickness",
      "min": 0,
      "max": 20,
      "step": 1,
      "default": 0,
      "unit": "px"
    },
    {
      "type": "color",
      "id": "border_color",
      "label": "Border Color",
      "default": "#000000"
    },
    {
      "type": "header",
      "content": "Text Section"
    },
    {
      "type": "checkbox",
      "id": "show_text",
      "label": "Show overlay text",
      "default": false
    },
    {
      "type": "richtext",
      "id": "text_content",
      "label": "Text Content",
      "default": "<p>Your text here</p>"
    },
    {
      "type": "range",
      "id": "text_size",
      "label": "Text Font Size",
      "min": 0.5,
      "max": 8,
      "step": 0.1,
      "default": 1.4,
      "unit": "rem",
      "info": "Font size in rem units (good for accessibility)"
    },
    {
      "type": "range",
      "id": "text_line_height",
      "label": "Text Line Height",
      "min": 1,
      "max": 2,
      "step": 0.1,
      "default": 1.4
    },
    {
      "type": "range",
      "id": "text_max_width",
      "label": "Text Max Width",
      "min": 10,
      "max": 100,
      "step": 1,
      "default": 14,
      "unit": "ch"
    },
    {
      "type": "range",
      "id": "text_mobile_scale_ratio",
      "label": "Text Mobile Scale Ratio",
      "min": 0.5,
      "max": 1,
      "step": 0.1,
      "default": 1,
      "unit": "Γ—",
      "info": "Controls how much text shrinks on smaller screens"
    },
    {
      "type": "header",
      "content": "Media Section"
    },
    {
      "type": "image_picker",
      "id": "image",
      "label": "Image"
    },
    {
      "type": "text",
      "id": "image_alt",
      "label": "Image Alt Text",
      "placeholder": "e.g. Floating decorative image"
    },
    {
      "type": "select",
      "id": "image_loading",
      "label": "Image Loading",
      "options": [
        {
          "value": "lazy",
          "label": "Lazy"
        },
        {
          "value": "eager",
          "label": "Eager"
        }
      ],
      "default": "lazy"
    },
    {
      "type": "range",
      "id": "image_width",
      "label": "Image Width",
      "min": 50,
      "max": 500,
      "step": 5,
      "default": 300,
      "unit": "px"
    },
    {
      "type": "range",
      "id": "image_height",
      "label": "Image Height",
      "min": 50,
      "max": 500,
      "step": 5,
      "default": 300,
      "unit": "px"
    },
    {
      "type": "select",
      "id": "image_object_fit",
      "label": "Image Object Fit",
      "options": [
        {
          "value": "cover",
          "label": "Cover"
        },
        {
          "value": "contain",
          "label": "Contain"
        }
      ],
      "default": "contain",
      "info": "Cover fills the entire area (may crop), Contain fits the entire image (may show empty space)"
    },
    {
      "type": "select",
      "id": "image_clipping",
      "label": "Image Clipping",
      "options": [
        {
          "value": "none",
          "label": "None"
        },
        {
          "value": "circle",
          "label": "Circle"
        },
        {
          "value": "parallelogram",
          "label": "Parallelogram"
        },
        {
          "value": "diamond",
          "label": "Diamond"
        },
        {
          "value": "hexagon",
          "label": "Hexagon"
        },
        {
          "value": "octagon",
          "label": "Octagon"
        },
        {
          "value": "bevel",
          "label": "Bevel"
        },
        {
          "value": "rabbet",
          "label": "Rabbet"
        },
        {
          "value": "star",
          "label": "Star"
        },
        {
          "value": "arch",
          "label": "Arch"
        },
        {
          "value": "left-point",
          "label": "Left Point"
        },
        {
          "value": "right-point",
          "label": "Right Point"
        },
        {
          "value": "left-chevron",
          "label": "Left Chevron"
        },
        {
          "value": "right-chevron",
          "label": "Right Chevron"
        }
      ],
      "default": "none",
      "info": "Some clip paths may require a square image aspect ratio to appear their best. Non-polygon clip paths require a fixed size due to SVG limitations."
    },
    {
      "type": "header",
      "content": "Position & Layout"
    },
    {
      "type": "range",
      "id": "x_axis",
      "label": "Position - X",
      "min": -50,
      "max": 150,
      "step": 2,
      "default": 0,
      "unit": "%"
    },
    {
      "type": "checkbox",
      "id": "center_horizontally",
      "label": "Center Horizontally",
      "default": false,
      "info": "Set \"Position - X\" to 50% and check this box to center your image horizontally"
    },
    {
      "type": "range",
      "id": "y_axis",
      "label": "Position - Y",
      "min": -500,
      "max": 500,
      "step": 10,
      "default": 0,
      "unit": "px"
    },
    {
      "type": "range",
      "id": "image_rotation",
      "label": "Image Tilt",
      "min": -50,
      "max": 50,
      "step": 1,
      "default": 0
    },
    {
      "type": "number",
      "id": "z_index",
      "label": "Z-Index",
      "default": 2,
      "info": "Z-index helps you select the order in which items stack on top of each other."
    },
    {
      "type": "header",
      "content": "Animations"
    },
    {
      "type": "select",
      "id": "animation_type",
      "label": "Animation",
      "options": [
        {
          "value": "none",
          "label": "None"
        },
        {
          "value": "spinning",
          "label": "Spinning"
        },
        {
          "value": "bouncing",
          "label": "Bouncing"
        },
        {
          "value": "swinging",
          "label": "Swinging"
        },
        {
          "value": "growing",
          "label": "Growing"
        },
        {
          "value": "floating",
          "label": "Floating"
        }
      ],
      "default": "none"
    },
    {
      "type": "header",
      "content": "Spinning Animation"
    },
    {
      "type": "select",
      "id": "spin_direction",
      "label": "Spin Direction",
      "options": [
        {
          "value": "clockwise",
          "label": "Clockwise"
        },
        {
          "value": "counterclockwise",
          "label": "Counterclockwise"
        }
      ],
      "default": "clockwise"
    },
    {
      "type": "range",
      "id": "spin_speed",
      "label": "Spin Speed",
      "min": 1,
      "max": 60,
      "step": 1,
      "default": 30,
      "unit": "s",
      "info": "Duration in seconds for one complete rotation"
    },
    {
      "type": "checkbox",
      "id": "spin_on_scroll",
      "label": "Spin on Scroll",
      "default": false,
      "info": "Spin the image based on scroll position instead of continuous animation"
    },
    {
      "type": "header",
      "content": "Bouncing Animation"
    },
    {
      "type": "range",
      "id": "bounce_speed",
      "label": "Bounce Speed",
      "min": 0.5,
      "max": 5,
      "step": 0.1,
      "default": 3.5,
      "unit": "s",
      "info": "Duration in seconds for one complete bounce cycle"
    },
    {
      "type": "range",
      "id": "bounce_height",
      "label": "Bounce Height",
      "min": 5,
      "max": 100,
      "step": 5,
      "default": 35,
      "unit": "px",
      "info": "Maximum height of the bounce effect"
    },
    {
      "type": "checkbox",
      "id": "bounce_on_scroll",
      "label": "Bounce on Scroll",
      "default": false,
      "info": "Bounce the image based on scroll position instead of continuous animation"
    },
    {
      "type": "header",
      "content": "Swinging Animation"
    },
    {
      "type": "range",
      "id": "swing_speed",
      "label": "Swing Speed",
      "min": 0.5,
      "max": 8,
      "step": 0.1,
      "default": 3,
      "unit": "s",
      "info": "Duration in seconds for one complete swing cycle"
    },
    {
      "type": "range",
      "id": "swing_angle",
      "label": "Swing Angle",
      "min": 5,
      "max": 45,
      "step": 1,
      "default": 20,
      "unit": "deg",
      "info": "Maximum angle of the swing from center"
    },
    {
      "type": "checkbox",
      "id": "swing_on_scroll",
      "label": "Swing on Scroll",
      "default": false,
      "info": "Swing the image based on scroll position instead of continuous animation"
    },
    {
      "type": "header",
      "content": "Growing Animation"
    },
    {
      "type": "range",
      "id": "grow_duration",
      "label": "Grow Duration",
      "min": 0.3,
      "max": 5,
      "step": 0.1,
      "default": 1.5,
      "unit": "s",
      "info": "Duration of the growing animation"
    },
    {
      "type": "range",
      "id": "grow_start_size",
      "label": "Start Size",
      "min": 0,
      "max": 100,
      "step": 5,
      "default": 75,
      "unit": "%",
      "info": "Initial size as percentage of original (0% = invisible)"
    },
    {
      "type": "range",
      "id": "grow_end_size",
      "label": "End Size",
      "min": 50,
      "max": 200,
      "step": 5,
      "default": 100,
      "unit": "%",
      "info": "Final size as percentage of original (100% = normal size)"
    },
    {
      "type": "checkbox",
      "id": "grow_on_scroll",
      "label": "Grow on Scroll",
      "default": false,
      "info": "Scale the image based on scroll position instead of one-time animation"
    },
    {
      "type": "header",
      "content": "Floating Animation"
    },
    {
      "type": "range",
      "id": "float_duration",
      "label": "Float Duration",
      "min": 0.3,
      "max": 5,
      "step": 0.1,
      "default": 1,
      "unit": "s",
      "info": "Duration of the floating animation"
    },
    {
      "type": "range",
      "id": "float_start_offset",
      "label": "Start Offset",
      "min": 20,
      "max": 200,
      "step": 10,
      "default": 80,
      "unit": "px",
      "info": "How far down the image starts before floating up"
    },
    {
      "type": "checkbox",
      "id": "float_on_scroll",
      "label": "Float on Scroll",
      "default": false,
      "info": "Float the image based on scroll position instead of one-time animation"
    },
    {
      "type": "header",
      "content": "Advanced Options"
    },
    {
      "type": "checkbox",
      "id": "hide_tablet",
      "label": "Hide on Tablet",
      "default": true,
      "info": "Recommended if image overlaps and hides other items at tablet size"
    },
    {
      "type": "checkbox",
      "id": "hide_mobile",
      "label": "Hide on Mobile",
      "default": true,
      "info": "Recommended if image overlaps and hides other items at mobile size"
    }
  ],
  "presets": [
    {
      "name": "BC Floating Image"
    }
  ]
}
{% endschema %}