How to draw svg on image? - html

I have a image, and i have cordinates (x1,y1),(x2,y2),(x3,y3),(x4,y4) to draw a svg/rectagle on image, how to draw?
I have tried using svg tag in img tag, but it does not work, the main thing is how to set width and height of svg(rect svg) using those cordinates.
<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 1055 717" preserveAspectRatio="xMinYMin meet" >
<rect x="540" y="134" width="150" height="100" fill="none" stroke="red" stroke-width="2" />
</svg>

If I understand correctly OP then so and look at the comments in the code.
<style>
.container {
width:100vw;
height:100vh;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 1055 717" preserveAspectRatio="xMinYMin meet" >
<!-- Add image -->
<image xlink:href="https://i.stack.imgur.com/ORJ3b.jpg" width="100%" height="100%" />
<!-- Add a red rectangle over the image. -->
<rect x="540" y="134" width="150" height="100" fill="none" stroke="red" stroke-width="2" />
<!-- Add text -->
<text x="550" y="200" font-size="48px" font-family="sans-serif" font-weight="700" fill="white" >TEST </text>
</svg>
</div>
UPDATE
If a square over the image is needed to focus on one or more fragments of the image, then
you can use it repeatedly but add individual tooltips <tooltip>
A tooltip pops up when you hover and hold the cursor on the red square
.container {
width:100vw;
height:100vh;
}
.rect {
fill:transparent;
stroke:red;
stroke-width:2;
}
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 1024 768" preserveAspectRatio="xMinYMin meet" >
<!-- Add image -->
<image xlink:href="https://i.stack.imgur.com/uOg10.jpg" width="100%" height="100%" />
<!-- Add a red rectangles over the image. -->
<g>
<!-- Tooltip pops up on hover -->
<title> Young lioness </title>
<rect class="rect" x="160" y="220" width="170" height="170" rx="15" />
</g>
<g>
<title> Young lion </title>
<rect class="rect" x="475" y="200" width="200" height="220" rx="15"/>
</g>
</svg>
</div>

You can consider using calc() and some CSS variables to find the width/height:
:root {
--x1:200;
--x2:100;
--x3:150;
--x4:200;
}
rect {
x:calc(var(--x1)*1px);
y:calc(var(--x2)*1px);
width:calc((var(--x1) + var(--x2))*1px);
height:calc((var(--x3) + var(--x4))*1px);
}
<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 1055 717" preserveAspectRatio="xMinYMin meet" >
<rect fill="none" stroke="red" stroke-width="2" />
</svg>

Related

In a svg shape divider fill with a background image

https://jsfiddle.net/4n7j5a1t/
I'm using a svg shape divider but how I can change the background color to a background image in the fill CSS property ?
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 120" preserveAspectRatio="none">
<path d="M600,112.77C268.63,112.77,0,65.52,0,7.23V120H1200V7.23C1200,65.52,931.37,112.77,600,112.77Z" class="shape-fill"></path>
</svg>
This is what I have tried so far but it does not keep the svg shape in place (wave):
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 120" preserveAspectRatio="none">
<defs>
<pattern id="imgpattern" x="0" y="0" width="1" height="1">
<image width="120" height="250"
xlink:href="https://example.com/slider-bg.png"/>
</pattern>
</defs>
<path d="M600,112.77C268.63,112.77,0,65.52,0,7.23V120H1200V7.23C1200,65.52,931.37,112.77,600,112.77Z" class="shape-fill" fill="url(#imgpattern)"></path>
</svg>
Thanks.
EDIT
You have to define the image and then add it as a fill.
You can read more about this here
I'm not sure if this is what you wanted but I hope it helps. If not try to explain a little more and I might be able to help you.
Cheers!
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 120" preserveAspectRatio="none">
<defs>
<pattern id="img1" patternUnits="userSpaceOnUse" width="600" height="450">
<image xlink:href="https://image.api.playstation.com/vulcan/img/rnd/202011/0714/vuF88yWPSnDfmFJVTyNJpVwW.png" x="0" y="0"
width="600" height="450" /><!-- Image from http://silviahartmann.com/background-tile/6-grass-meadow-tile.php-->
</pattern>
</defs>
<path fill="url(#img1")" d="M600,112.77C268.63,112.77,0,65.52,0,7.23V120H1200V7.23C1200,65.52,931.37,112.77,600,112.77Z" class="shape-fill"></path>
</svg>

How can I create responsive nested SVG line relative to other elements?

