Как вставить изображение в SVG?
Вот макет:
Вот svg код, который не работает.
<svg width="727" height="620" viewBox="0 0 727 620" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M533.771 0H0V620H727V247.5L533.771 0Z" fill="url(#pattern0)"/>
<path d="M533.771 0H0V620H727V247.5L533.771 0Z" fill="url(#paint0_linear)"/>
<defs>
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0" transform="translate(0 -0.134532) scale(0.000927721 0.00108783)"/>
</pattern>
<linearGradient id="paint0_linear" x1="711" y1="620" x2="363.5" y2="620" gradientUnits="userSpaceOnUse">
<stop stop-color="#0B1424"/>
<stop offset="1" stop-opacity="0"/>
</linearGradient>
<image id="image0" width="1080" height="1080" src="https://cdn2.unrealengine.com/kena-keyart-1200x1600-1200x1600-3cc88c815329.png?h=854&resize=1&w=640" />
</defs>
</svg>
То есть, нужна возможность вставлять любую картинку. И правый верхний угол должен быть срезан. Подскажите, где моя ошибка.
Ответы (5 шт):
Можно с помощью canvas:
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const image = new Image();
image.src = "https://cdn2.unrealengine.com/kena-keyart-1200x1600-1200x1600-3cc88c815329.png?h=854&resize=1&w=640";
image.onload = () => {
const w = canvas.width = image.width;
const h = canvas.height = image.height;
const path = new Path2D(`M ${w*2/3} 0 L ${w} ${w/3} V ${h} H 0 V 0 z`);
ctx.clip(path);
ctx.drawImage(image,0,0);
}
<canvas></canvas>
В ссылке на картинку есть знаки не разрешенные в таге svg - &, <, >
<image id="image0" width="1080" height="1080" src="https://cdn2.unrealengine.com/kena-keyart-1200x1600-1200x1600-3cc88c815329.png?h=854&resize=1&w=640" />
Если заменить в ссылке & на %26 HTML URL Encoding Reference то всё работает
https://cdn2.unrealengine.com/kena-keyart-1200x1600-1200x1600-3cc88c815329.png?h=854%26resize=1%26w=640
Финальный svg выглядит так:
<svg width="727" height="620" viewBox="0 0 727 620" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M533.771 0H0V620H727V247.5L533.771 0Z" fill="url(#pattern0)"/>
<path d="M533.771 0H0V620H727V247.5L533.771 0Z" fill="url(#paint0_linear)"/>
<defs>
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="1" height="1">
<use href="#image0" transform="translate(0 -0.134532) scale(0.000927721 0.00108783)"/>
</pattern>
<linearGradient id="paint0_linear" x1="711" y1="620" x2="363.5" y2="620" gradientUnits="userSpaceOnUse">
<stop stop-color="#0B1424"/>
<stop offset="1" stop-opacity="0"/>
</linearGradient>
<image id="image0" width="1080" height="1080" href="https://cdn2.unrealengine.com/kena-keyart-1200x1600-1200x1600-3cc88c815329.png?h=854%26resize=1%26w=640" />
</defs>
</svg>
*Редакторы кода такие как IntelliJ или замечательный бесплатный редактор VSCode сразу показывают где ошибка
Подскажите где моя ошибка.
При добавлении изображения с помощью тега <image> вместо src= нужно использовать href=
<svg width="727" height="620" viewBox="0 0 727 620" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M533.771 0H0V620H727V247.5L533.771 0Z" fill="url(#pattern0)"/>
<path d="M533.771 0H0V620H727V247.5L533.771 0Z" fill="url(#paint0_linear)"/>
<defs>
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0" transform="translate(0 -0.134532) scale(0.000927721 0.00108783)"/>
</pattern>
<linearGradient id="paint0_linear" x1="711" y1="620" x2="363.5" y2="620" gradientUnits="userSpaceOnUse">
<stop stop-color="#0B1424"/>
<stop offset="1" stop-opacity="0"/>
</linearGradient>
<image id="image0" width="1080" height="1080" href="https://cdn2.unrealengine.com/kena-keyart-1200x1600-1200x1600-3cc88c815329.png?h=854&resize=1&w=640" />
</defs>
</svg>
- Добавление изображения с помощью
clipPath
Для адаптивностиwidth="75%" height="75%"
<svg width="75%" height="75%" viewBox="0 0 727 620" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<clipPath id="cp">
<path transform="translate(-100)" d="M533.771 0H0V620H727V247.5L533.771 0Z" />
</clipPath>
</defs>
<image clip-path="url(#cp)" id="image0" width="100%" height="100%" href="https://i.stack.imgur.com/6lNYF.png" />
</svg>
- Добавление изображения с помощью mask
<svg width="75%" viewBox="0 0 727 620" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<mask id="cp">
<path fill="white" transform="translate(-100)" d="M533.771 0H0V620H727V247.5L533.771 0Z" />
</mask>
</defs>
<image mask="url(#cp)" id="image0" width="100%" height="100%" href="https://i.stack.imgur.com/6lNYF.png" />
</svg>
Чтобы приложение выглядело один к одному, как на заданном макете, было адаптивным и вёрстка не разъезжалась на разных разрешениях у разных гаджетов и не нужно было заниматься ручной подгонкой размеров с помощью scale() translate() и заполнять пустоты градиентами, предлагаю воспользоваться несложной техникой с помощью векторного редактора, это будет буквально несколько кликов мышкой
- Загружаете шаблон в векторный редактор и с помощью инструмента - "Рисовать кривые Безье" shift+F6 наносите по контуру изображения узловые точки:
- Сохраняете файл в формате *.svg
- Оптимизируете его с помощью SVGOMG
- Далее, полученный path используете для обрезки изображения с помощью clipPath, mask
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" id="svg4" width="75%" height="75%" viewBox="0 0 727 620">
<defs>
<clipPath id="cp">
<path d="m0 0 535 0 191 246 0 372H0Z" />
</clipPath>
</defs>
<image clip-path="url(#cp)" xlink:href="https://i.stack.imgur.com/ZKnFL.png" id="image2" height="100%" width="100%"/>
</svg>
Для такой обрезки можно использовать clip-path в сочетании с calc().
Пример обрезки правого верхнего угла (катеты по 60px):
body{
margin: 0;
background: #cda;
}
img{
clip-path: polygon(0 0, calc(100% - 60px) 0, 100% 60px, 100% 100%, 0 100%);
}
<img src="https://www.placecage.com/c/300/200" alt=""/>


