I am creating a star shape in svg
<polygon></polygon>
with this
The code is following
// targeting the svg itself
const svg = document.querySelector("svg");
// variable for the namespace
const svgns = "http://www.w3.org/2000/svg"
//make background
var fill1 = "#e6e6e6";
var fill2 = "transparent";
let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute("class", "bg");
bg.setAttribute("id", "bg");
bg.setAttribute("width", "500");
bg.setAttribute("height", "500");
bg.setAttribute("fill", fill1);
svg.appendChild(bg);
let ln1 = document.createElementNS(svgns, 'line');
ln1.setAttribute("x1", "250");
ln1.setAttribute("y1", "0");
ln1.setAttribute("x2", "250");
ln1.setAttribute("y2", "500");
ln1.setAttribute("stroke-width", "1");
ln1.setAttribute("stroke", "red");
ln1.setAttribute("class", "XAxis")
svg.appendChild(ln1);
let ln2 = document.createElementNS(svgns, 'line');
ln2.setAttribute("x1", "0");
ln2.setAttribute("y1", "250");
ln2.setAttribute("x2", "500");
ln2.setAttribute("y2", "250");
ln2.setAttribute("stroke-width", "2");
ln2.setAttribute("stroke", "green");
ln2.setAttribute("class", "YAxis");
svg.appendChild(ln2);
let circ = document.createElementNS(svgns, 'circle');
circ.setAttribute("cx", "250");
circ.setAttribute("cy", "250");
circ.setAttribute("r", "50");
circ.setAttribute("fill", "none");
circ.setAttribute("stroke", "blue");
circ.setAttribute("id", "circ");
circ.setAttribute("class", "circ");
svg.appendChild(circ);
var circle = document.getElementById('circ');
var circleCX = parseFloat(circle.getAttribute('cx'));
var circleCY = parseFloat(circle.getAttribute('cy'));
var circleR = parseFloat(circle.getAttribute('r'));
var arms = 5;
function CalculateStarPoints(centerX, centerY, arms, outerRadius, innerRadius) {
var results = "";
var angle = Math.PI / arms;
for (var i = 0; i < 2 * arms; i ) {
// Use outer or inner radius depending on what iteration we are in.
var r = (i % 2) == 0 ? outerRadius : innerRadius;
var currX = centerX Math.cos(i * angle) * r;
var currY = centerY Math.sin(i * angle) * r;
// Our first time we simply append the coordinates, subsequet times
// we append a ", " to distinguish each coordinate pair.
if (i == 0) {
results = currX "," currY;
} else {
results = ", " currX "," currY;
}
}
return results;
};
//creates pentagram
let poly = document.createElementNS(svgns, 'polygon');
poly.setAttribute("points", CalculateStarPoints(circleCX, circleCY, arms, 40, 20));
poly.setAttribute("stroke", "black");
svg.appendChild(poly);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<link rel="stylesheet" href="style.css"></link>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<script href="index.js"></script>
</svg>
</body>
</html>
I want to correctly align the star with the X Axis which is the red line
so that the top of the star is exactly aligned. How do I calculate the exact angle that I can pass on the following code that would correctly align the shape
poly.setAttribute("transform", ``rotate(${exactAngle},${circleCX},${circleCY})``);
CodePudding user response:
Here's a solution that calculates rotation based on number of arms:
For 5 arms (as per question):
// targeting the svg itself
const svg = document.querySelector("svg");
// variable for the namespace
const svgns = "http://www.w3.org/2000/svg"
//make background
var fill1 = "#e6e6e6";
var fill2 = "transparent";
let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute("class", "bg");
bg.setAttribute("id", "bg");
bg.setAttribute("width", "500");
bg.setAttribute("height", "500");
bg.setAttribute("fill", fill1);
svg.appendChild(bg);
let ln1 = document.createElementNS(svgns, 'line');
ln1.setAttribute("x1", "250");
ln1.setAttribute("y1", "0");
ln1.setAttribute("x2", "250");
ln1.setAttribute("y2", "500");
ln1.setAttribute("stroke-width", "1");
ln1.setAttribute("stroke", "red");
ln1.setAttribute("class", "XAxis")
svg.appendChild(ln1);
let ln2 = document.createElementNS(svgns, 'line');
ln2.setAttribute("x1", "0");
ln2.setAttribute("y1", "250");
ln2.setAttribute("x2", "500");
ln2.setAttribute("y2", "250");
ln2.setAttribute("stroke-width", "2");
ln2.setAttribute("stroke", "green");
ln2.setAttribute("class", "YAxis");
svg.appendChild(ln2);
let circ = document.createElementNS(svgns, 'circle');
circ.setAttribute("cx", "250");
circ.setAttribute("cy", "250");
circ.setAttribute("r", "50");
circ.setAttribute("fill", "none");
circ.setAttribute("stroke", "blue");
circ.setAttribute("id", "circ");
circ.setAttribute("class", "circ");
svg.appendChild(circ);
var circle = document.getElementById('circ');
var circleCX = parseFloat(circle.getAttribute('cx'));
var circleCY = parseFloat(circle.getAttribute('cy'));
var circleR = parseFloat(circle.getAttribute('r'));
var arms = 5;
function CalculateStarPoints(centerX, centerY, arms, outerRadius, innerRadius) {
var results = "";
var angle = Math.PI / arms;
for (var i = 0; i < 2 * arms; i ) {
// Use outer or inner radius depending on what iteration we are in.
var r = (i % 2) == 0 ? outerRadius : innerRadius;
var currX = centerX Math.cos(i * angle) * r;
var currY = centerY Math.sin(i * angle) * r;
// Our first time we simply append the coordinates, subsequet times
// we append a ", " to distinguish each coordinate pair.
if (i == 0) {
results = currX "," currY;
} else {
results = ", " currX "," currY;
}
}
return results;
};
function CalculateAngle(arms) {
const angle = Math.PI / arms
let exactAngle = 0
// Conditions based on number of arms
if (arms % 2 === 0) {
if (arms % 4 === 0) {
exactAngle = 0
} else {
exactAngle = angle
}
} else {
exactAngle = Math.PI / 2 - angle
}
// Return as degrees
return exactAngle * 180 / Math.PI
}
//creates pentagon
let poly = document.createElementNS(svgns, 'polygon');
poly.setAttribute("points", CalculateStarPoints(circleCX, circleCY, arms, 40, 20));
poly.setAttribute("stroke", "black");
poly.setAttribute("transform", `rotate(${CalculateAngle(arms)},${circleCX},${circleCY})`);
svg.appendChild(poly);
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"></svg>
For 7 arms:
// targeting the svg itself
const svg = document.querySelector("svg");
// variable for the namespace
const svgns = "http://www.w3.org/2000/svg"
//make background
var fill1 = "#e6e6e6";
var fill2 = "transparent";
let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute("class", "bg");
bg.setAttribute("id", "bg");
bg.setAttribute("width", "500");
bg.setAttribute("height", "500");
bg.setAttribute("fill", fill1);
svg.appendChild(bg);
let ln1 = document.createElementNS(svgns, 'line');
ln1.setAttribute("x1", "250");
ln1.setAttribute("y1", "0");
ln1.setAttribute("x2", "250");
ln1.setAttribute("y2", "500");
ln1.setAttribute("stroke-width", "1");
ln1.setAttribute("stroke", "red");
ln1.setAttribute("class", "XAxis")
svg.appendChild(ln1);
let ln2 = document.createElementNS(svgns, 'line');
ln2.setAttribute("x1", "0");
ln2.setAttribute("y1", "250");
ln2.setAttribute("x2", "500");
ln2.setAttribute("y2", "250");
ln2.setAttribute("stroke-width", "2");
ln2.setAttribute("stroke", "green");
ln2.setAttribute("class", "YAxis");
svg.appendChild(ln2);
let circ = document.createElementNS(svgns, 'circle');
circ.setAttribute("cx", "250");
circ.setAttribute("cy", "250");
circ.setAttribute("r", "50");
circ.setAttribute("fill", "none");
circ.setAttribute("stroke", "blue");
circ.setAttribute("id", "circ");
circ.setAttribute("class", "circ");
svg.appendChild(circ);
var circle = document.getElementById('circ');
var circleCX = parseFloat(circle.getAttribute('cx'));
var circleCY = parseFloat(circle.getAttribute('cy'));
var circleR = parseFloat(circle.getAttribute('r'));
var arms = 7;
function CalculateStarPoints(centerX, centerY, arms, outerRadius, innerRadius) {
var results = "";
var angle = Math.PI / arms;
for (var i = 0; i < 2 * arms; i ) {
// Use outer or inner radius depending on what iteration we are in.
var r = (i % 2) == 0 ? outerRadius : innerRadius;
var currX = centerX Math.cos(i * angle) * r;
var currY = centerY Math.sin(i * angle) * r;
// Our first time we simply append the coordinates, subsequet times
// we append a ", " to distinguish each coordinate pair.
if (i == 0) {
results = currX "," currY;
} else {
results = ", " currX "," currY;
}
}
return results;
};
function CalculateAngle(arms) {
const angle = Math.PI / arms
let exactAngle = 0
// Conditions based on number of arms
if (arms % 2 === 0) {
if (arms % 4 === 0) {
exactAngle = 0
} else {
exactAngle = angle
}
} else {
exactAngle = Math.PI / 2 - angle
}
// Return as degrees
return exactAngle * 180 / Math.PI
}
//creates pentagon
let poly = document.createElementNS(svgns, 'polygon');
poly.setAttribute("points", CalculateStarPoints(circleCX, circleCY, arms, 40, 20));
poly.setAttribute("stroke", "black");
poly.setAttribute("transform", `rotate(${CalculateAngle(arms)},${circleCX},${circleCY})`);
svg.appendChild(poly);
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"></svg>
For 10 arms:
// targeting the svg itself
const svg = document.querySelector("svg");
// variable for the namespace
const svgns = "http://www.w3.org/2000/svg"
//make background
var fill1 = "#e6e6e6";
var fill2 = "transparent";
let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute("class", "bg");
bg.setAttribute("id", "bg");
bg.setAttribute("width", "500");
bg.setAttribute("height", "500");
bg.setAttribute("fill", fill1);
svg.appendChild(bg);
let ln1 = document.createElementNS(svgns, 'line');
ln1.setAttribute("x1", "250");
ln1.setAttribute("y1", "0");
ln1.setAttribute("x2", "250");
ln1.setAttribute("y2", "500");
ln1.setAttribute("stroke-width", "1");
ln1.setAttribute("stroke", "red");
ln1.setAttribute("class", "XAxis")
svg.appendChild(ln1);
let ln2 = document.createElementNS(svgns, 'line');
ln2.setAttribute("x1", "0");
ln2.setAttribute("y1", "250");
ln2.setAttribute("x2", "500");
ln2.setAttribute("y2", "250");
ln2.setAttribute("stroke-width", "2");
ln2.setAttribute("stroke", "green");
ln2.setAttribute("class", "YAxis");
svg.appendChild(ln2);
let circ = document.createElementNS(svgns, 'circle');
circ.setAttribute("cx", "250");
circ.setAttribute("cy", "250");
circ.setAttribute("r", "50");
circ.setAttribute("fill", "none");
circ.setAttribute("stroke", "blue");
circ.setAttribute("id", "circ");
circ.setAttribute("class", "circ");
svg.appendChild(circ);
var circle = document.getElementById('circ');
var circleCX = parseFloat(circle.getAttribute('cx'));
var circleCY = parseFloat(circle.getAttribute('cy'));
var circleR = parseFloat(circle.getAttribute('r'));
var arms = 10;
function CalculateStarPoints(centerX, centerY, arms, outerRadius, innerRadius) {
var results = "";
var angle = Math.PI / arms;
for (var i = 0; i < 2 * arms; i ) {
// Use outer or inner radius depending on what iteration we are in.
var r = (i % 2) == 0 ? outerRadius : innerRadius;
var currX = centerX Math.cos(i * angle) * r;
var currY = centerY Math.sin(i * angle) * r;
// Our first time we simply append the coordinates, subsequet times
// we append a ", " to distinguish each coordinate pair.
if (i == 0) {
results = currX "," currY;
} else {
results = ", " currX "," currY;
}
}
return results;
};
function CalculateAngle(arms) {
const angle = Math.PI / arms
let exactAngle = 0
// Conditions based on number of arms
if (arms % 2 === 0) {
if (arms % 4 === 0) {
exactAngle = 0
} else {
exactAngle = angle
}
} else {
exactAngle = Math.PI / 2 - angle
}
// Return as degrees
return exactAngle * 180 / Math.PI
}
//creates pentagon
let poly = document.createElementNS(svgns, 'polygon');
poly.setAttribute("points", CalculateStarPoints(circleCX, circleCY, arms, 40, 20));
poly.setAttribute("stroke", "black");
poly.setAttribute("transform", `rotate(${CalculateAngle(arms)},${circleCX},${circleCY})`);
svg.appendChild(poly);
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"></svg>
Let's see 51 arms:
// targeting the svg itself
const svg = document.querySelector("svg");
// variable for the namespace
const svgns = "http://www.w3.org/2000/svg"
//make background
var fill1 = "#e6e6e6";
var fill2 = "transparent";
let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute("class", "bg");
bg.setAttribute("id", "bg");
bg.setAttribute("width", "500");
bg.setAttribute("height", "500");
bg.setAttribute("fill", fill1);
svg.appendChild(bg);
let ln1 = document.createElementNS(svgns, 'line');
ln1.setAttribute("x1", "250");
ln1.setAttribute("y1", "0");
ln1.setAttribute("x2", "250");
ln1.setAttribute("y2", "500");
ln1.setAttribute("stroke-width", "1");
ln1.setAttribute("stroke", "red");
ln1.setAttribute("class", "XAxis")
svg.appendChild(ln1);
let ln2 = document.createElementNS(svgns, 'line');
ln2.setAttribute("x1", "0");
ln2.setAttribute("y1", "250");
ln2.setAttribute("x2", "500");
ln2.setAttribute("y2", "250");
ln2.setAttribute("stroke-width", "2");
ln2.setAttribute("stroke", "green");
ln2.setAttribute("class", "YAxis");
svg.appendChild(ln2);
let circ = document.createElementNS(svgns, 'circle');
circ.setAttribute("cx", "250");
circ.setAttribute("cy", "250");
circ.setAttribute("r", "50");
circ.setAttribute("fill", "none");
circ.setAttribute("stroke", "blue");
circ.setAttribute("id", "circ");
circ.setAttribute("class", "circ");
svg.appendChild(circ);
var circle = document.getElementById('circ');
var circleCX = parseFloat(circle.getAttribute('cx'));
var circleCY = parseFloat(circle.getAttribute('cy'));
var circleR = parseFloat(circle.getAttribute('r'));
var arms = 51;
function CalculateStarPoints(centerX, centerY, arms, outerRadius, innerRadius) {
var results = "";
var angle = Math.PI / arms;
for (var i = 0; i < 2 * arms; i ) {
// Use outer or inner radius depending on what iteration we are in.
var r = (i % 2) == 0 ? outerRadius : innerRadius;
var currX = centerX Math.cos(i * angle) * r;
var currY = centerY Math.sin(i * angle) * r;
// Our first time we simply append the coordinates, subsequet times
// we append a ", " to distinguish each coordinate pair.
if (i == 0) {
results = currX "," currY;
} else {
results = ", " currX "," currY;
}
}
return results;
};
function CalculateAngle(arms) {
const angle = Math.PI / arms
let exactAngle = 0
// Conditions based on number of arms
if (arms % 2 === 0) {
if (arms % 4 === 0) {
exactAngle = 0
} else {
exactAngle = angle
}
} else {
exactAngle = Math.PI / 2 - angle
}
// Return as degrees
return exactAngle * 180 / Math.PI
}
//creates pentagon
let poly = document.createElementNS(svgns, 'polygon');
poly.setAttribute("points", CalculateStarPoints(circleCX, circleCY, arms, 40, 20));
poly.setAttribute("stroke", "black");
poly.setAttribute("transform", `rotate(${CalculateAngle(arms)},${circleCX},${circleCY})`);
svg.appendChild(poly);
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"></svg>