How to use Jointjs and SVG to draw element tools

2019-07-14 12:37发布

问题:

I'm new to javascript and SVG and I have no graphical programming background and this is my first project using all of those. So I started to make a custom element just like Mike Goodwin answer proposed and I ended with this code after editing it:

joint.shapes.tools.tooledElement = joint.shapes.basic.Generic.extend({

    toolMarkup: [
        '<g class="element-tools">',
            '<g class="element-tool-remove"><circle fill="red" r="11" stroke="black" stroke-width="1"/>',
                '<path transform="scale(.7) translate(-16, -16)" stroke="black" stroke-width="1" d="M24.778,21.419 19.276,15.917 24.777,10.415 21.949,7.585 16.447,13.087 10.945,7.585 8.117,10.415 13.618,15.917 8.116,21.419 10.946,24.248 16.447,18.746 21.948,24.248z"/>',
                '<title>Remove this element from the model</title>',
            '</g>',
            '<g class="element-tool-link"><circle fill="green" r="11" cx="160" cy="40" stroke="black" stroke-width="1"/>',
                '<path transform="scale(.7) translate(-16, -16)"/>',
                '<title>creates a new link</title>',
            '</g>',
        '</g>'
    ].join(''),

    defaults: joint.util.deepSupplement({
        attrs: {
            text: { 'font-weight': 400, 'font-size': 'small', fill: 'black', 'text-anchor': 'middle', 'ref-x': .5, 'ref-y': .5, 'y-alignment': 'middle' }
        }
    }, joint.shapes.basic.Generic.prototype.defaults)

});

Which works properly. Now I would like to draw some line on the green circle and to make the red circle into a red square. To achieve this I looked at this tutorial on paths to draw and this tutorial on basic shapes. But if I try to make a line on the green circle like this:

'<path transform="scale(.7) translate(-16, -16)" stroke="black" stroke-width="1" d="x y L 10 10 " />' 

it won't draw anything. They do say " If your cursor already was somewhere on the page, no line is drawn to connect the two places." and that's why I omitted the "M" from path.

So here comes the first question: How can I draw the line on the center of the green circle without starting from the previous last point defined on any other path?

To make the red square I tried the exactly example from the second tutorial changing the fill (as a test):

//first line to test
<rect x="10" y="10" width="30" height="30" stroke="black" fill="red" stroke-width="5"/>

or

//second line to test
<rect x="60" y="10" rx="10" ry="10" width="30" height="30" stroke="black" fill="red" stroke-width="5"/>

The result of the first line would be the element at which the tools are being used to be draw again above itself like this:

And the second line would end up on nothing being show.

So here are the next questions:

Why did the results from the first line got like that? and How can I change the red circle into any other shape?

UPDATE: About the line draw:

'<path transform="scale(.7) translate(-16, -16)" stroke="black" stroke-width="1" d="M150 150 H 5 V 5 H 5 z" />'

If I use this code for example, this is the result:

'<path transform="scale(.7) translate(-16, -16)" stroke="black" stroke-width="1" d="M150 150 H 5 V 5 H 5 z" />'

If I use this other code then the result will be:

The tutorial led me to believe that M is defining the start point but changing the translate(-16, -16) to something else made the correct start point be possible. So its the translate attribute combined with M that set the starting point.

回答1:

The first question as been answered on update. As for the second question (concerning the red square conflicting with the element shape inside a rect) this was my work around:

Use the path to draw the tools elements instead of using basic shapes, that way it won't conflict with the element shape.

Example:

'<g class="element-tool-link"><circle fill="green" r="11" cx="160" cy="40" stroke="black" stroke-width="1"/>',
    '<path transform="scale(.7) translate(-16, -16)"/>',
    '<title>creates a new link</title>',
'</g>'

would turn into:

'<g class="element-tool-link">',
    '<path d="M33 0 a 11 11 0 1 0 0.0001 0z " stroke="black" fill="lightblue" stroke-width="1"/>',
    '<path transform="scale(.7) " stroke="black" stroke-width="1" d="M58,16  H 37 "/>',
    '<title>creates a new link</title>',
'</g>'

where '<path d="M33 0 a 11 11 0 1 0 0.0001 0z " stroke="black" fill="lightblue" stroke-width="1"/>' defines a circle shape.