svg mask для лоадера

216
13 декабря 2017, 21:55

Есть такой интересный лоадер:

Как я понимаю, должна быть картинка, svg лоадер, маска. Принцип как тут - пример (использование mask).

Но пока есть набросок:

html, 
body { 
  margin: 0; 
  padding: 0; 
  width: 100%; 
  height: 100%; 
} 
 
* { 
  box-sizing: border-box; 
} 
 
.box { 
  width: 100%; 
  height: 100%; 
  background: url(http://farm4.staticflickr.com/3137/2698866948_f273755a09_z.jpg?zz=1) center no-repeat; 
  -webkit-background-size: cover; 
  background-size: cover; 
  display: flex; 
  align-items: center; 
  justify-content: center; 
} 
 
.loader { 
  max-width: 200px; 
  width: 100%; 
}
<div class="box"> 
  <div class="loader"> 
    <svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" xmlns="http://www.w3.org/2000/svg"> 
 
      <defs> 
        <clipPath id="clip"> 
          <path  d="M 50 50 L 35 0 L 65 0 z" /> 
        </clipPath> 
 
        <ellipse id= "MyEllipse" clip-path="url(#clip)" 
                 cx="50" cy="50" rx="40" ry="40" 
                 style="fill:none; stroke:#eee" stroke-width="20" /> 
      </defs> 
 
 
      <use xlink:href="#MyEllipse" /> 
      <use xlink:href="#MyEllipse" transform="rotate(40 50 50)" /> 
      <use xlink:href="#MyEllipse" transform="rotate(80 50 50)" /> 
      <use xlink:href="#MyEllipse" transform="rotate(120 50 50)"/> 
      <use xlink:href="#MyEllipse" transform="rotate(160 50 50)"/> 
      <use xlink:href="#MyEllipse" transform="rotate(200 50 50)"/> 
      <use xlink:href="#MyEllipse" transform="rotate(240 50 50)"/> 
      <use xlink:href="#MyEllipse" transform="rotate(280 50 50)"/> 
      <use xlink:href="#MyEllipse" transform="rotate(320 50 50)"/> 
 
 
      <ellipse clip-path="url(#clip)" 
               cx="50" cy="50" rx="40" ry="40" 
               style="fill:none; stroke:black" stroke-width="20"  > 
         
        <animateTransform attributeName="transform" attributeType="XML" 
                          type="rotate" values="0 50 50; 40 50 50; 80 50 50; 120 50 50; 
                                                160 50 50; 200 50 50; 240 50 50; 280 50 50; 320 50 50; 360 50 50"   
                          dur="3s" 
                          repeatCount="indefinite" 
                          additive="replace" 
                          calcMode="discrete" fill="freeze"/> 
      </ellipse>  
    </svg> 
  </div> 
</div>

Такой вариант с маской:

html { 
  -webkit-font-smoothing: antialiased; 
  -moz-osx-font-smoothing: grayscale; 
  text-rendering: optimizelegibility; 
} 
 
html, 
body { 
  height: 100%; 
} 
 
body { 
  font-family: 'Open Sans', sans-serif; 
} 
 
.text { 
  position: fixed; 
  top: 0; 
  left: 0; 
  width: 100%; 
  height: 250px; 
  z-index: 10; 
} 
 
svg { 
  width: 100%; 
  height: inherit; 
} 
 
svg text { 
  text-anchor: middle; 
} 
 
svg #alpha { 
  fill: #666666; 
} 
 
svg #title { 
  letter-spacing: -2px; 
  font-size: 6em; 
  font-weight: 800; 
} 
 