I have a nested SVG with 3 elements. 2 triangles that are positioned at the right-left sides and one line in the middle. I would like to obtain a responsive line (line should only have the width available between the triangles), both when resizing horizontally and vertically. I have tried setting the width in percentage but in only works when resizing horizontally. When I am resizing vertically it doesn't work because the width of the triangles changes. Here is a codepen link: https://codepen.io/roppazvan/pen/dyyPKKL?editors=1100
<svg
class='input-source'
stroke='black'
stroke-width='0'
fill="black">
<rect x="20" y="20%" width="100%" height="60%"
stroke='black'
stroke-width='0'
>
</rect>
<!-- The right head -->
<svg class='head input-source' id='right'
height="100%"
width='100%'
viewBox="0 0 20 40"
preserveAspectRatio="xMaxYMid"
>
<rect width="100%" height="100%"/>
</svg>
<!-- The left head -->
<svg class='head input-source' id='left'
height="100%"
width='100%'
viewBox="0 0 15 30"
preserveAspectRatio="xMinYMid"
>
<rect width="100%" height="100%"/>
</svg>
</svg>
</svg>
<svg width="110px" height="40px" version="1.0" state='normal'>
<svg
class='input-source'
stroke='black'
stroke-width='0'
fill="black">
<rect x="20" y="20%" width="100%" height="60%"
stroke='black'
stroke-width='0'
>
</rect>
<!-- The right head -->
<svg class='head input-source' id='right'
height="100%"
width='100%'
viewBox="0 0 20 40"
preserveAspectRatio="xMaxYMid"
>
<rect width="100%" height="100%"/>
</svg>
<!-- The left head -->
<svg class='head input-source' id='left'
height="100%"
width='100%'
viewBox="0 0 15 30"
preserveAspectRatio="xMinYMid"
>
<rect width="100%" height="100%"/>
</svg>
</svg>
</svg>
The simplest and easiest approach to implement and understand, is probably to just use flex-box.
#svg-container {
margin-top: 100px;
width: 100%;
border: 1px solid #bada55;
display: flex;
flex-direction: row;
}
svg {
height: 10vh;
}
/* stretch the middle box */
svg:nth-child(2) {
flex: 1;
}
<div id="svg-container">
<!-- left head -->
<svg viewBox="0 0 14 14" preserveAspectRatio="xMinYMid" opacity="0.5">
<polygon points="0,7 14,0 14,14 " />
</svg>
<!-- line -->
<svg viewBox="0 0 14 14" preserveAspectRatio="none">
<rect y="30%" width="100%" height="40%" />
</svg>
<!-- right head -->
<svg viewBox="0 0 14 14" preserveAspectRatio="xMaxYMid" opacity="0.5">
<polygon points="14,7 0,0 0,14 "/>
</svg>
</div>

SVG not changing size

I have created an svg heart with a background image inside.
I'm trying to make the svg larger, but changing the width and height on both the pattern and the svg itself does not work.
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" height="315" width="345" >
<!-- START SVG RULES -->
<defs>
<!-- DEFINE IMAGE INSIDE PATTERN -->
<pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
<image xlink:href="https://images.pexels.com/photos/325185/pexels-photo-325185.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260" x="0" y="0" width="100" height="100" /></pattern>
<!-- SVG SHAPE CREATION -->
<g id="heart">
<path
d="M0 200 v-200 h200
a100,100 90 0,1 0,200
a100,100 90 0,1 -200,0
z" />
</g>
</defs>
<use xlink:href="#heart" class="outline" fill="url(#img1)" />
</svg>
For a resizable SVG use viewBox="0 0 315 345"instead height="315" width="345"
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" viewBox="0 0 315 345" >
<!-- START SVG RULES -->
<defs>
<!-- DEFINE IMAGE INSIDE PATTERN -->
<pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
<image xlink:href="https://images.pexels.com/photos/325185/pexels-photo-325185.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260" x="0" y="0" width="100" height="100" /></pattern>
<!-- SVG SHAPE CREATION -->
<g id="heart">
<path
d="M0 200 v-200 h200
a100,100 90 0,1 0,200
a100,100 90 0,1 -200,0
z" />
</g>
</defs>
<use xlink:href="#heart" class="outline" fill="url(#img1)" />
</svg>
Click the resize button to see if this is what you need.
https://jsfiddle.net/gbxquc05/29/
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%" preserveAspectRatio="none" viewBox="0 0 400 400">
Drawing paths in SVG is unfortunately limitted to absolute units. This is a workaround using viewBox to create coordinate system that transforms to percentage.

SVG <use> element not visible in Chrome

