是这样的,目前我是实习,然后公司会用到一点svg所以就有这个实习,话不多说,
在慕课上找到的视频,一个svg简单的编辑器,先放一下代码。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>svg编辑器</title>
<style>
*{
margin: 0;
padding: 0;
}
#toolbox{
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 250px;
border-right: 1px solid #ccc;
}
#toolbox h2{
margin: 0;
/*padding: 0;*/
background: #EEE;
font-size: 16px;
height: 24px;
line-height: 24px;
padding: 5px 10px;
}
#toolbox form{
padding: 10px;
}
#canvas{
position: absolute;
top: 10px;
bottom: 10px;
left: 260px;
right: 10px;
border-shadow: 2px 2px 10px rgba(0,0,0,.4);
border-radius: 5px;
}
label{
display: inline-block;
width: 80px;
text-align: right;
}
</style>
</head>
<body>
<div id="toolbox">
<h2>创建图形</h2>
<form id="shape-creat">
<button type="button" create="rect">Rect</button>
<button type="button" create="circle">Circle</button>
<button type="button" create="ellipse">Ellipse</button>
<button type="button" create="line">Line</button>
</form>
<h2>图形形状</h2>
<form id="shape-attrs">
请先创建图形
</form>
<h2>图形外观变换</h2>
<form id="shape-look" disabled="disabled">
<p>
<label style="display: inline">填充</label>
<input id="fill" type="color" value="#ffffff" />
</p>
<p>
<label style="display: inline">描边</label>
<input id="stroke" type="color" value="#ff0000" />
<input id="strokeWidth" type="range" value="1" />
</p>
<p>
<label>translateX</label>
<input id="translateX" type="range" min="-400" max="400" value="0">
<label>translateY</label>
<input id="translateY" type="range" min="-400" max="400" value="0">
<label>rotate</label>
<input id="rotate" type="range" min="-180" max="180" value="0">
<label>scale</label>
<input id="scale" type="range" min="-1" max="2" value="1">
</p>
</form>
</div>
<div id="canvas">
</div>
<script>
//图形及对应默认属性
//默认公共属性
var SVG_NS = 'http://www.w3.org/2000/svg',
shapeInfo = {
rect: 'x:10,y:10,width:200,height:100,rx:0,ry:0',
circle: 'cx:200,cy:200,r:50',
ellipse: 'cx:200,cy:200,rx:80,ry:30',
line: 'x1:10,y1:10,x2:100,y2:100'
},
defaultAttrs = {
fill: '#ffffff',
stroke: '#ff0000'
},
createForm = document.getElementById('shape-creat'),
attrForm = document.getElementById('shape-attrs'),
lookForm = document.getElementById('shape-look'),
//创建svg
svg = createSVG(),
// 选中状态为空
selected = null;
//创建svg图形
function createSVG() {
var svg = document.createElementNS(SVG_NS, 'svg');
svg.setAttribute('width','100%');
svg.setAttribute('height','100%');
canvas.appendChild(svg);
return svg;
}
//给创建svg添加事件监听
svg.addEventListener('click', function (e) {
// 判断点击的svg图形是否在shapeInfo里
if (e.target.tagName.toLowerCase() in shapeInfo){
//如果是,那么select选定这个svg图形
select(e.target);
}
});
//选中
function select(shape) {
// 根据参数也就图形名从shapeInfo里拿到属性值把每一项属性以逗号分隔开
var attrs = shapeInfo[shape.tagName].split(',');
// 创建三个数组
var attr, name, value;
//清空形状属性重新生成
attrForm.innerHTML = "";
while (attrs.length){
// 循环方式以冒号分隔属性名和属性值
attr = attrs.shift().split(':');
//属性名
name = attr[0];
//值
//如果本身设置过就用设置的值,如果没有就用默认的,
//因为已经有生成的图形时,点击图形要读取已经设置的属性
value = shape.getAttribute(name) || attr[1];
//给这个图形设置控制器
createHandle(name, value);
shape.setAttribute(name, value);
}
for (name in defaultAttrs){
value = shape.getAttribute(name) || defaultAttrs[name];
shape.setAttribute(name, value);
}
selected = shape;
//更新外观变换区域的控制器
updateLookHandle();
}
//生成控制器
function createHandle(name, value) {
//创建label标签,内容为属性名称
var label = document.createElement('label');
label.textContent = name;
//创建input标签,设置属性
var handle =document.createElement('input');
handle.setAttribute('name',name);
handle.setAttribute('type','range');
handle.setAttribute('min', 0);
handle.setAttribute('max', 800);
handle.setAttribute('value',value);
//最后把label和handle添加到shape-attr表单里
attrForm.appendChild(label);
attrForm.appendChild(handle);
}
function updateLookHandle() {
fill.value = selected.getAttribute('fill');
stroke.value = selected.getAttribute('stroke');
var t = decodeTransform(selected.getAttribute('transform'));
translateX.value = t ? t.tx : 0;
translateY.value = t ? t.ty : 0;
rotate.value = t ? t.rotate : 0;
scale.value = t ? t.scale : 1;
}
//给创建表单添加事件监听
createForm.addEventListener('click',function(e) {
if (e.target.tagName.toLowerCase() === 'button'){
// 点哪个按钮生成哪个图形
create(e.target.getAttribute('create'));
}
});
//给形状表单添加事件监听
// 在input框里监听input事件,
attrForm.addEventListener('input',function (e) {
if (e.target.tagName.toLowerCase() !== 'input') return;
if (!selected) return;
var handle = e.target;
selected.setAttribute(handle.name,handle.value);
});
//给图形外观变换添加事件监听
// 在input框里监听input事件,
lookForm.addEventListener('input',function (e) {
// 监听input事件具体到哪个input框
if (e.target.tagName.toLowerCase() !== 'input') return;
if (!selected) return;
selected.setAttribute('fill',fill.value);
selected.setAttribute('stroke',stroke.value);
selected.setAttribute('stroke-width',strokeWidth.value);
selected.setAttribute('transform',encodeTransform({
tx: translateX.value,
ty: translateY.value,
scale: scale.value,
rotate: rotate.value,
}));
});
function create(name) {
var shape = document.createElementNS(SVG_NS,name);
svg.appendChild(shape);
select(shape);
}
function decodeTransform(transString) {
var match = /translate\((\d+),(\d+)\)\srotate\((\d+)\)\sscale\((\d+)\)/.exec(transString);
return match ? {
tx: +match[1],
ty: +match[2],
rotate: +match[3],
scale: +match[4]
} : null;
}
function encodeTransform(transObject) {
return ['translate(',transObject.tx,',',transObject.ty,')',
'rotate(',transObject.rotate,')',
'scale(',transObject.scale,')'].join('');
}
</script>
</body>
</html>
这是最终成果,不过我要说的是代码早早就写好了,但是生成了几个不同大小形状样式的图形之后,我再通过点击图形去选中的时候,控制器都变成了默认值,
然后因为我是一个真·小白,所以我正儿八经的困扰了一天,然后实在没辙去问老师,
老师说推测有个方法没调用,我说视频看n遍上边有的我都有,但是视频上就能出效果,我这没有,
老师说传值可能没传到,我试了试,在选中方法里的值最后都是正确的,也都传了过去,
这个时候我想只有一种可能就是选中最后一步,渲染的时候,我当时的代码是这个亚子的
然后,这渲染传值没毛病鸭,该有的都有了,正当我一筹莫展,上下滚动时,我看到了我view代码
看,input标签的属性,,,顺序!value在最后一位,虽然我渲染的value的值也不是在外观这里,是在形状那里,
但是我抱着死马当活马医的态度,试了一试,于是
我把value传值放到了最后,成功实现点击svg图片赋值给控制器,
这算是一个坑了吧,我现在还不知道是因为啥,以后总会明白的,先记小本本上,
ps:有没有大佬懂这到底是为啥啊,浪费我一天时间,经理都要嫌我菜了,(虽然真的菜/小声比比)