- 不鏽鋼隱身機.jpg (9.66 KiB) 查看 1655 次
做了一個svg 三角形畫板
源碼分享
代码: 全选
<p>因為我手機上的simplector不能方便的畫正三角形svg,因此我製作了此工具。▼◀</p>
<form id="ejmondouter">
<div id="svgouter">
<div id="svginner"></div>
<div><svg id="ejmond" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" width="480" height="480" viewbox="0 0 480 480"></svg></div>
</div>
<div></div>
<div class="ejmondbtn"><label class="ejmondlabel"> <input type="radio" name="pointtype" value="1" checked="checked" /> △ </label> <label class="ejmondlabel"> <input type="radio" name="pointtype" value="0" /> ▷ </label> <label class="ejmondlabel" style="float: right;"> <input type="checkbox" name="net" value="1" /> net </label></div>
<div></div>
<div class="ejmondbtn"><button type="button" onclick="undo()">undo</button> <button type="button" onclick="finish()">finish</button> <button type="button" onclick="downloadsvg()" style="float: right;">download</button></div>
</form>
<p><style>
#ejmondouter {text-align: center;}
.ejmondbtn {display: inline-block; width: 100%; max-width: 480px; text-align: left;}
.ejmondlabel {display: inline-block; border: 1px solid #444; border-radius: 7px; padding: 7px 24px;}
#ejmond {width: 100%; height: 100%; position: absolute; top: 0; left: 0;}
#svgouter {display: inline-block; position: relative; max-width: 100%;}
#svginner {width: 480px; max-width: 100%; padding-top: 100%; background-color: #fff;}
.hide {display: none;}
</style> <script>
var ejform = document.getElementById("ejmondouter");
var ejmond = document.getElementById("ejmond");
var paths = ejmond.getElementsByClassName("ejmond_path");
var paths_continue = ejmond.getElementsByClassName("continue");
var ejpoint_g, netpathmask, netpath;
addManyDots();
addLine();
// make dot
ejform.onchange = function (e) {
if (e.target.name == "pointtype") {
modifyManyDots();
modifyLine();
}
else if (e.target.name == "net") {
if (ejform.elements.net.checked) {
addMask();
} else {
removeMask();
}
}
};
function addManyDots () {
ejpoint_g = document.createElementNS('http://www.w3.org/2000/svg',
'g');
ejpoint_g.classList.add("point_g");
ejmond.appendChild(ejpoint_g);
modifyManyDots();
}
function modifyManyDots () {
let direction = ejform.elements.pointtype.value;
let sqrt3 = Math.sqrt(3);
let dots = ejmond.getElementsByClassName("ejmond_point");
let minidots = ejmond.getElementsByClassName("ejmond_minipoint");
// clear dots
while (dots.length) {
dots[0].remove();
}
while (minidots.length) {
minidots[0].remove();
}
if ("1" == direction) {
for (let j = -3; j <= 3; j++) {
for (let i = 0; i <= 12; i++) {
addDot(i * 36 + 24, 240 + sqrt3 * 36 * j);
if (j < 3 && i < 12) {
addDot(i * 36 + 42, 240 + sqrt3 * (36 * j + 18));
}
}
}
} else {
for (let j = -3; j <= 3; j++) {
for (let i = 0; i <= 12; i++) {
addDot(240 + sqrt3 * 36 * j, i * 36 + 24);
if (j < 3 && i < 12) {
addDot(240 + sqrt3 * (36 * j + 18), i * 36 + 42);
}
}
}
}
}
function addDot (cx, cy) {
// cdot
let cdot = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
cdot.classList.add("ejmond_point");
cdot.setAttribute("cx", cx);
cdot.setAttribute("cy", cy);
cdot.setAttribute("r", "12");
cdot.setAttribute("fill", "#ffffff");
ejpoint_g.appendChild(cdot);
// minidot
let minidot = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
minidot.classList.add("ejmond_minipoint");
minidot.setAttribute("cx", cx);
minidot.setAttribute("cy", cy);
minidot.setAttribute("r", "1");
minidot.setAttribute("fill", "#444");
ejpoint_g.appendChild(minidot);
}
// mousedown
var state = 0;
ejmond.onmousedown = ejmondDown;
ejmond.ontouchstart = function (e) {
e.preventDefault();
ejmondDown(e);
}
function ejmondDown(e) {
if (state == 0) {
if (e.target.classList.contains("ejmond_point") ||
e.target.classList.contains("ejmond_minipoint")) {
state = 4;
addPath(e);
}
} else {
if (e.target.classList.contains("ejmond_point") ||
e.target.classList.contains("ejmond_minipoint")) {
if (paths_continue.length ||
!e.target.classList.contains("start")) {
state = 2;
continuePath(e);
}
}
}
pTypeDisable();
};
ejmond.onmouseup = ejmondUp;
ejmond.ontouchend = function (e) {
e.preventDefault();
ejmondUp(e);
}
function ejmondUp (e) {
if (state == 2) {
state = 1;
}
else if (state == 4) {
state = 3;
}
};
ejmond.onmousemove = ejmondMove;
function ejmondMove(e) {
if (state == 2 || state == 4) {
if (e.target.classList.contains("ejmond_point") ||
e.target.classList.contains("ejmond_minipoint")) {
if (state == 2 || !e.target.classList.contains("start")) {
state = 2;
continuePath(e);
}
}
}
};
function addPath (e) {
// addPath
var ejpath = document.createElementNS('http://www.w3.org/2000/svg',
'path');
ejpath.classList.add("ejmond_path");
ejpath.setAttribute("fill", "none");
ejpath.setAttribute("stroke-width", "4");
ejpath.setAttribute("stroke-linecap", "round");
ejpath.setAttribute("stroke-linejoin", "round");
ejpath.setAttribute("stroke", "#4c4");
let cx = Number.parseFloat(e.target.getAttribute("cx"));
let cy = Number.parseFloat(e.target.getAttribute("cy"));
ejpath.setAttribute("d", "M " + Math.round(cx) + " " + Math.round(cy)) ;
ejmond.appendChild(ejpath);
// add start
var startdot = document.createElementNS('http://www.w3.org/2000/svg',
'circle');
startdot.classList.add("ejmond_point", "start");
startdot.setAttribute("cx", cx);
startdot.setAttribute("cy", cy);
startdot.setAttribute("r", "12");
startdot.setAttribute("fill", "#d9a");
ejmond.appendChild(startdot);
}
function continuePath (e) {
if (e.target.classList.contains("start")) {
finish(true);
} else if (!e.target.classList.contains("continue")) {
e.target.classList.add("continue");
e.target.classList.add("continue" + paths_continue.length);
let pathd = paths[paths.length - 1].getAttribute("d");
let pathcx = Number.parseFloat(e.target.getAttribute("cx"));
let pathcy = Number.parseFloat(e.target.getAttribute("cy"));
pathd += " L " + Math.round(pathcx) + " " + Math.round(pathcy);
paths[paths.length - 1].setAttribute("d", pathd);
}
}
// end mousemove
// download
function downloadsvg() {
let ejmond_clone = ejmond.cloneNode(true);
ejmond_clone.getElementsByClassName("point_g")[0].remove();
// remove mask
if (!ejform.elements.net.checked) {
ejmond_clone.querySelector(".netpath").remove();
ejmond_clone.querySelector(".netpathmask").remove();
}
// download
let a = document.createElement('a');
a.style.display = "none";
let data = ejmond_clone.outerHTML;
let file = new Blob([data], {type: "data:image/svg"});
a.href = URL.createObjectURL(file);
a.download = "ejpath.svg";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
// undo
function undo() {
if (state == 3) {
ejmond.querySelector(".start").remove();
paths[paths.length - 1].remove();
state = 0;
}
else if (state == 1) {
let last_continue = ejmond.querySelector(".continue"
+ paths_continue.length);
last_continue.classList.remove("continue" + paths_continue.length);
last_continue.classList.remove("continue");
let pathd = paths[paths.length - 1].getAttribute("d");
let last_L = pathd.lastIndexOf("L");
pathd = pathd.substring(0, last_L);
paths[paths.length - 1].setAttribute("d", pathd);
if (!paths_continue.length) {
state = 3;
}
}
else if (state == 0) {
if (paths.length) {
paths[paths.length - 1].remove();
}
}
pTypeDisable();
if (ejform.elements.net.checked) {
addMask();
}
}
// finish
function finish(funfn = false) {
if (state == 1 || funfn) {
ejmond.querySelector(".start").remove();
for (let i = 1; i <= paths_continue.length; i++) {
ejmond.querySelector(".continue" + i)
.classList.remove("continue" + i);
}
while (paths_continue.length) {
paths_continue[0].classList.remove("continue");
}
if (funfn) {
let pathd = paths[paths.length - 1].getAttribute("d");
pathd += " Z";
paths[paths.length - 1].setAttribute("d", pathd);
}
paths[paths.length - 1].setAttribute("stroke", "#444");
state = 0;
}
if (ejform.elements.net.checked) {
addMask();
}
}
// disable input radio
function pTypeDisable () {
let ejradio = ejform.querySelectorAll("input[name=pointtype]");
for (let x = 0; x < ejradio.length; x++) {
if (state == 0 && !paths.length) {
ejradio[x].removeAttribute("disabled");
} else {
ejradio[x].setAttribute("disabled", true);
}
}
}
// add line
function addLine () {
netpathmask = document.createElementNS('http://www.w3.org/2000/svg',
'mask');
netpathmask.setAttribute("id", "netmask");
netpathmask.classList.add("netpathmask");
ejmond.appendChild(netpathmask);
netpath = document.createElementNS('http://www.w3.org/2000/svg',
'path');
netpath.classList.add("netpath");
netpath.setAttribute("mask", "url(#netmask)");
netpath.setAttribute("fill", "none");
netpath.setAttribute("stroke-linecap", "round");
netpath.setAttribute("stroke-linejoin", "round");
netpath.setAttribute("stroke-dasharray", "1, 5");
netpath.setAttribute("stroke-width", "1");
netpath.setAttribute("stroke", "#777");
ejmond.appendChild(netpath);
modifyLine();
}
// modify line
function modifyLine () {
let path_d = "";
let sqrt3 = Math.sqrt(3);
let direction = ejform.elements.pointtype.value;
if ("1" == direction) {
for (let i = -5; i < 12; i++) {
path_d += "M " + (i * 36 + 24) + " "
+ Math.round(240 + sqrt3 * 36 * (-3));
path_d += "l " + (6 * 36) + " " + (sqrt3 * 36 * 6);
}
for (let i = 1; i < 18; i++) {
path_d += "M " + (i * 36 + 24) + " "
+ Math.round(240 + sqrt3 * 36 * (-3));
path_d += "l " + (-6 * 36) + " " + (sqrt3 * 36 * 6);
}
for (let i = -6; i <= 6; i++) {
path_d += "M " + 24 + " "
+ Math.round(240 + sqrt3 * 18 * i);
path_d += "h " + (12 * 36);
}
} else {
for (let i = -5; i < 12; i++) {
path_d += "M " + Math.round(240 + sqrt3 * 36 * (-3)) + " "
+ (i * 36 + 24);
path_d += "l " + (sqrt3 * 36 * 6) + " " + (6 * 36);
}
for (let i = 1; i < 18; i++) {
path_d += "M " + Math.round(240 + sqrt3 * 36 * (-3)) + " "
+ (i * 36 + 24);
path_d += "l " + (sqrt3 * 36 * 6) + " " + (-6 * 36);
}
for (let i = -6; i <= 6; i++) {
path_d += "M " + Math.round(240 + sqrt3 * 18 * i) + " "
+ 24;
path_d += "v " + (12 * 36);
}
}
netpath.setAttribute("d", path_d);
}
// add mask
function addMask () {
netpathmask.innerHTML = "";
for (let i = 0; i < paths.length; i++) {
if (i < paths.length - 1 || state == 0) {
let pathclone = paths[i].cloneNode(true);
pathclone.classList.remove("ejmond_path");
pathclone.setAttribute("fill", "#ffffff");
pathclone.setAttribute("stroke", "none");
netpathmask.appendChild(pathclone);
}
}
netpath.classList.remove("hide");
}
// remove mask
function removeMask () {
netpath.classList.add("hide");
}
</script></p>
https://ejsoon.win/
天蒼人頡:發掘好玩事物
天蒼人頡:發掘好玩事物
在线用户
正浏览此版面之用户: 没有注册用户 和 3 访客