I have an SVG element that is embedded into my HTML page that works perfectly on Firefox but does not work on Chrome.
I'm using a mask to cover a video background while the SVG element has a transparent fill (using CSS class on use element) to show video background through it.
I believe I identified the problem to be with the <use> tag because when I inspect it in Chrome, the use element has some dimensions but is not matching the SVG viewbox's size: <svg viewBox="0 0 1000 300" class="svg-inverted-mask"> that it lives in. In Firefox, the size of use element matches the viewbox and renders correctly.
Code:
<div class="wrap heightwrap wow fadeInDown" data-wow-delay="0.4s">
<svg viewBox="0 0 1000 300" class="svg-defs">
<!-- Symbol with Logo -->
<symbol id="s-text2">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="30%" y="-25%" width="700" height="800" viewBox="0 0 1000 800">
<defs>
<rect id="a" x="50%" y="50%" width="612" height="792"/>
</defs>
<clipPath id="b">
<use href="#a" overflow="visible"/>
</clipPath>
<path clip-path="url(#b)" d="M468.896,118.65l-80.667,254.289H145.563l-24.334-62.667h188 c0,0,26.167,0.167,33.311-18.676l15.356-50.99c20.333-62.333,22.67-67.217-34-67.667c-15.121-0.12-30.689,0.122-39.254,0.072 c-17.878-0.105-22.246,0.139-20.368-10.094l10.712-34.979c0,0,1.285-9.287,17.66-9.287"/>
<path clip-path="url(#b)" d="M275.563,267.9c28.667,0,28.013-1.13,35.833-28.5c8-28,9.457-29.082-12-29.5 c-10.548-0.205-26.166,0-26.166,0c-51.959,0-64.834,1.5-58.222-24.03c2.682-10.354,6.587-25.693,12.221-45.637 c4.024-14.247,8.103-29.353,11.369-38.006C250.481,70.74,271.842,75.708,343.23,75.9c92.334,0.249,139.333,0,139.333,0l20.333-62 h-314l-41.553,149.031c0,0-2.537,10.65-6.408-0.212L87.896,13.9h-69l89.667,254H275.563"/>
</svg>
</symbol>
<!-- Mask with text -->
<mask id="m-text2" maskunits="userSpaceOnUse" maskcontentunits="userSpaceOnUse">
<rect width="100%" height="100%" class="mask__shape">
</rect>
<use href="#s-text2" class="mask__text"></use>
</mask>
</svg>
<div class="box-with-text">
<!-- Container for video -->
<div class="text-fill">
<video class="video" src="/css/fractal3.mp4" autoplay loop></video>
</div>
<!-- Visible SVG -->
<svg viewBox="0 0 1000 300" class="svg-inverted-mask">
<rect width="100%" height="100%" mask="url(#m-text2)" class="shape--fill" />
<use href="#s-text2" class="text--transparent"></use>
</svg>
</div>
</div>
Getting rid of the unnecessary clipPaths seems to help.
They look like the sort of clips that Illustrator adds to reproduce its way of rendering strokes. But since your symbol doesn't have an stroking, they are safe to remove.
<div class="wrap heightwrap wow fadeInDown" data-wow-delay="0.4s">
<svg viewBox="0 0 1000 300" class="svg-defs">
<!-- Symbol with Logo -->
<symbol id="s-text2">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="30%" y="-25%" width="700" height="800" viewBox="0 0 1000 800">
<path d="M468.896,118.65l-80.667,254.289H145.563l-24.334-62.667h188 c0,0,26.167,0.167,33.311-18.676l15.356-50.99c20.333-62.333,22.67-67.217-34-67.667c-15.121-0.12-30.689,0.122-39.254,0.072 c-17.878-0.105-22.246,0.139-20.368-10.094l10.712-34.979c0,0,1.285-9.287,17.66-9.287"/>
<path d="M275.563,267.9c28.667,0,28.013-1.13,35.833-28.5c8-28,9.457-29.082-12-29.5 c-10.548-0.205-26.166,0-26.166,0c-51.959,0-64.834,1.5-58.222-24.03c2.682-10.354,6.587-25.693,12.221-45.637 c4.024-14.247,8.103-29.353,11.369-38.006C250.481,70.74,271.842,75.708,343.23,75.9c92.334,0.249,139.333,0,139.333,0l20.333-62 h-314l-41.553,149.031c0,0-2.537,10.65-6.408-0.212L87.896,13.9h-69l89.667,254H275.563"/>
</svg>
</symbol>
<!-- Mask with text -->
<mask id="m-text2" maskUnits="userSpaceOnUse" maskContentUnits="userSpaceOnUse">
<rect width="100%" height="100%" class="mask__shape">
</rect>
<use href="#s-text2" class="mask__text"></use>
</mask>
</svg>
<div class="box-with-text">
<!-- Container for video -->
<div class="text-fill">
<video class="video" src="/css/fractal3.mp4" autoplay loop></video>
</div>
<!-- Visible SVG -->
<svg viewBox="0 0 1000 300" class="svg-inverted-mask">
<rect width="100%" height="100%" mask="url(#m-text2)" class="shape--fill" />
<use href="#s-text2" class="text--transparent"></use>
</svg>
</div>
</div>

