I have a svg array:
var rects = []; //for svg objectsvar
var j=0;
var NS ="http://www.w3.org/2000/svg";
var x = 140, y = 100;
$(document).ready(function() {
function drawRect() {
for(var i=0; i<4; i++) {
var rect = document.createElementNS(NS, 'rect');
rect.setAttributeNS(null, 'id', "srect"+i);
rect.setAttributeNS(null, 'x', x);
rect.setAttributeNS(null, 'y', y);
rect.setAttributeNS(null, 'height', '80');
rect.setAttributeNS(null, 'width', '80');
rect.setAttributeNS(null, 'fill', '#000000');
rects.push(rect);
document.getElementById('svgOne').appendChild(rects[i]);
x+=80;
}
moveTwoRect(j);
}
}
function moveTwoRect() {
for(var j=0; j<4; j++) {
$(function () {
$('#'+rects[j].id).animate({y: '50px'}, 3000);
$('#'+rects[j+1].id).animate({y: '50px'}, 3000);
});
}
}
$("#bu").click(drawRect);
});
</script>
<svg xmlns:svg="http://www.w3.org/2000/svg" id="svgOne"
xmlns="http://www.w3.org/2000/svg" width="800" height="600">
This browser is not support svg. Please Upgrade Your browser version
or Use Other browser.
<rect width="800" height="400" style="fill:white; stroke-width:3;stroke:black">
</svg>
<button id='bu1'>Push Me</button>
I want to move two rects at same time.
for example, rects[0], rects[1] move at same time.
and rects[1], rects[2] move at same time.
other rects move like this.
but all of rects move at same time when i push button.
What do i do for this problem?
I want use only javascript or jquery.
Related
HTML code:
<div class="dots" id="dotsSlider">
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="30" viewBox="0 0 400 60" id="ante">
<rect width="100%" height="100%" fill="none" />
</svg>
</div>
Javascript code:
for (let i = 0; i < 10; i++) {
// targeting the svg itself
const svgns = "http://www.w3.org/2000/svg";
// variable for the namespace
var svg = document.querySelector("svg");
var x = i.toString();
var name = "newCircle" + x;
var name2 = name;
var counter = i + 1;
var position = 36 * counter;
// make a simple rectangle
var name = document.createElementNS(svgns, "circle");
// set attributes of new circle
gsap.set(name, {attr: {
cx: position,
cy: 25,
r: 8,
width: 30,
height: 30,
fill: "black",
id: name2
}});
// append the new rectangle to the svg
svg.appendChild(name);
}
So far so good I created 10 SVGs (dots for a slider). For loop is written inside a function that runs when the page loads. My problem is that I do not know how to access the fill property of these SVGs in order to be able to change it in a dynamic way inside another function. I tried everything related to getElement parsing it to a variable, but propably I am writing something wrong. Any help is much appreciated.
Try this:
var circle = document.getElementById("newCircle3"); // etc
circle.style.fill = "red";
I'm about to write some JavaScript that wraps around SVG for convenience. This code can take an SVG section of a HTML page and insert SVG items dynamically. This works quite well for rectangles and circles and these kind of shapes, but it does not work for images: Whenever I create an image item the Y position of the image is way off. X is fine: An X-value of zero renders the image left aligned with the SVG canvas. But it is quite strange: I require a negative Y-value for the image to align to the top of the SVG.canvas. In contrast to primitive shapes if I specify zero for Y for images these images get centered vertically within my SVG canvas. Why is that the case? What am I missing?
The essential aspects of my code:
function __makeSVG(tag, attrs)
{
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
And:
function createImageXY(x, y, url) {
var style = {};
style["x"] = x;
style["y"] = y;
style["width"] = "100%";
style["height"] = "100%";
style["visibility"] = "visible";
var svgItem = __makeSVG('image', style);
svgItem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', url);
main.appendChild(svgItem);
}
And the SVG canvas in HTML is created like this:
<svg id="viewport" style="stroke-width: 0px; background-color: black; width:1200px; height:800px"
xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
>
</svg>
More strangely: If I scale the image the vertical position will be scaled as well.
I would like to have absolute positioning like I have for rectangles and circles and these things. A position of (100, 100) should position the image to exact (100, 100) and not somewhere else. What am I missing? How can I accomplish that?
Am I correct in guessing that the image you are using is wider than it is high? Like this example?
var main = document.getElementById("viewport");
function __makeSVG(tag, attrs)
{
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
function createImageXY(x, y, url) {
var style = {};
style["x"] = x;
style["y"] = y;
style["width"] = "100%";
style["height"] = "100%";
style["visibility"] = "visible";
var svgItem = __makeSVG('image', style);
svgItem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', url);
main.appendChild(svgItem);
}
createImageXY(0, 0, "https://placekitten.com/400/200");
<svg id="viewport" style="stroke-width: 0px; background-color: black; width:1200px; height:800px"
xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>
When you specify width="100%" and height="100%" for an SVG image element, you are not saying "draw the image at the image's natural width and height". Nor are you saying "draw it at the same width and height as the <svg>".
What you are saying is "draw the image at its normal aspect ratio, but scaled up to fit inside a box that is the same width and height as the <svg>".
So in my example above, the 400x200 image is being scaled up to neatly fit inside the 1200x800 <svg>. When you do that, the image is actually drawn at 1200x600. That's the largest size it can be and still fit inside the SVG.
Additionally, by default, the image gets centred inside that "viewport". Which means there is 200 pixels (800 - 600 ) of blank space that gets distributed above and below the scaled image.
Solution 1: stretch the image
If you want the image to be exactly the same width and height of the SVG. Then you can set preserveAspectRatio="none", which will cause it to be stretched vertically and horizontally to the same size as the SVG.
var main = document.getElementById("viewport");
function __makeSVG(tag, attrs)
{
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
function createImageXY(x, y, url) {
var style = {};
style["x"] = x;
style["y"] = y;
style["width"] = "100%";
style["height"] = "100%";
style["visibility"] = "visible";
style["preserveAspectRatio"] = "none";
var svgItem = __makeSVG('image', style);
svgItem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', url);
main.appendChild(svgItem);
}
createImageXY(100, 100, "https://placekitten.com/400/200");
<svg id="viewport" style="stroke-width: 0px; background-color: black; width:1200px; height:800px"
xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>
Solution 2: position at top left of image viewport instead of centering
You can keep the scaling that preserves the aspect ratio, but disable the centering behaviou by setting preserveAspectRatio="xMinYMin". This value tells it to position the top left of the image at the x,y, coordinates you have specified.
var main = document.getElementById("viewport");
function __makeSVG(tag, attrs)
{
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
function createImageXY(x, y, url) {
var style = {};
style["x"] = x;
style["y"] = y;
style["width"] = "100%";
style["height"] = "100%";
style["visibility"] = "visible";
style["preserveAspectRatio"] = "xMinYMin";
var svgItem = __makeSVG('image', style);
svgItem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', url);
main.appendChild(svgItem);
}
createImageXY(100, 100, "https://placekitten.com/400/200");
<svg id="viewport" style="stroke-width: 0px; background-color: black; width:1200px; height:800px"
xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>
Solution 3: give it a real size instead of percentage size
Specify a width and height that is appropriate, rather than using percentages. But remember that if you specify a width and height that have a different aspect ration different from the image, you will still see the same problem.
var main = document.getElementById("viewport");
function __makeSVG(tag, attrs)
{
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
function createImageXY(x, y, url) {
var style = {};
style["x"] = x;
style["y"] = y;
style["width"] = "600";
style["height"] = "300";
style["visibility"] = "visible";
var svgItem = __makeSVG('image', style);
svgItem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', url);
main.appendChild(svgItem);
}
createImageXY(100, 100, "https://placekitten.com/400/200");
<svg id="viewport" style="stroke-width: 0px; background-color: black; width:1200px; height:800px"
xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>
I have created a small rect using js and svg, here is the code for it:
Html:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<svg id="svgOne" xmlns="http://www.w3.org/2000/svg" width="5000" height="3000">
</svg>
</body>
</html>
and js:
var svgns = "http://www.w3.org/2000/svg";
var x = 50,
y = 30;
var rect = document.createElementNS(svgns, 'rect');
rect.setAttributeNS(null, 'x', x);
rect.setAttributeNS(null, 'y', y);
rect.setAttributeNS(null, 'height', '50');
rect.setAttributeNS(null, 'width', '50');
rect.setAttributeNS(null, 'fill', 'grey');
document.getElementById('svgOne').appendChild(rect);
and here is the jsfiddle.
I want to add a check mark inside the rectangle, the check mark looks like:
How am I supposed to do this?
You can use the svg path element to crate your check mark. The tricky part about the path element is the d attribute, which will describe the path combining several instructions. Here is some good information on how the d attribute works.
Take a look at the example and i'm sure you will get the idea.
var svgns = "http://www.w3.org/2000/svg";
var x = 50,
y = 30;
// create group element
var group = document.createElementNS(svgns, 'g');
var rect = document.createElementNS(svgns, 'rect');
// create the path element
var checkMark = document.createElementNS(svgns, 'path');
// set group position
group.setAttributeNS(null, 'transform', 'translate('+ x + ', '+ y + ')');
rect.setAttributeNS(null, 'height', '50');
rect.setAttributeNS(null, 'width', '50');
rect.setAttributeNS(null, 'fill', 'grey');
// set path attributes
checkMark.setAttributeNS(null, 'd', 'M7.375,33.25 c0,0,10,11.375,14.125,11.375S44.875,8,44.875,8');
checkMark.setAttributeNS(null, 'fill', 'none');
checkMark.setAttributeNS(null, 'stroke-linecap', 'round');
checkMark.setAttributeNS(null, 'style', 'stroke:rgb(255,255,255);stroke-width:6');
// append elements to group
group.appendChild(rect);
group.appendChild(checkMark);
// append group to svg
document.getElementById('svgOne').appendChild(group);
// clone your checkmark
var checkMarkCopy = group.cloneNode(true);
checkMarkCopy.setAttributeNS(null, 'transform', 'translate(100, 100)');
document.getElementById('svgOne').appendChild(checkMarkCopy);
<svg id="svgOne" xmlns="http://www.w3.org/2000/svg" width="5000" height="3000"></svg>
When I executed the web page I got the error:
Uncaught TypeError: Cannot read property 'appendChild' of null
at: document.getElementById('svgOne').appendChild(group);
So I rearranged stuff according to what I learned from:
Saved from: https://www.sitepoint.com/community/t/creating-a-svg-element/5929/
ADDED: <title> in the <head> (not important at all).
MOVED: </head> to just after the <title>.
MOVED: <body> and <h2> to just after </head>.
ADDED: <div id="container"/> to <body>. //Will contain all of the SVG content.
NOTE: At this point, the container has been added to the <body> and the <script> is now positioned INSIDE the <body>.
DELETED the original SVG element from the : => <svg id="svgOne" xmlns="http://www.w3.org/2000/svg" width="500" height="300"> </svg>.
ADDED the creation of a new SVG element in the <script>:
var svg = document.createElementNS(svgns, "svg"); //Create an svg tag in SVG's namespace
svg.setAttribute("width", "300");
svg.setAttribute("height", "400");
DELETED the original appendChild(group): => document.getElementById('svgOne').appendChild(group);
REPLACED it with the new appendChild(group):=>
svg.appendChild(group);
DELETED the original appendChild(checkMarkCopy): => document.getElementById('svgOne').appendChild(checkMarkCopy);
REPLACED it with the new appendChild(checkMarkCopy):=>
svg.appendChild(checkMarkCopy);
ADDED: => document.getElementById("container").appendChild(svg);
This worked in Chrome Version 58.0.3029.110.
In the Chrome console, the framework looks like:
Framework of web page.
(UPDATED) I'm having some issues regarding svg and javascript. What I want to create is a series of circles on top of one another, with their radius (r) values increasing by one each time the loop goes round, so that it creates some sort of a pattern. Here is what I have so far(for loop values are from another forum post, I would rather do it with a while loop that would execute 10 times) -
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Dynamic SVG!</title>
</head>
<defs>
<svg height="10000" width="10000" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle id="cir1" cx="300" cy="300" r="40" stroke="yellow" stroke-width="" fill="none"/>
</svg>
</defs>
<script>
var svgns = "http://www.w3.org/2000/svg";
for (var x = 0; x < 5000; x += 50) {
for (var y = 0; y < 3000; y += 50) {
var circle = document.createElementNS(svgns, 'circle');
circle.setAttributeNS(null, 'x', x);
circle.setAttributeNS(null, 'y', y);
circle.setAttributeNS(null, 'height', '50');
circle.setAttributeNS(null, 'width', '50');
document.getElementById('cir1').appendChild(circle);
}
}
</script>
<body>
</body>
</html>
Any help out there?
Thanks.
Ok, so this is, what I had to fix in order to get your code working:
You append to the circle element, but should append to the svg-container. A circle element has no child elements.
You did not set any styles for the circles, so they were transparent.
The coordinates in a circle element are called cx and cy instead of x and y.
The <defs> element should be a child of the <svg> element. Also everything within it wont be rendered.
JavaScript
var svgns = "http://www.w3.org/2000/svg",
container = document.getElementById( 'cont' );
for (var x = 0; x < 500; x += 50) {
for (var y = 0; y < 300; y += 50) {
var circle = document.createElementNS(svgns, 'circle');
circle.setAttributeNS(null, 'cx', x);
circle.setAttributeNS(null, 'cy', y);
circle.setAttributeNS(null, 'r', 50);
circle.setAttributeNS(null, 'style', 'fill: none; stroke: blue; stroke-width: 1px;' );
container.appendChild(circle);
}
}
HTML
<svg id="cont" height="1000" width="1000" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle id="cir1" cx="300" cy="300" r="40" stroke="yellow" stroke-width="" fill="none" />
</svg>
Example Fiddle
I also adjusted your sizes as for a mere test, they were quite big.
The code below should generate 100 random rectangles. But its not working. Can anyone tell me what I am doing wrong??
<html>
<head>
<script type="text/javascript">
function rectan()
{
var svgns = "http://www.w3.org/2000/svg";
for (var i = 0; i < 100; i++) {
var x = Math.random() * 5000,
y = Math.random() * 3000;
var rect = document.createElementNS(svgns, 'rect');
rect.setAttributeNS(null, 'x', x);
rect.setAttributeNS(null, 'y', y);
rect.setAttributeNS(null, 'height', '50');
rect.setAttributeNS(null, 'width', '50');
rect.setAttributeNS(null, 'fill', '#'+Math.round(0xffffff * Math.random()).toString(16));
document.getElementById('svgOne').appendChild(rect);
}
}
</script>
</head>
<body onload="rectan"();">
<svg id="svgOne" xmlns="http://www.w3.org/2000/svg" width="5000" height="3000">
<rect x="50" y="50"
width="50" height="50"
fill="black"
/>
</svg>
</body>
</html>
All it does is one black rectangle form SVG section. I know that I made a mistake somewhere, but I don't know where.
There seems to be an extraneous double qouote in the onload attribute. You want this...
<body onload="rectan();">