How to animate SVG rect to fill from bottom to top? - javascript

I'm working on an SVG here I want blue color fill from bottom to top I had tried using transform="rotate(-90)" but the problem is text also rotates. I newbie in an SVG can anyone suggest to me how to achieve this output. Any help will be appreciated!
svg {
width: 200px;
}
rect {
transition: height 0.5s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="slider1" type="range" min="0" max="100" step="25" value="25" oninput="document.querySelector(`#SVG${this.id} rect`).setAttribute('height',this.value+'%')" />
<svg id="SVGslider1" viewBox="0 0 28 6">
<rect width="100%" height="25%" fill="blue" />
<rect width="100%" height="100%" fill="none" stroke="black"/>
<text x="5" y="5" font-size="6" fill="green">text here</text>
</svg>

The shortest answer would be to update your CSS with rect {transform: transform: rotate(180deg); transform-origin: center center;} to rotate it 180ยบ, pinned to the SVG center.
Alternatively, rebuild the SVG with a white rect overlaid on blue and the slider javascript targets the white rectangle.
svg {
width: 200px;
}
rect {
transform: rotate(180deg);
transform-origin: center center;
transition: height 0.5s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="slider1" type="range" min="0" max="100" step="25" value="25" oninput="document.querySelector(`#SVG${this.id} rect`).setAttribute('height',this.value+'%')" />
<svg id="SVGslider1" viewBox="0 0 28 6">
<rect width="100%" height="25%" fill="blue" />
<rect width="100%" height="100%" fill="none" stroke="black"/>
<text x="5" y="5" font-size="6" fill="green">text here</text>
</svg>

Instead of animating the width you can animate the height and to make it fill from bottom to top you can rotate the rect upside around its center:
svg {
width: 200px;
}
rect {
transition: height 0.5s;
transform-origin: center center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="slider1" type="range" min="0" max="100" step="25" value="25" oninput="document.querySelector(`#SVG${this.id} rect`).setAttribute('height',this.value+'%')" />
<svg id="SVGslider1" viewBox="0 0 28 6">
<rect width="100%" height="25%" fill="blue" transform="rotate(180)" />
<rect width="100%" height="100%" fill="none" stroke="black"/>
<text x="5" y="5" font-size="6" fill="green">text here</text>
</svg>

Related

Unable to show text on mouse over of SVG

I am trying to show only text whenever the user hover on svg element(a rectangle in my case) either with CSS or JS.
<svg width="400" height="180">
<rect x="50" y="20" width="150" height="150"
style="fill:blue;stroke:pink;stroke-width:5;fill-opacity:0.1;stroke-opacity:0.9" />
<text class="img__description" x="50" y="100" font-family="Verdana" font-size="35" fill="blue">Hello</text>
</svg>
I would appreciate any help.
You can add css styles to the elements of the svg, e.g. display: none.
Working example:
svg:hover rect {
display: none;
}
svg text {
display: none;
}
svg:hover text {
display: block;
}
<svg width="400" height="180">
<rect x="50" y="20" width="150" height="150"
style="fill:blue;stroke:pink;stroke-width:5;fill-opacity:0.1;stroke-opacity:0.9"
/>
<text class="img__description" x="50" y="100" font-family="Verdana" font-size="35" fill="blue">Hello</text>
</svg>

IE & Firefox rendering incorrectly but not in Chrome, Safari & Chromium browsers

All,
There is a double walled circle and a text. Ideally the text should be rendered within the circle but in IE & Firefox , the circle is coming down and the text on the top. The issue can be seen using the below code.
Any help or advice on how to get it fixed in IE & firefox is much appreciated.
<div class="col-xs-4 col-sm-2">
<div style="margin-top: 20px; position: relative; display: inline-block; max-width: 116px; max-height: 116px;">
<svg width="100%" height="100%" viewBox="0 0 418 418" tabindex="-1">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-31.000000, -31.000000)" stroke="#9B9B9B" stroke-width="2" fill="#FFFFFF">
<g transform="translate(32, 32)">
<path d="M208,416 C322.875228,416 416,322.875228 416,208 C416,93.124772 322.875228,0 208,0 C93.124772,0 -9.09494702e-13,93.124772 -9.09494702e-13,208 C-9.09494702e-13,322.875228 93.124772,416 208,416 Z"></path>
<path d="M208,398.666667 C313.302292,398.666667 398.666667,313.302292 398.666667,208 C398.666667,102.697708 313.302292,17.3333333 208,17.3333333 C102.697708,17.3333333 17.3333333,102.697708 17.3333333,208 C17.3333333,313.302292 102.697708,398.666667 208,398.666667 Z"></path>
</g></g></g>
</svg>
<span style="font-size: 24px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">400</span>
</div>
</div>
The styling you have added to the divs pushes the number outside of the SVG.
I would just avoid the problem in the first place by using an SVG <text> element that you can position inside the svg.
You might have to fiddle with the x and y values a bit.
ps: There's also a <circle> element you could use instead of a <path>.
<svg width="100%" height="100%" viewBox="0 0 418 418" tabindex="-1">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-31.000000, -31.000000)" stroke="#9B9B9B" stroke-width="2" fill="#FFFFFF">
<g transform="translate(32, 32)">
<path d="M208,416 C322.875228,416 416,322.875228 416,208 C416,93.124772 322.875228,0 208,0 C93.124772,0 -9.09494702e-13,93.124772 -9.09494702e-13,208 C-9.09494702e-13,322.875228 93.124772,416 208,416 Z"></path>
<path d="M208,398.666667 C313.302292,398.666667 398.666667,313.302292 398.666667,208 C398.666667,102.697708 313.302292,17.3333333 208,17.3333333 C102.697708,17.3333333 17.3333333,102.697708 17.3333333,208 C17.3333333,313.302292 102.697708,398.666667 208,398.666667 Z"></path>
</g>
</g>
</g>
<text x="47%" y="49%" style="font-size: 32px;">400</text>
</svg>
I don't know what are your constraints, but to render these circles in particular I'd play with border-radius: 50% and display: flex:
.circle {
border: 2px solid #888;
border-radius: 50%; /* make the border a circle */
display: flex; /* align the content vertically and horizontally */
align-items: center; /* same */
justify-content: space-around; /* same */
}
<div class="circle" style="width: 100px; height: 100px;">
<div class="circle" style="width: 90px; height: 90px;">
400
</div>
</div>

Fade color in path tag

In HTML with SVG you can create a rect with fading color:
<svg>
<rect width="100%" height="100%">
<animate attributeName="fill" values="red;blue;red" dur="10s" repeatCount="indefinite" />
</rect>
</svg>
Now in my code I have a path like that:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="247pt" height="543pt" viewBox="0.00 0.00 246.86 543.19">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 539.1859)">
<!-- c->e -->
<g id="a1124" class="edge">
<title>c->e</title>
<path fill="none" stroke="#ff0000" stroke-width="3" d="M208.109,-297.8625C205.1217,-279.2357 200.2512,-248.8658 195.5911,-219.8076" />
<polygon fill="#ff0000" stroke="#ff0000" stroke-width="3" points="198.9943,-218.9251 193.9549,-209.6055 192.0827,-220.0336 198.9943,-218.9251" />
</g>
</g>
</svg>
I am looking for a way to fade the color of the path along the path so that it illustrates some kind of data flow. Is there a way to accomplish that? (via CSS or Javascript).
Try this
#keyframes fade {
0% {
stroke: red;
fill: red;
}
50% {
stroke: blue;
fill: blue;
}
100% {
stroke: red;
fill: red;
}
}
#fade {
animation-name: fade;
animation-duration: 10s;
animation-iteration-count: infinite;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="247pt" height="543pt" viewBox="0.00 0.00 246.86 543.19">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 539.1859)">
<!-- c->e -->
<g id="a1124" class="edge">
<title>c->e</title>
<path id="fade" stroke="#ff0000" stroke-width="3" d="M208.109,-297.8625C205.1217,-279.2357 200.2512,-248.8658 195.5911,-219.8076" />
<polygon id="fade" stroke-width="3" points="198.9943,-218.9251 193.9549,-209.6055 192.0827,-220.0336 198.9943,-218.9251" />
</g>
</g>
</svg>