ClipPath on SVG within 'use' link in IE

I've got a four slice scaling SVG image which works great in all browsers, except when I try and include it via a use tag. Then it works fine in Chrome, Firefox and Safari but not in <=IE11.
The problem seems to be with the clip-path, is there something I'm missing to get this working in IE or is it just not supported? If not, is there a way I can achieve the same effect in an IE friendly way?
Thanks!
#box,
#use {
width: 200px;
height: 50px;
}
#use {
fill: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div style="display: none;">
<svg id="box" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="topleft" viewBox="0 0 500 500">
<path d="M3.1,22.6c0,0.2,0,0.4,0,477.4H5C5,22.9,5,22.5,5,22.6c0-4.3,0-7.9,0.1-8.8C5.1,11.5,5,8.2,6.2,6.1
c0.4-0.6,40.8-0.8,80.2-0.9c0.5,0,413.6,0,413.6,0V3.4c0,0-413.3,0-413.6,0C47.5,3.4,8.2,3.6,6.7,4C6.5,3,6.6,2,6.5,1
C6.4,0.3,5.7-0.1,5,0c-0.7,0.1-1,0.8-1,1.4C4.2,2.2,4.2,3,4.2,3.7C3.4,3.9,2.7,4.2,1.9,4.4c-1.5,0.3-1,2.7,0.5,2.4
C2.9,6.6,3.5,6.4,4,6.3C3.5,7.8,3.5,9.7,3.4,11C3.3,12,3.1,19.8,3.1,22.6z"/>
</symbol>
<symbol id="topright" viewBox="0 0 500 500">
<use xlink:href="#topleft"/>
</symbol>
<symbol id="bottomleft" viewBox="0 0 500 500">
<path d="M5.3,494.5C5,493.1,5,484.3,5,477.4L5,0H3.1l0,477.4c-0.1,7.2,0,15.3,0.4,17.2c-0.8,0.1-1.7,0.1-2.5,0.3
c-0.6,0.2-1.1,0.7-1,1.4c0.1,0.6,0.8,1.1,1.4,1c0.6-0.2,1.3-0.2,1.9-0.2c0,0.2-0.2,1.5-0.3,1.7C3,499.4,3.7,500,4.3,500
c0.7,0,1.2-0.5,1.3-1.1c0-0.1,0.3-2.3,0.3-2.3c1.8,0.4,4.2,0.3,5.3,0.4c0.9,0.1,37.6,0.2,75.2,0.3c0.3,0,413.6,0,413.6,0v-2.1
c0,0-413.3,0-413.6,0C46.8,495.2,6,495,5.3,494.5z"/>
</symbol>
<symbol id="bottomright" viewBox="0 0 500 500">
<use xlink:href="#bottomleft"/>
</symbol>
<clipPath id="crop">
<rect class="mask" width="100%" height="100%" x="0"/>
</clipPath>
</defs>
<svg width="50%" height="50%">
<use xlink:href="#topleft" width="500" height="500" class="box_border__tl"/>
</svg>
<!-- top right: -->
<g transform="scale(-1, 1)">
<svg width="50%" height="50%" x="-100%" y="0">
<use xlink:href="#topright" width="500" height="500" class="box_border__tr"/>
</svg>
</g>
<!-- bottom left: -->
<g transform="scale(1, -1)">
<svg width="50%" height="50%" x="0" y="-100%" clip-path="url(#crop)">
<use xlink:href="#bottomleft" width="500" height="500" y="-500" transform="scale(1, -1)" class="box_border__bl"/>
</svg>
</g>
<!-- bottom right: clip-path="url(#crop)" -->
<g transform="scale(-1, -1)">
<svg width="50%" height="50%" x="-100%" y="-100%" clip-path="url(#crop)">
<use xlink:href="#bottomright" width="500" height="500" y="-500" transform="scale(1, -1)" class="box_border__br"/>
</svg>
</g>
</svg>
</div>
<svg id="use" class="box" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="#box"/>
</svg>
The issue is happening because I'm hiding the main SVG in a container with display: none; The same also happens if I use visibility: hidden; or position: absolute; on the parent container.
It only works if the main SVG is rendered on the page. It also works if you start with the main item visible, then hide it using javascript.
It's a really obscure issue, and odd how the non-clipped elements render even when the SVG is hidden. Oh, also the main SVG must be placed above the use links otherwise Safari doesn't render it.