Basic vertical SVG line - javascript

I cannot seem to find a good, working example / tutorial of how to draw a simple, vertical line which animates gradually on scroll from nothing to a full line.
I have the code below which draws a horizontal line, but I cannot seem to successfully change this to a vertical line that continues to animate.
HTML:
<svg id="mySVG">
<path fill="none" stroke="red" stroke-width="3" id="triangle" d="M1 0 L75 0"/>
</svg>
CSS:
#mySVG {
position: fixed;
top: 15%;
width: 400px;
height: 210px;
margin-left:0px;
}
JS:
<script>
// Get the id of the <path> element and the length of <path>
var triangle = document.getElementById("triangle");
var length = triangle.getTotalLength();
// The start position of the drawing
triangle.style.strokeDasharray = length;
// Hide the triangle by offsetting dash. Remove this line to show the triangle before scroll draw
triangle.style.strokeDashoffset = length;
// Find scroll percentage on scroll (using cross-browser properties), and offset dash same amount as percentage scrolled
window.addEventListener("scroll", myFunction);
function myFunction() {
var scrollpercent = (document.body.scrollTop + document.documentElement.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
var draw = length * scrollpercent;
// Reverse the drawing (when scrolling upwards)
triangle.style.strokeDashoffset = length - draw;
}
</script>

It should just be a matter of making your line vertical, as follows:
<svg id="mySVG">
<path fill="none" stroke="red" stroke-width="3" id="triangle" d="M1 0 L1 75"/>
</svg>
What happens when you do that?

thanks for all your replies - I ended up using CSS transitions as this seem to work better.

Related

Curved Text inside a circle and center to bottom center

I have a circle, and i need to have text inside the circle, that follows the circles path. I have found this other question: Wrapping a text around a circular element
However, i was not able to achieve what i'm trying to do. My text has a dynamic length, and i need it to be always centered to the bottom center of the circle, and wrap "upwards" on both sides, if that makes sense. I have tried the svg approach, but when the text is too long, it gets cut off. What would be the best approach to do this?
The text would be orange here (dynamic length), and it needs to centered to the bottom of the circle (blue dot)
Having tried positioning text with middle in the svg I found it cut the text if the text was following a path - as in the question.
Could not find a solution for this in SVG and/or CSS so resorted to a method with JS and show it here just in case of use as an interim measure.
In this snippet, the width of the text is found and the amount the SVG needs to rotate in order to put the mid point of the text at the bottom center of the circle is calculated:
const textPath = document.querySelector('textPath');
const temp = document.createElement('div');
temp.innerHTML = textPath.innerHTML;
temp.style.display = 'inline-block';
temp.style.fontSize = '20px';
document.body.append(temp);
const w = temp.offsetWidth;
document.body.removeChild(temp);
const circumference = Math.PI * 200;
document.querySelector('svg').style.transform = 'rotate(' + Number((180 * w / circumference) - 90) + 'deg)';
.qr--label {
font-size: 20px;
margin: 0 0 -15px 0;
text-align: center;
}
<div class="qr">
<div>
<svg width="220" height="220">
<path fill="white" d="M0,110a110,110 0 1,0 220,0a110,110 0 1,0 -220,0"/>
<path fill="none" id="innerCircle" d="M10,110a100,100 0 1,0 200,0a100,100 0 1,0 -200,0"/>
<text>
<textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#innerCircle" class="qr--label">
Some dynamic text here
</textPath>
</text>
</svg>
</div>
</div>

SVG Element is Vertically Centred and I don't want it to be

I'm trying to recreate the old DVD logo that would bounce around the tv screen using the SVG html element.
<svg className='canvas'>
<svg ref={this.image} xmlns="http://www.w3.org/2000/svg" width="10%" viewBox="0 0 510 305" version="1.1">
<g ref={this.g} id="g1" transform="matrix(6,0,0,6,48.16071,-418.59098)">
<path id="path1" d="m 30.57323,69.90683 0,0.14991 0.14998,0.30006 0.15001,0.44999 0.14999,0.67505 0.37501,0.67497 0.22499,0.82497 0.22501,0.75005 0.29999,0.74996 0.22501,0.67505 0.14999,0.67497 0.15001,0.44998 0.6,1.57501 0.45,1.35003 0.29999,1.12496 0.375,0.90004 0.15001,0.74996 0.15,0.67505 0.075,0.37499 0.075,0.37498 0,0.29999 0.075,-0.075 0.075,-0.22499 0.15,-0.22507 0.22499,-0.37498 0.30001,-0.52498 0.52501,-0.59998 0.52498,-0.67497 0.67501,-0.90004 0.82499,-1.12495 0.97501,-1.20003 1.19999,-1.42502 0.30001,-0.29999 0.375,-0.44997 0.44999,-0.67505 0.67501,-0.67498 0.525,-0.74997 0.60001,-0.75004 0.67499,-0.74998 0.525,-0.59997 0.59999,-0.67505 0.37501,-0.37499 0.22499,-0.30006 0.075,-0.14991 17.24999,0 2.17501,0.14991 2.02499,0.22507 1.8,0.44998 1.72501,0.60005 1.49999,0.74997 1.35001,0.89997 1.12499,1.05003 0.975,1.05003 0.60002,1.19995 0.375,1.35002 0.075,1.35003 -0.22501,1.42494 -0.45,1.50001 -0.74999,1.35002 -0.97501,1.35003 -1.27499,1.19995 -1.425,1.12495 -1.57501,0.97504 -1.72499,0.89996 -1.875,0.82505 -2.02501,0.52505 -2.02498,0.44999 -2.10001,0.22498 -2.25,0.075 -11.55001,0 3.45001,-14.62502 8.175,0 -2.325,10.05005 1.8,0 1.425,-0.075 1.425,-0.15 1.425,-0.22499 1.19999,-0.37499 1.20002,-0.59997 1.12499,-0.60005 0.89999,-0.82498 0.75001,-0.82496 0.60001,-1.05004 0.44998,-1.20002 0.15001,-1.04995 -0.075,-0.97504 -0.29999,-0.89996 -0.6,-0.67505 -0.67501,-0.74998 -0.97499,-0.52497 -1.05,-0.44999 -1.20001,-0.30006 -1.34998,-0.14999 -1.57501,-0.075 -9.9,0 -18.75,21.30005 -7.425,-20.92506 0,-0.075 -0.075,-0.14999 0,-0.075 -0.15,-0.15 -0.075,0 -0.14999,0.15 0,0.075 0.075,0.075 0,0.15 0.075,0 0,0.075 0.22502,0.82504 0.14998,0.74997 0.075,0.90004 0.075,0.89996 0,0.75004 -0.075,0.74998 -0.075,0.52497 -0.45,1.50001 -0.825,1.35003 -0.975,1.35002 -1.20002,1.19988 -1.425,1.12495 -1.57501,0.97504 -1.79999,0.89996 -1.875,0.67505 -1.95001,0.67505 -2.09999,0.44999 -2.17501,0.22498 -2.09999,0.075 -11.625,0 3.525,-14.62502 8.175,0 -2.475,10.05005 1.95,0 1.425,-0.075 1.425,-0.15 1.275,-0.22499 1.35,-0.37499 1.19999,-0.59997 1.05002,-0.60005 0.89998,-0.82498 0.82501,-0.82496 0.52501,-1.05004 0.44998,-1.20002 0.15,-1.04995 -0.075,-0.97504 -0.375,-0.89996 -0.45,-0.67505 -0.74999,-0.74998 -0.9,-0.52497 -1.125,-0.44999 -1.2,-0.30006 -1.34999,-0.14999 -1.50001,-0.075 -10.12499,0 1.12499,-4.64996 31.12501,0" />
<path id="path2" d="m 30.64821,103.58183 -1.5,0 -2.69998,-0.15007 -1.12501,-0.14992 -1.125,-0.22506 -0.9,-0.15 -0.75,-0.29999 -0.6,-0.29999 -0.30001,-0.29999 -0.14999,-0.29998 0.14999,-0.29999 0.30001,-0.22506 0.6,-0.37499 0.75,-0.22499 0.9,-0.225 1.125,-0.14999 1.12501,-0.15007 1.34998,-0.0749 1.35,-0.075 1.5,-0.075 1.5,0.075 1.42501,0.075 1.27499,0.0749 1.27501,0.15008 0.975,0.14999 0.97501,0.225 0.67499,0.22498 0.6,0.37499 0.29999,0.22507 0.15001,0.29999 -0.15001,0.29998 -0.29999,0.29999 -0.6,0.29999 -0.67499,0.29999 -0.97501,0.15 -0.975,0.22506 -1.27501,0.14992 -1.27499,0.0751 -1.42501,0.075 -1.5,0 z m 1.5,-7.65007 -3.67499,0 -3.6,0.0751 -3.375,0.15 -3.3,0.14992 -3.225,0.15007 -3.00001,0.29999 -2.925,0.22499 -2.7,0.29998 -2.475,0.30007 -2.325,0.37498 -2.09999,0.44993 -1.875,0.37497 -1.65001,0.375 -1.275,0.52498 -1.05,0.45005 -0.825,0.44999 -0.44999,0.52498 -0.15001,0.52505 0.15001,0.44998 0.44999,0.59998 0.825,0.44999 1.05,0.45005 1.275,0.52497 1.65001,0.37499 1.875,0.37499 2.09999,0.44998 2.325,0.37498 2.475,0.30006 2.7,0.29999 2.925,0.225 3.00001,0.29999 3.225,0.15006 3.3,0.15 3.375,0.14999 3.6,0 3.67499,0.075 3.67502,-0.075 3.52499,0 3.375,-0.14999 3.29999,-0.15 3.22501,-0.15006 2.99999,-0.29999 2.92501,-0.225 2.69999,-0.29999 2.55001,-0.30006 2.25,-0.37498 2.17499,-0.44998 1.8,-0.37499 1.65001,-0.37499 1.34999,-0.52497 0.975,-0.45005 0.82502,-0.44999 0.44998,-0.59998 0.15001,-0.44998 -0.15001,-0.52505 -0.44998,-0.52498 -0.82502,-0.44999 -0.975,-0.45005 -1.34999,-0.52498 -1.65001,-0.37499 -1.8,-0.37498 -2.17499,-0.44998 -2.25,-0.37499 -2.55001,-0.30006 -2.69999,-0.29999 -2.92501,-0.22499 -2.99999,-0.29999 -3.22501,-0.15007 -3.29999,-0.14991 -3.375,-0.15 -3.52499,-0.0751 -3.67502,0" />
<path id="path3" d="m 71.59822,106.0568 -0.97501,0 -0.37499,2.92504 -0.45,0 0.375,-2.92504 -1.05001,0 0.075,-0.37506 2.475,0 -0.075,0.37506" />
<path id="path4" d="m 75.04822,108.98184 -0.45,0 0,-2.55005 -1.35001,2.55005 -0.52499,-2.55005 -0.89999,2.55005 -0.375,0 1.12499,-3.3001 0.29999,0 0.525,2.17506 1.20001,-2.17506 0.45,0 0,3.3001" />
<path id="path5" d="m 5.07322,117.53179 2.69999,-5.475 2.55001,0 -4.65,8.40004 -1.425,0 -4.57501,-8.40004 2.475,0 2.92501,5.475" />
<path id="path6" d="m 16.02321,120.45683 2.25,0 0,-8.4 -2.25,0 0,8.4 z" />
<path id="path7" d="m 28.39821,120.45683 -3.44998,0 0,-8.40004 3.44998,0 1.20001,0.075 1.12499,0.22499 1.05001,0.44998 0.82499,0.45005 0.67501,0.67498 0.525,0.67505 0.3,0.82496 0.075,0.82498 -0.075,0.90003 -0.3,0.74997 -0.525,0.75005 -0.75001,0.52497 -0.74999,0.59998 -1.05001,0.37506 -1.12499,0.22499 -1.20001,0.075 z m -0.67499,-6.97503 1.12499,0 0.9,0.225 0.67501,0.29999 0.59999,0.37499 0.45001,0.52505 0.225,0.59997 0.075,0.74998 -0.075,0.60005 -0.15001,0.52497 -0.22499,0.44999 -0.525,0.45005 -0.52501,0.29999 -0.67499,0.22491 -0.82501,0.15007 -1.04999,0.075 -0.37501,0 0,-5.55001 0.37501,0" />
<path id="path8" d="m 42.72322,113.4818 0,1.875 3.675,0 0,1.42503 -3.675,0 0,2.24998 3.89999,0 0,1.42502 -6.225,0 0,-8.40004 6.225,0 0,1.42501 -3.89999,0" />
<path id="path9" d="m 58.47322,120.45683 1.35,-0.075 1.125,-0.22499 1.04999,-0.37506 0.82501,-0.59998 0.75,-0.59997 0.525,-0.75004 0.29999,-0.74998 0.075,-0.82503 -0.075,-0.82498 -0.29999,-0.82496 -0.525,-0.60005 -0.75,-0.67498 -0.82501,-0.52505 -1.04999,-0.44998 -1.125,-0.22499 -1.35,-0.075 -1.20001,0.075 -1.12499,0.22499 -1.05001,0.44998 -0.82499,0.52505 -0.75001,0.67498 -0.52499,0.60005 -0.29999,0.82496 -0.075,0.82498 0.075,0.82503 0.29999,0.74998 0.52499,0.75004 0.75001,0.59997 0.82499,0.59998 1.05001,0.37506 1.12499,0.22499 1.20001,0.075 z m 0,-6.90003 0.89999,0.075 0.75,0.29999 0.67501,0.29999 0.525,0.37506 0.45,0.4499 0.22499,0.60005 0.075,0.52499 -0.075,0.60005 -0.22499,0.44997 -0.45,0.52499 -0.525,0.52505 -0.75,0.29999 -0.67501,0.22491 -0.89999,0.0751 -0.75,-0.0751 -0.82501,-0.22491 -0.59999,-0.29999 -0.525,-0.52505 -0.45,-0.52499 -0.22501,-0.44997 -0.075,-0.60005 0.075,-0.52499 0.22501,-0.60005 0.45,-0.4499 0.525,-0.37506 0.59999,-0.29999 0.82501,-0.29999 0.75,-0.075" />
</g>
</svg>
</svg>
This is what I've got so far. I have a parent SVG element which has some CSS styling to set its position to absolute and its width and height to 100%, so that it fills the whole window.
I then have the internal SVG element, which I've given a viewbox so that I can have the image be dynamically sized according to the size of the window.
This works but the SVG image ends up vertically centred in the window when x and y are set to 0, which is frustrating. I want the x=0 y=0 coordinate to be the top left of the window. If I am to remove the parent SVG element then the image successfully displays in the top left but I then can't use the coordinates to move it around the page, and if I don't specify a viewBox then I can use the coordinates and the origin is at the top left of the window but I have no control over the size of the image and it is rather larger than I would like.
What do I do?
Instead of using x and y to move your SVG around, you could use a translation. That would allow you to get rid of the outer SVG-element and have the inner one start positioned at the top left.
For example the CSS-rule svg { transform: translate(10px, 10px); } would move it 10px to the right and 10px down. Just set this as you would x and y otherwise.

How to make svg path as moveable?

I have created an SVG image. You can see it here:
jsfiddle.net/o2n56fyb/5/
In this SVG image, there is few dot line. You can see it here:
http://creativeartbd.com/demo/blockchain/
Now, I want to make those dot lines as moveable like it's running continuously. Is that possible? If so, can you tell me how?
You need to use stroke-dasharray and stroke-dashoffset for example like this:
var polygon = document.querySelector("polygon");
var dashoffset = 0;
polygon.style.strokeDashoffset = dashoffset;
function Animate() {
window.requestAnimationFrame(Animate);
dashoffset += 2;
polygon.style.strokeDashoffset = dashoffset;
}
Animate();
svg{border:1px solid #d9d9d9; display:block; margin:0 auto;max-height:100vh}
<svg width="250" height="250" viewBox="0 0 250 250">
<polygon points="50,50 200,50 200,200 50 200"
style="fill:none;
stroke:#000;
stroke-width:3;
stroke-dasharray: 30,15;"
></polygon>
</svg>
I hope this is what you need.

Partially fill a shape's border with colour

I am trying to create a progress effect whereby colour fills a DOM object's border (or possibly background). The image attached should give you a better idea of what I'm going for. I have achieved the current result by adding an object with a solid background colour over the grey lines and setting its height. This object has mix-blend-mode: color-burn; applied to it which is why it only colours the grey lines underneath it.
This works okay, but ruins the anti aliasing around the circle, and also the produced colour is unpredictable (changes depending on the colour of the lines).
I feel there must be a better way of achieving this, perhaps with the canvas element. Could someone point me in the right direction please?
Thanks in advance!
This should be possible to do with Canvas and may even be possible with CSS itself by playing with multiple elements etc but I would definitely recommend you to use SVG. SVG offers a lot of benefits in terms of how easy it is to code, maintain and also produce responsive outputs (unlike Canvas which tends to become pixelated when scaled).
The following are the components:
A rect element which is the same size as the parent svg and has a linear-gradient fill. The gradient has two colors - one is the base (light gray) and the other is the progress (cyan-ish).
A mask which is applied on the rect element. The mask has a path which is nothing but the line and the circle. When the mask is applied to the rect, only this path would show through the actual background (or fill) of the rect, the rest of the area would be masked out by the other rect which is added inside the mask.
The mask also has a text element to show the progress value.
The linear-gradient has the stop offset set in such a way that it is equal to the progress. By changing the offset, we can always make sure that the path shows the progress fill only for the required length and the base (light gray) for the rest.
window.onload = function() {
var progress = document.querySelector('#progress'),
base = document.querySelector('#base'),
prgText = document.querySelector('#prg-text'),
prgInput = document.querySelector('#prg-input');
prgInput.addEventListener('change', function() {
prgText.textContent = this.value + '%';
progress.setAttribute('offset', this.value + '%');
base.setAttribute('offset', this.value + '%');
});
}
svg {
width: 200px;
height: 300px;
}
path {
stroke-width: 4;
}
#rect {
fill: url(#grad);
mask: url(#path);
}
/* just for demo */
.controls {
position: absolute;
top: 0;
right: 0;
height: 100px;
line-height: 100px;
border: 1px solid;
}
.controls * {
vertical-align: middle;
}
body {
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<svg viewBox='0 0 200 300' id='shape-container'>
<linearGradient id='grad' gradientTransform='rotate(90 0 0)'>
<stop offset='50%' stop-color='rgb(0,218,235)' id='progress' />
<stop offset='50%' stop-color='rgb(238,238,238)' id='base' />
</linearGradient>
<mask id='path' maskUnits='userSpaceOnUse' x='0' y='0' width='200' height='300'>
<rect x='0' y='0' width='200' height='300' fill='black' />
<path d='M100,0 100,100 A50,50 0 0,0 100,200 L100,300 M100,200 A50,50 0 1,0 100,100' stroke='white' />
<text id='prg-text' x='100' y='155' font-size='20' text-anchor='middle' fill='white'>50%</text>
</mask>
<rect id='rect' x='0' y='0' width='200' height='300' />
</svg>
<!-- just for demo -->
<div class='controls'>
<label>Set Progress:</label>
<input type='range' id='prg-input' min='0' max='100' value='50' />
</div>
If you are new to SVG you can refer to the MDN Docs (links provided below) for more information about the elements, their attributes and values.
SVG Mask Element
SVG Tutorial on Paths

How to change parent offset value without changing its child offset?

I have a problem with element positioning. I have a div element which further contains the svg path element. Mark-up is something like this :
<div style="position:absolute;" class="svg">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<path id="path203" d="M150 0 L75 200 L225 200 Z" />
</svg>
</div>
I want to set the border around the path element when user mouseover the path. For this i have to access the height and weight of the path element and then set those value as an height and width of its parent div element. For this i used getBoundingClientRect(). Code :
var box = document.getElementById("path203").getBoundingClientRect();
$("#path203").parents("div.svg").css({ width: box.width + "px", height: box.height + "px" });
Here my problem is not fully solved by this i only get the border, but the position of div and its children path element is not the same both have different offset values. So for this i set the top and left for the parent div also :
var box = document.getElementById("path203").getBoundingClientRect();
$("#path203").parents("div.svg").offset({ left: box.left + "px", top: box.top });
Now by this div got the correct position but its child path element move away from its position. May be the reason is because the path element is the child of div element. So when we move div , all of its child elements will also move simultaneously. How can i change the parent div offset value without changing its child element offset ?
You could take the svg outside of parent div and access the div directly via $('div.svg').
Here is a fiddle: http://jsfiddle.net/FSQrz/
Is this what you're trying to achieve?
<div style="position:absolute;" class="svg">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="302" height="202">
<path id="path203" d="M150 0 L75 200 L225 200 Z" onmouseover="showRect()" onmouseout="hideRect()" />
<rect id="border203" fill="none" stroke="black" stroke-width="1"/>
<script>
function showRect() {
var bbox = document.getElementById("path203").getBBox();
var border = document.getElementById("border203");
border.x.baseVal.value = bbox.x;
border.y.baseVal.value = bbox.y;
border.width.baseVal.value = bbox.width;
border.height.baseVal.value = bbox.height;
}
function hideRect() {
var border = document.getElementById("border203");
border.width.baseVal.value = 0;
border.height.baseVal.value = 0;
}
</script>
</svg>
</div>

Categories

Resources