is it possible to change color of png image in svg element by css or javascript?

codepen-mydemo
.icon {
display: inline-block;
width: 80px;
height: 80px;
overflow: hidden;
}
.icon-del {
background: url("http://i1.piimg.com/567571/220defbd8306acf8.png") no-repeat center;
}
.icon > .icon {
position: relative;
left: -80px;
border-right: 80px solid transparent;
-webkit-filter: drop-shadow(80px 0);
filter: drop-shadow(rgb(204, 51, 255) 80px 0);
}
.imgicon1 {
-webkit-filter: drop-shadow(80px 0);
filter: drop-shadow(rgb(204, 51, 255) 80px 0);
}
<p><strong>origin icon</strong>
</p>
<i class="icon icon-del"></i>
<p><strong>after change icon color</strong>
</p>
<i class="icon"><i class="icon icon-del"></i></i>
<br />
<br />
<p>can i use the same way to change the icon color in svg image below</p>
<svg x=200 y=200 width=500 height=500>
<defs>
<filter id="f1" x="0" y="0" width="100%" height="100%">
<feOffset result="offOut" in="SourceGraphic" dx="20" dy="20" />
<feBlend in="SourceGraphic" in2="offOut" mode="normal" />
</filter>
<filter id="f2" x="0" y="0" width="100%" height="100%">
<feImage result="sourc12eTwo" xlink:href="http://i1.piimg.com/567571/220defbd8306acf8.png" preserveAspectRatio="xMidYMid slice" />
<!-- <feOffset result="offO12ut" dx="0" dy="0" fill="red"/>
<feOffset in="SourceGraphic" dx="60" dy="60" color="red"/> -->
<!-- <feFlood flood-color="red" flood-opacity="1" result="offsetColor"/> -->
<!-- <feFlood flood-color="rgb(20, 0, 0)" result="color"/> -->
<!-- <feOffset result="offOut" in="SourceGraphic" dx="20" dy="20" /> -->
<!-- <feBlend in="SourceGraphic" in2="offOut" mode="normal" /> -->
<!-- <feComposite in="SourceGraphic" in2="sourceTwo" operator="arithmetic" k1="0" k2=".5" k3=".7" k4="0"/> -->
</filter>
</defs>
<image filter="url(#f1)" class="imgicon1" xlink:href="http://i1.piimg.com/567571/220defbd8306acf8.png" />
<!-- <image class="imgicon2" xlink:href="http://i1.piimg.com/567571/220defbd8306acf8.png" class="testicon" x=200 y=0 /> -->
<rect x=300 y=0 width="80" height="80" filter="url(#f2)" />
</svg>
we can change color of png in HTML by changing drop-shadow(css3 filter)'color of the element.
so i wonder if i can change the color of png referenced in svg(image tag) by the same way.
after reading the related svg filter API on MDN,i found there is no way to change color of drop-shadow like above.
is there any good solution to solve this problem?
You can change the color of an image by using an feColorMatrix filter.
.icon {
display: inline-block;
width: 80px;
height: 80px;
overflow: hidden;
}
.icon-del {
background: url("http://i1.piimg.com/567571/220defbd8306acf8.png") no-repeat center;
}
.icon > .icon {
position: relative;
left: -80px;
border-right: 80px solid transparent;
-webkit-filter: drop-shadow(80px 0);
filter: drop-shadow(rgb(204, 51, 255) 80px 0);
}
.imgicon1 {
-webkit-filter: drop-shadow(80px 0);
filter: drop-shadow(rgb(204, 51, 255) 80px 0);
}
.imgicon2 {
-webkit-filter: url(#f2);
filter: url(#f2);
}
<p><strong>origin icon</strong>
</p>
<i class="icon icon-del"></i>
<p><strong>after change icon color</strong>
</p>
<i class="icon"><i class="icon icon-del"></i></i>
<br />
<br />
<p>can i use the same way to change the icon color in svg image below</p>
<svg x=200 y=200 width=500 height=500 color-interpolation-filters="sRGB">
<defs>
<filter id="f1" x="0" y="0" width="100%" height="100%">
<feOffset result="offOut" in="SourceGraphic" dx="20" dy="20" />
<feBlend in="SourceGraphic" in2="offOut" mode="normal" />
</filter>
<filter id="f2" x="0" y="0" width="100%" height="100%">
<feColorMatrix type="matrix" values="0 0 0 0 0.82
0 0 0 0 0.21
0 0 0 0 1
0 0 0 1 0" />
</filter>
</defs>
<image filter="url(#f1)" class="imgicon1" xlink:href="http://i1.piimg.com/567571/220defbd8306acf8.png" x="0" y="0" height="100" width="100"/>
<image class="imgicon2" xlink:href="http://i1.piimg.com/567571/220defbd8306acf8.png" class="testicon" x="200" y="0" height="100" width="100" />
</svg>

event.offsetX during mousemove

When I move the mouse over the element I need to find the offsetX position. The problem is that when I move the mouse I'm getting the value for the child element which is present inside. Is it possible to identify the mouse position of my main object even if I move my mouse in child target?
I'm not able to use event.pageX because I'm using transform: scale(1) for the element.
$('.main').on('mousemove', function(event) {
event.preventDefault();
$(this).closest('.outer').find('p').html(event.offsetX);
});
<style> * {
margin: 0;
}
.outer {
border: 1px solid #ff0000;
float: left;
margin: 10px;
padding: 5px;
overflow: hidden
}
.inner > svg {
width: 100;
height: 100px;
}
.inner {
-ms-transform: scale(1);
-webkit-transform: scale(1);
transform: scale(1);
transform-origin: 0 0;
}
.two {
-ms-transform: scale(1.5);
-webkit-transform: scale(1.5);
transform: scale(1.5);
}
.three {
-ms-transform: scale(.5);
-webkit-transform: scale(.5);
transform: scale(.5);
}
p {
position: relative;
z-index: 1;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="outer">
<div class="inner one">
<svg style="border:1px solid #000" class="main">
<g transform="translate(10, 10)" stroke="#000000" fill="#ffffff" stroke-width="1" data-id="16">
<foreignObject style="overflow:visible;" pointer-events="all" width="100" height="100">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%">
<rect x="0" y="0" width="100%" height="100%" pointer-events="all"></rect>
<foreignObject style="overflow:visible;" pointer-events="all" width="100%" height="100%">
<div class="labelwrapper" xmlns="http://www.w3.org/1999/xhtml" style="width:100%; height:100%;">
<div class="labelcontent" contenteditable="true" style="height:100%;">Sample</div>
</div>
</foreignObject>
</svg>
</foreignObject>
</g>
</svg>
</div>
<p>Value</p>
</div>
<div class="outer">
<div class="inner two">
<svg style="border:1px solid #000" class="main">
<g transform="translate(10, 10)" stroke="#000000" fill="#ffffff" stroke-width="1" data-id="16">
<foreignObject style="overflow:visible;" pointer-events="all" width="100" height="100">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%">
<rect x="0" y="0" width="100%" height="100%" pointer-events="all"></rect>
<foreignObject style="overflow:visible;" pointer-events="all" width="100%" height="100%">
<div class="labelwrapper" xmlns="http://www.w3.org/1999/xhtml" style="width:100%; height:100%;">
<div class="labelcontent" contenteditable="true" style="height:100%;">Sample</div>
</div>
</foreignObject>
</svg>
</foreignObject>
</g>
</svg>
</div>
<p>Value</p>
</div>
<div class="outer">
<div class="inner three">
<svg style="border:1px solid #000" class="main">
<g transform="translate(10, 10)" stroke="#000000" fill="#ffffff" stroke-width="1" data-id="16">
<foreignObject style="overflow:visible;" pointer-events="all" width="100" height="100">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%">
<rect x="0" y="0" width="100%" height="100%" pointer-events="all"></rect>
<foreignObject style="overflow:visible;" pointer-events="all" width="100%" height="100%">
<div class="labelwrapper" xmlns="http://www.w3.org/1999/xhtml" style="width:100%; height:100%;">
<div class="labelcontent" contenteditable="true" style="height:100%;">Sample</div>
</div>
</foreignObject>
</svg>
</foreignObject>
</g>
</svg>
</div>
<p>Value</p>
</div>
I Found the answer by change the script as given below.
$('.main').on('mousemove', function(event) {
event.preventDefault();
if($(event.target).attr('class')== 'main')
$(this).closest('.outer').find('p').html(event.offsetX);
else{
var val = parseInt($(event.target).closest('g').attr('transform').split(/[()]/)[1].split(',')[0]);
$(this).closest('.outer').find('p').html(event.offsetX+val);
}
});

Categories

Resources