SVG clipPath в Bootstrap

223
15 июля 2018, 06:20

Хочу сделать из фотографии одной картины модульную картину из 5 частей с помощью clipPath.
Как бы получается, но в адаптивной верстке все едет: картинка адаптируется, части нет. Как зафиксировать картинку в каждой части при изменении размера окна?

https://jsfiddle.net/aq9Laaew/31565/

.modular{clip-path:url(#modular)} 
.modular{max-height: 80vh; max-width: 100%; display: block; margin: 15px auto;}
<img class="modular" src="//i.stack.imgur.com/GsPE7.jpg" alt="Модульная картина"/> 
 
<svg width="0" height="0"> 
  <defs> 
    <clipPath id="modular"> 
      <rect x="0" y="0" width="190" height="500" /> 
      <rect x="210" y="0" width="180" height="500" /> 
      <rect x="410" y="0" width="180" height="500" /> 
      <rect x="610" y="0" width="180" height="500" /> 
      <rect x="810" y="0" width="190" height="500" /> 
    </clipPath> 
  </defs> 
</svg>

Answer 1

Чтобы приложение было адаптивно и не разрушались пропорции между фрагментами изображения необходимо сделать следующее:

  • Изображение добавить внутрь svg с помощью команды <image> и задать размеры его в процентах width="100%" height="100"
  • Окна вырезать комбинированной маской. При присвоении одним частям маски fill="white" она будет прозрачна и в вырезанных окошках будут видны фрагменты изображения. Закраска fill="black" делает участок маски непрозрачным - это белые перемычки между окнами.
  • Обернуть svg <div class="container"> в родительский контейнер. Изменяя проценты ширины и высоты контейнера можно регулировать начальные размеры блока.

.container { 
width:100%; 
height:100%; 
}
<div class="container"> 
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"  
    xmlns:xlink="http://www.w3.org/1999/xlink" 
       width="100%" height="100%" viewBox="0 0 1000 500" preserveAspectRatio="xMinYMin meet" >  
 <defs> 
    <mask id="modular"> 
      <rect width="100%" height="100%"	 fill="black" />  
	 <g fill="white"> 
      <rect x="0" y="0" width="190" height="500" /> 
      <rect x="210" y="0" width="180" height="500" /> 
      <rect x="410" y="0" width="180" height="500" /> 
      <rect x="610" y="0" width="180" height="500" /> 
      <rect x="810" y="0" width="190" height="500" />   
	  </g> 
    </mask> 
  </defs>	    
 
<image xlink:href="https://i.stack.imgur.com/i1ZDz.jpg" width="100%" height="100%" mask="url(#modular)" /> 
</svg>	  
</div>

Приложение полностью адаптивно и работает во всех браузерах

Answer 2

Вариант с анимацией при наведении курсора на картинку

  • При наведении курсора на картинку фрагменты изображения сливаются в целое изображение.

Это обеспечивает команда анимации добавленная в маску:

<animate attributeName="x" values="210;189" dur="1s" begin="img1.mouseover" restart="whenNotActive" fill="freeze" />

Реализация смещения фрагмента изображения (секции маски) осуществляется изменением координаты левого верхнего угла прямоугольника - X values="210;189"

  • При уходе курсора с картинки, изображение возвращается к исходному состоянию :

    <animate attributeName="x" values="189;210" dur="1s" begin="img1.mouseout" restart="whenNotActive" fill="freeze" />

.container { 
width:100%; 
height:100%; 
}
<div class="container"> 
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"  
    xmlns:xlink="http://www.w3.org/1999/xlink" 
       width="100%" height="100%" viewBox="0 0 1000 500" preserveAspectRatio="xMinYMin meet"  >  
 <defs> 
    <mask id="modular"> 
      <rect width="100%" height="100%"	 fill="black" />  
	 <g fill="white"> 
      <rect x="0" y="0" width="190" height="500" /> 
      <rect x="210" y="0" width="180" height="500" > 
	   <animate attributeName="x" values="210;189" dur="1s" begin="img1.mouseover" restart="whenNotActive"  fill="freeze" /> 
	   <animate attributeName="x" values="189;210" dur="1s" begin="img1.mouseout" restart="whenNotActive" fill="freeze" /> 
	  </rect> 
      <rect x="410" y="0" width="180" height="500" > 
	  <animate attributeName="x" values="410;360" dur="1s" begin="img1.mouseover" restart="whenNotActive" fill="freeze" /> 
	  <animate attributeName="x" values="360;410" dur="1s" begin="img1.mouseout" restart="whenNotActive" fill="freeze" /> 
	   </rect> 
      <rect x="610" y="0" width="180" height="500" > 
	  <animate attributeName="x" values="610;535" dur="1s" begin="img1.mouseover" restart="whenNotActive"  fill="freeze" />  
	   <animate attributeName="x" values="535;610" dur="1s" begin="img1.mouseout" restart="whenNotActive" fill="freeze" /> 
	   </rect> 
      <rect x="810" y="0" width="190" height="500" > 
<animate attributeName="x" values="810;710" dur="1s" begin="img1.mouseover" restart="whenNotActive" fill="freeze" /> 
 <animate attributeName="x" values="710;810" dur="1s" begin="img1.mouseout" restart="whenNotActive" fill="freeze" /> 
	   </rect>	   
	  </g> 
    </mask> 
  </defs>	    
 
<image id="img1" xlink:href="https://i.stack.imgur.com/i1ZDz.jpg" width="100%" height="100%" mask="url(#modular)" /> 
</svg>	  
</div>

Вариант анимации с кликом

.container { 
width:100%; 
height:100%; 
}
<div class="container"> 
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"  
    xmlns:xlink="http://www.w3.org/1999/xlink" 
       width="100%" height="100%" viewBox="0 0 1000 500" preserveAspectRatio="xMinYMin meet"  >  
 <defs> 
    <mask id="modular"> 
      <rect width="100%" height="100%"	 fill="black" />  
	 <g fill="white"> 
      <rect x="0" y="0" width="190" height="500" /> 
      <rect x="210" y="0" width="180" height="500" > 
	   <animate attributeName="x" values="210;189" dur="1s" begin="img1.click"  fill="freeze" /> 
	   <animate attributeName="x" values="189;210" dur="1s" begin="img1.mouseout"  restart="whenNotActive" fill="freeze" /> 
	  </rect> 
      <rect x="410" y="0" width="180" height="500" > 
	  <animate attributeName="x" values="410;360" dur="1s" begin="img1.click"  fill="freeze" /> 
	  <animate attributeName="x" values="360;410" dur="1s" begin="img1.mouseout" restart="whenNotActive" fill="freeze" /> 
	   </rect> 
      <rect x="610" y="0" width="180" height="500" > 
	  <animate attributeName="x" values="610;535" dur="1s" begin="img1.click"  fill="freeze" />  
	   <animate attributeName="x" values="535;610" dur="1s" begin="img1.mouseout" restart="whenNotActive" fill="freeze" /> 
	   </rect> 
      <rect x="810" y="0" width="190" height="500" > 
<animate attributeName="x" values="810;710" dur="1s" begin="img1.click" fill="freeze" /> 
 <animate attributeName="x" values="710;810" dur="1s" begin="img1.mouseout" restart="whenNotActive" fill="freeze" /> 
	   </rect>	   
	  </g> 
    </mask> 
  </defs>	    
 
<image id="img1" xlink:href="https://i.stack.imgur.com/i1ZDz.jpg" width="100%" height="100%" mask="url(#modular)" /> 
</svg>	  
</div>

READ ALSO
Расположить блоки шириной 50% в строку

Расположить блоки шириной 50% в строку

Почему когда задаю блокамblock ширину 50% , то они располагаются в колонку

180
Рациональное использование вложенных div-блоков

Рациональное использование вложенных div-блоков

Существуют ли какие-нибудь практики по верстке сайтов, определяющие необходимый уровень вложенности div-блоковК примеру, мне необходимо сверстать...

185
Как сохранить перенос строки из Textarea?

Как сохранить перенос строки из Textarea?

Есть форма блога для поста: Название статьи и тело поста

211
Отправить post запрос html

Отправить post запрос html

Отправить запрос методом POST на сторонний сайт, как это сделать правильно, в форме будет 2-3 поля для заполнения, нужно написать скрипт отправления...

237