|
|

楼主 |
发表于 2023-10-2 20:25
|
显示全部楼层
本帖最后由 马黑黑 于 2023-10-2 22:28 编辑
代码
<style>
#wrapper { margin: auto; width: 760px; height: fit-content; font: normal 16px/20px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; position: relative; }
#wrapper h2 { margin: 20px; text-align: center; font-family: sans-serif; }
#wrapper > div, #wrapper > p { margin: 8px 0; }
#wrapper > hr { margin: 18px 0; border-width: 1px 0 0 0; border-color: #eee; }
#ssShape { margin-right: 16px; font-size: 14px; }
#eCode { padding: 20px; width: calc(100% - 40px); box-sizing: border-box; overflow-x: auto; tab-size: 4; caret-color: red; white-space: pre-wrap; word-wrap: break-word; }
#eCode:not(:focus):empty::before { content: attr(data-ph); }
#svgShape, #svgPath { width: fit-content; height: fit-content; min-width: 200px; min-height: 200px; border: 1px solid gray; }
#mysite { position: absolute; right: 10px; bottom: -110px; }
svg { border: 0px solid gray; }
.rred { color: red; }
</style>
<div id="wrapper">
<h2>SVG基本图形转路径</h2>
<hr>
<p>
<label for="ssShape">选择 : </label>
<select id="ssShape" name="shape" title="更改SVG基本图形"><option value="">svg基本图形</option></select>
<input id="btnColor" type="button" value="代码着色" />
</p>
<pre id="eCode" contenteditable="true" data-ph=">> svg图形代码待选择或输入"></pre>
<p>
<label for="btnOk"></label>
<input id="btnOk" type="button" value="确定" />
</p>
<hr>
<p>原图 : </p>
<div id="svgShape"></div>
<p>路径图 : </p>
<div id="svgPath">
<svg id="svg2" width="100%" height="100%">
<path id="cPath" d="" fill="none" stroke="blue"></path>
</svg>
</div>
<p>路径数据 : </p>
<div id="pathData"></div>
<div id="mysite"><a href="http://mhh.52qingyin.cn/">马黑网站</a></div>
</div>
<script>
/* 预定义基本svg图形 */
let shapes = {
line: '<line x1="10" y1="10" x2="190" y2="190" fill="none" stroke="red" />',
polyline: '<polyline points="10 10,10 190,100 10, 190 10" fill="none" stroke="red" />',
polygon: '<polygon points="100 10,190 190, 10 190" fill="none" stroke="red" />',
rect: '<rect x="10" y="10" width="180" height="180" rx="0" ry="0" fill="none" stroke="red" />',
circle: '<circle cx="100" cy="100" r="90" fill="none" stroke="red" />',
ellipse: '<ellipse cx="100" cy="100" rx="90" ry="60" fill="none" stroke="red" />'
};
let eles = Object.keys(shapes); /* 图形标签数组 */
/*函数 : 代码着色*/
let colorCode = (code) => {
let reg = /([\'\"]([^\"]+)[\'\"])/g;
code = code.replaceAll('<', '<');
code = code.replaceAll('>', '>');
return (code.replace(reg,'<span class="rred">$1</span>'));
};
//函数 : 生成 path
let getEleData = () => {
let svgEle = document.querySelector('svg').children[0];
let tagName = svgEle.tagName.toLowerCase();
if(!eles.includes(tagName)) return;
let path, x, y, r, cx, cy, rx, ry, w, h;
switch(tagName) {
case 'line':
x = 1 * svgEle.getAttribute('x1');
y = 1 * svgEle.getAttribute('y1');
cx = 1 * svgEle.getAttribute('x2');
cy = 1 * svgEle.getAttribute('y2');
path = `M${x} ${y} L${cx} ${cy}`;
break;
case 'polyline':
case 'polygon':
path = 'M';
let points = svgEle.getAttribute('points');
let ar = points.replace(/[^\d.]/g, ',').split(',').filter(Number);
for(j = 0; j < ar.length; j ++) {
if(j <= 1) {
path += ar[j] + ' ';
}else{
path += (j % 2 === 0 ? 'L' + ar[j] : ar[j]) + ' ';
}
}
path += tagName === 'polygon' ? 'z' : '';
break;
case 'rect':
x = 1 * svgEle.getAttribute('x');
y = 1 * svgEle.getAttribute('y');
w = 1* svgEle.getAttribute('width');
h = 1* svgEle.getAttribute('height');
rx = svgEle.getAttribute('rx') ? 1 * svgEle.getAttribute('rx') : 1 * svgEle.getAttribute('ry');
ry = svgEle.getAttribute('ry') ? 1 * svgEle.getAttribute('ry') : 1 * svgEle.getAttribute('rx');
if(rx > w / 2) rx = w / 2;
if(ry > h / 2) ry = h / 2;
path = (rx === 0 || ry === 0)
? `M${x} ${y} h${w} v${h} h-${w} v-${h}`
: `M${x} ${y + ry}
a${rx} ${ry} 0 0 1 ${rx} -${ry}
h${w - rx * 2}
a${rx} ${ry} 0 0 1 ${rx} ${ry}
v${h - ry * 2}
a${rx} ${ry} 0 0 1 -${rx} ${ry}
h-${w - rx * 2}
a${rx} ${ry} 0 0 1 -${rx} -${ry}
v-${h - ry * 2}`;
break;
case 'circle':
cx = 1 * svgEle.getAttribute('cx');
cy = 1 * svgEle.getAttribute('cy');
r = 1 * svgEle.getAttribute('r');
path = `
M${cx-r} ${cy}
A${r} ${r} 0 1 1 ${(cx + r)} ${cy}
A${r} ${r} 0 1 1 ${cx-r} ${cy}
`;
break;
case 'ellipse':
cx = 1 * svgEle.getAttribute('cx');
cy = 1 * svgEle.getAttribute('cy');
rx = 1 * svgEle.getAttribute('rx');
ry = 1 * svgEle.getAttribute('ry');
path = `
M${cx-rx} ${cy}
A${rx} ${ry} 0 1 1 ${(cx + rx)} ${cy}
A${rx} ${ry} 0 1 1 ${cx-rx} ${cy}
`;
break;
}
return path;
};
/* select初始化 : 生成option菜单 */
(function() {
let hcode = '';
for(j = 0; j < eles.length; j++) {
hcode += `<option value="${j}">${eles[j]}</option>`;
}
ssShape.innerHTML += hcode;
})();
/* 确定按钮 : 生成图形 */
btnOk.onclick = () => {
if(!eCode.innerText) return;
svgShape.innerHTML = eCode.innerText;
if(getEleData()) cPath.setAttribute('d', getEleData());
pathData.innerText = cPath.getAttribute('d').replaceAll('\n',' ');
};
/* select按钮 : 选择基本图形 */
ssShape.onchange = () => {
let code = '<svg width="200" height="200">\n\t';
let idx = ssShape.options[ssShape.selectedIndex].value;
code += shapes[eles[idx]] + '\n<svg>';
eCode.innerHTML = code;
}
/* 着色按钮点击 : 代码上色 */
eCode.onfocus = btnColor.onclick = () => eCode.innerHTML = colorCode(eCode.innerText);
eCode.onmouseover = () => eCode.focus();
const resizeObserver = new ResizeObserver(() => {
svgPath.style.width = svgShape.offsetWidth + 'px';
svgPath.style.height =svgShape.offsetHeight + 'px';
});
resizeObserver.observe(svgShape);
</script>
|
评分
-
| 参与人数 1 | 威望 +50 |
金钱 +100 |
经验 +50 |
收起
理由
|
红影
| + 50 |
+ 100 |
+ 50 |
赞一个! |
查看全部评分
|