Personnaliser l'icône de chargement

Customize the loading icon

Note that it changes the main loading icon, but not the small loading icon (composer, search menu, etc).

  1. Edit your current theme or create a new theme component.

  2. Go in </head> and paste this code:

    <script type="text/x-handlebars" data-template-name="components/conditional-loading-spinner">
    {{#if condition}}
    <div class="custom-loader-container">
    
      <div class="my-custom-loader">
      </div>
    
    </div>
    {{else}}
      {{yield}}
    {{/if}}
    </script>
    

    Replace or fill .my-custom-loader with your loader HTML code.

  3. Go in CSS and paste this code:

    .custom-loader-container {
        position: relative;
        margin: 20px 0 20px;
        display: flex;
        justify-content: center;
    }
    

    Add your custom loader CSS.

Examples

Pulsing circles

image

Preview: https://theme-creator.discourse.org/theme/canapin/loader-pulse

Original code from https://codepen.io/victordarras/pen/vHitB

</head>:

<script type="text/x-handlebars" data-template-name="components/conditional-loading-spinner">
{{#if condition}}
<div class="custom-loader-container">

  <div class="loader-pulser">
  </div>
  
</div>
{{else}}
  {{yield}}
{{/if}}
</script>

CSS:

.custom-loader-container {
    position: relative;
    margin: 20px 0 20px;
    display: flex;
    justify-content: center;
}
.loader-pulser {
  display: inline-block;
  vertical-align: middle;
  position: relative;
  margin-right: 3em;
  font-size: 10px;
  width: 3.2em;
  height: 3.2em;
  right: 2em;
  position: relative;
  &:before, &:after {
    content: '';
    border: 2px solid #ccc;
    border-radius: 50%;
    height: 100%;
    width: 100%;
    position: absolute;
    animation: pulse .5s ease-out;
    animation-iteration-count: infinite;
    opacity: 0;
  }
  &:before {
    border: 2px solid #aaa;
    animation-delay: .15s;
  }
}
@keyframes pulse {
  0% {
    transform: scale(0.1,.1);
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    transform: scale(1.2,1.2);
    opacity: 0;
  }
}

Fading bars (svg animation)

image

Preview: https://theme-creator.discourse.org/theme/canapin/loader-bars

Original code from https://codepen.io/aurer/pen/jEGbA

</head>:

<script type="text/x-handlebars" data-template-name="components/conditional-loading-spinner">
{{#if condition}}
<div class="custom-loader-container">
    <div class="bars-loader">
      <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="24px" height="30px" viewBox="0 0 24 30" style="enable-background:new 0 0 50 50;" xml:space="preserve">
        <rect x="0" y="10" width="4" height="10" fill="#333" opacity="0.2">
          <animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0s" dur="0.4s" repeatCount="indefinite"></animate>
          <animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0s" dur="0.4s" repeatCount="indefinite"></animate>
          <animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0s" dur="0.4s" repeatCount="indefinite"></animate>
        </rect>
        <rect x="8" y="10" width="4" height="10" fill="#333" opacity="0.2">
          <animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0.15s" dur="0.4s" repeatCount="indefinite"></animate>
          <animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0.15s" dur="0.4s" repeatCount="indefinite"></animate>
          <animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0.15s" dur="0.4s" repeatCount="indefinite"></animate>
        </rect>
        <rect x="16" y="10" width="4" height="10" fill="#333" opacity="0.2">
          <animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0.3s" dur="0.4s" repeatCount="indefinite"></animate>
          <animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0.3s" dur="0.4s" repeatCount="indefinite"></animate>
          <animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0.3s" dur="0.4s" repeatCount="indefinite"></animate>
        </rect>
      </svg>
    </div>
</div>
{{else}}
  {{yield}}
{{/if}}
</script>

CSS:

.custom-loader-container {
    position: relative;
    margin: 20px 0 20px;
    display: flex;
    justify-content: center;
}
.bars-loader {
    svg path,
    svg rect{
      fill: #333;
    }
}

Unicycle

Preview: https://theme-creator.discourse.org/theme/canapin/loader-unicycle

Original code from https://codepen.io/Canapin/pen/gOrddVR

</head>:

<script type="text/x-handlebars" data-template-name="components/conditional-loading-spinner">
{{#if condition}}
<div class="custom-loader-container">

    <div class="unicycle-loader">
        <div class="saddle"></div>
        <div class="frame">
            <div class="hub"></div>
        </div>
        <div class="wheel">
            <div class="crank left">
                <div class="pedal"></div>
            </div>
            <div class="spokes">
                <div class="spoke"></div>
                <div class="spoke"></div>
                <div class="spoke"></div>
                <div class="spoke"></div>
                <div class="spoke"></div>
                <div class="spoke"></div>
                <div class="spoke"></div>
                <div class="spoke"></div>
                <div class="spoke"></div>
                <div class="spoke"></div>
                <div class="spoke"></div>
                <div class="spoke"></div>
            </div>
            <div class="crank">
                <div class="pedal"></div>
            </div>
        </div>
    </div>
    
</div>
{{else}}
  {{yield}}
{{/if}}
</script>

CSS:

.custom-loader-container {
    position: relative;
    margin: 20px 0 20px;
    display: flex;
    justify-content: center;
}
$color: black;
$speed: 1.5s;
.unicycle-loader {
    margin: 20px auto 20px auto;
    position: relative;
    transform: rotate(7.5deg) scale(0.70);
    opacity: .2;
    .saddle {
      width: 50px;
      height: 15px;
      background-color: $color;
      margin-left: 30px;
      position: relative;
      border-bottom-left-radius: 10px;
      border-bottom-right-radius: 20px;
      transform: rotate(-5deg);
      &:before {
        content: "";
        display: block;
        width: 30px;
        height: 20px;
        background-color: $color;
        border-radius: 50%;
        position: absolute;
        left: -5px;
        top: -5px;
      }
      &:after {
        content: "";
        display: block;
        width: 20px;
        height: 10px;
        background-color: $color;
        border-radius: 50%;
        position: absolute;
        right: -7px;
        top: 1px;
        transform: rotate(-35deg);
      }
    }
    
    .frame {
      width: 7px;
      height: 45px;
      background: $color;
      margin-left: 51px;
      position: relative;
      z-index: 1;
      margin-bottom: 15px;
      &:before {
        content: "";
        height: 75px;
        width: 11px;
        background: $color;
        display: block;
        position: relative;
        top: 100%;
        margin-left: -2px;
      }
    }
    
    .hub {
      position: absolute;
      bottom: calc(-100% - 30px);
      left: calc(50% - 0.5px);
      transform: translateX(-50%);
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background-color: $color;
      border: 3px solid $color;
      z-index: 2;
    }
    
    .loader * {
      box-sizing: border-box;
    }
    $tire_size: 1;
    .wheel {
      width: 110px;
      height: 110px;
      border: 10px solid $color;
      border-radius: 50%;
      position: relative;
      animation: $speed rotate360 infinite linear;
      box-sizing: border-box;
      &:before {
        content: "";
        width: 100%;
        height: 100%;
        border: 12px dotted $color;
        border-radius: 50%;
        margin-left: -12px;
        margin-top: -12px;
        position: absolute;
      }
      &:after {
        content: "";
        width: 100%;
        height: 100%;
        border: 12px dotted $color;
        border-radius: 50%;
        margin-left: -12px;
        margin-top: -12px;
        position: absolute;
        transform: rotate(12deg);
      }
    }
    
    .spoke {
      top: 50%;
      transform: translateY(-50%);
      left: 50%;
      transform: translateX(-50%);
      position: absolute;
      &:before {
        left: 0;
        content: "";
        height: 1px;
        width: 45px;
        transform-origin: 20px center;
        background: rgba(0,0,0,.5);
        position: absolute;
        transform: rotate(10deg);
      }
      &:after {
        left: 0;
        content: "";
        height: 1px;
        width: 45px;
        transform-origin: 20px center;
        background: rgba(0,0,0,.5);
        position: absolute;
        transform: rotate(10deg);
        transform: rotate(-10deg);
      }
      &:nth-child(1) {
        transform: rotate(30deg);
      }
      &:nth-child(2) {
        transform: rotate(60deg);
      }
      &:nth-child(3) {
        transform: rotate(90deg);
      }
      &:nth-child(4) {
        transform: rotate(120deg);
      }
      &:nth-child(5) {
        transform: rotate(150deg);
      }
      &:nth-child(6) {
        transform: rotate(180deg);
      }
      &:nth-child(7) {
        transform: rotate(210deg);
      }
      &:nth-child(8) {
        transform: rotate(240deg);
      }
      &:nth-child(9) {
        transform: rotate(270deg);
      }
      &:nth-child(10) {
        transform: rotate(300deg);
      }
      &:nth-child(11) {
        transform: rotate(330deg);
      }
      &:nth-child(12) {
        transform: rotate(360deg);
      }
    }
    
    .crank {
      height: 4px;
      width: 30%;
      background: $color;
      transform-origin: left 1px;
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translateY(-50%);
      .pedal {
        width: 20px;
        height: 6px;
        background: $color;
        position: absolute;
        right: -10px;
        margin-top: -1px;
        animation: $speed rotate360pedal infinite linear;
      }
      &.left {
        transform: rotate(180deg);
      }
    }
    
    @keyframes rotate360 {
      0% {
        transform: rotate(-50deg);
      }
    
      100% {
        transform: rotate(310deg);
      }
    }
    
    @keyframes rotate360pedal {
      0% {
        transform: rotate(410deg);
      }
    
      100% {
        transform: rotate(50deg);
      }
    }
}
26 « J'aime »

J’adore vraiment, vraiment ça. Comme nous avons un grand nombre de catégories, notre page de liste des catégories met quelques secondes à charger. Le monocycle me fait sourire !

5 « J'aime »

Bonjour @Canapin,
Merci de nous l’avoir partagé, je l’apprécie vraiment. :heart: :slight_smile:
Est-il possible de modifier le loader globalement ?

Merci ! :slight_smile:

1 « J'aime »

Si vous parlez du petit spinner, vous pouvez peut-être commencer par ceci :

2 « J'aime »

Merci @Canapin,

J’ai compris ! J’ai simplement ciblé la classe spinner et je l’ai remplacée par le chargeur pulsé.

2 « J'aime »

comment le remplacer par un gif ? par exemple :

Pas possible pour le moment.

1 « J'aime »

Puis-je le remplacer par une image statique ? Je ne le changerai probablement pas, mais.