svg #base { 
  fill: black; 
  -webkit-mask: url(#mask); 
          mask: url(#mask); 
} 
 
section.intro { 
  background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/953/mision.jpg) no-repeat top center; 
  background-size: cover; 
  position: relative; 
  width: 100%; 
  min-height: 100%; 
}
<div class="text"> 
  <svg> 
   <defs> 
     <mask id="mask" x="0" y="0" width="100%" height="100%" > 
       <!-- alpha rectangle --> 
       <!-- rectángulo alfa --> 
       <rect id="alpha" x="0" y="0" width="100%" height="100%"/> 
       <!-- All text that you want --> 
       <!-- Coloca todo el texto que necesites -->        
        <svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" xmlns="http://www.w3.org/2000/svg"> 
 
          <defs> 
            <clipPath id="clip"> 
              <path  d="M 50 50 L 35 0 L 65 0 z" /> 
            </clipPath> 
 
            <ellipse id= "MyEllipse" clip-path="url(#clip)" 
                     cx="50" cy="50" rx="40" ry="40" 
                     style="fill:none; stroke:#999" stroke-width="20" /> 
          </defs> 
 
          <use xlink:href="#MyEllipse" /> 
          <use xlink:href="#MyEllipse" transform="rotate(40 50 50)" /> 
          <use xlink:href="#MyEllipse" transform="rotate(80 50 50)" /> 
          <use xlink:href="#MyEllipse" transform="rotate(120 50 50)"/> 
          <use xlink:href="#MyEllipse" transform="rotate(160 50 50)"/> 
          <use xlink:href="#MyEllipse" transform="rotate(200 50 50)"/> 
          <use xlink:href="#MyEllipse" transform="rotate(240 50 50)"/> 
          <use xlink:href="#MyEllipse" transform="rotate(280 50 50)"/> 
          <use xlink:href="#MyEllipse" transform="rotate(320 50 50)"/> 
 
 
          <ellipse clip-path="url(#clip)" 
                   cx="50" cy="50" rx="40" ry="40" 
                   style="fill:none; stroke:black" stroke-width="20"  > 
 
            <animateTransform attributeName="transform" attributeType="XML" 
                              type="rotate" values="0 50 50; 40 50 50; 80 50 50; 120 50 50; 
                                                    160 50 50; 200 50 50; 240 50 50; 280 50 50; 320 50 50; 360 50 50"   
                              dur="3s" 
                              repeatCount="indefinite" 
                              additive="replace" 
                              calcMode="discrete" fill="freeze"/> 
          </ellipse>  
        </svg> 
     </mask> 
    </defs> 
    <!-- Apply color here! --> 
    <!-- Color aquí --> 
    <rect id="base" x="0" y="0" width="100%" height="100%"/> 
  </svg> 
</div> 
 
<section class="intro"></section>

На codepen.

Но проблема что svg внутри svg (думаю это совсем не валидно) и анимация не совсем такая, когда активная секция появляется предыдущая должна быть на половину видимой.

Вопрос: как можно реализовать такой лоадер (как на картинке), можно ли правильно применить к существующему svg маску?

Answer 1

Загрузчик сделал в два раза больше, чем было в вопросе. Иначе смысла нет от прозрачности,- ничего не было видно. В случае необходимости можно поменять на max-width: 200px; Позиционирование ещё нужно доработать.

Вся соль анимации - использование stroke-dasharray совместно с stroke-dashoffset. Один круг- шаблон. Второй круг- бегунок по шаблону.

.box {  
 
width: 100%; 
  height: 100%; 
  background: url(https://i.stack.imgur.com/hopXQ.jpg) center no-repeat; 
  -webkit-background-size: cover; 
  background-size: cover; 
  display: flex; 
  align-items: center; 
  justify-content: center; 
} 
 
.loader { 
  
 max-width: 400px; 
  width: 100%; 
  
}
<div class="box"> 
<div class="loader"> 
<svg width="100%" height="100%" viewBox="50 50 400 400"  > 
<circle cx="250" cy="250" r="100" style="stroke:black; fill:none; stroke-opacity:0.3; stroke-width:50; stroke-dasharray:70 8.5;" />  
 
<circle transform="rotate(-90 250 250)" cx="250" cy="250" r="100" style="stroke:dodgerblue; fill:none; stroke-opacity:0.4; stroke-width:50; 
 stroke-dasharray:70 558; stroke-dashoffset: 558" > 
 <animate attributeName="stroke-dashoffset" values="0;-78.5;-157;-235.5;-314;-392.5;-471;-549.5" dur="4s" repeatCount="indefinite" calcMode="discrete" fill="freeze" /> 
  </circle> 
  
			    
   </svg>   
 </div> 
</div>

READ ALSO
Передача данных из формы в mysql

Передача данных из формы в mysql

Не могу передать данные из html формы в mysqlПодключение - работает

227
Разница в объявлении JS файла

Разница в объявлении JS файла

Доброго времени суток ! Почему если объявить JS файл в начале кода html, некоторые функции не работают, а если в конце кода, то работают ? Никогда...

195
Смена картинки при клике

Смена картинки при клике

Как написать на Jquery функцию, которая будет при нажатии на иконку плюс (изображение plusgif) будет менять его на минус (изображение minus

242
SVG shadow не появляется

SVG shadow не появляется

SVG, с которым я работаю, имеет тень, сделанную с помощью фильтра feGaussianBlur

166