是这样的,目前我是实习,然后公司会用到一点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遍上边有的我都有,但是视频上就能出效果,我这没有,

老师说传值可能没传到,我试了试,在选中方法里的值最后都是正确的,也都传了过去,

这个时候我想只有一种可能就是选中最后一步,渲染的时候,我当时的代码是这个亚子的学svg的第一个坑,来自前端小白

然后,这渲染传值没毛病鸭,该有的都有了,正当我一筹莫展,上下滚动时,我看到了我view代码

学svg的第一个坑,来自前端小白

看,input标签的属性,,,顺序!value在最后一位,虽然我渲染的value的值也不是在外观这里,是在形状那里,

但是我抱着死马当活马医的态度,试了一试,于是

学svg的第一个坑,来自前端小白

我把value传值放到了最后,成功实现点击svg图片赋值给控制器,

这算是一个坑了吧,我现在还不知道是因为啥,以后总会明白的,先记小本本上,

ps:有没有大佬懂这到底是为啥啊,浪费我一天时间,经理都要嫌我菜了,(虽然真的菜/小声比比)

相关文章: