Personalizar o ícone de carregamento

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 curtidas

Eu realmente, realmente amo isso. Como temos um grande número de categorias, a página de lista de categorias leva alguns segundos para carregar. A monocicleta me faz sorrir!

5 curtidas

Olá @Canapin,
Obrigado por compartilhar conosco, eu realmente gostei. :heart: :slight_smile:
É possível alterar o loader globalmente?

Obrigado! :slight_smile:

1 curtida

Se você está falando do pequeno spinner, talvez seja bom começar por aqui:

2 curtidas

Obrigado, @Canapin,

Entendi! Basta selecionar a classe spinner e alterá-la para o carregador pulsante.

2 curtidas

Como faço para substituí-lo por um GIF? Por exemplo:

Não é possível no momento.

1 curtida

Posso substituir por uma imagem estática? Provavelmente não vou alterá-la, mas…