Jump to content
GreenSock

Catalin R.

DrawSVG with variables instead of values

Recommended Posts

Hi,

I have a rotator and I want to draw a dashed stroke between icons.

How can I keep the dashed stroke with drawSVG plugin?

And, how can I use variables instead of values to get stroke only between icons?

I need something like this:

TweenMax.set(circle, {drawSVG:"variable1 variable2"});

How can I use modifier plugin for this?

Thanks!

 

circle2.jpg

circle1.jpg

Link to comment
Share on other sites

Hi @DevSaver:)

 

For a dashed line and DrawSVG, you'll need to use a mask. I wrote about that here:

 

 

Using variable shouldn't be any problem. You could do something like this:

 

See the Pen BrWLjK by PointC (@PointC) on CodePen

 

You may also want to take a look at our big 'circle start point' thread.

 

 

Hopefully that helps. Happy tweening.

:)

 

  • Like 3
Link to comment
Share on other sites

Hi PointC,

I thank you for help!

It doesn't help a mask into my project, because I can change the background and the rect element has fill: #fff;

Link to comment
Share on other sites

I'm not sure I follow. Do you mean the white rectangle in my demo? If so, that can be removed (or change the color) and the mask will still be fine. The white stroke in the mask is just what will be revealed, but it doesn't have to be over white.

 

See the Pen rdyWKV by PointC (@PointC) on CodePen

 Is that what you meant?

  • Like 3
Link to comment
Share on other sites

As usual, @PointC is right on. For the fun of it, I made a little dynamic demo that'll plot things around a circle and show you how to convert angles into the drawSVG % values so that you can do your variables accordingly: 

 

See the Pen vRxXyY?editors=0010 by GreenSock (@GreenSock) on CodePen

 

Just click on any of the green dots and you should see what I mean. 

 

That assumes you want to always start the drawing at the top. You could change that, of course. Hopefully this gets you headed in the right direction. In any case, a mask is likely what you need. 

 

Happy tweening!

  • Like 5
Link to comment
Share on other sites

@GreenSock - somebody's getting fancy today. Nice! I've been 'GreenShocked' ;)

 

I was just about to tag you into this thread. After I posted my demo, I looked at it in Edge 41 and I'm seeing some weirdness. Your demo is doing the same funkiness as mine. The line sometimes draws a bit, other times not. If you resize the window, it then suddenly appears. Maybe this is a CodePen/Edge issue, but thought I'd mention it and see if you can confirm?

 

I'm using Edge 41.16299.248.0.

  • Like 2
  • Haha 1
Link to comment
Share on other sites

Great catch, Craig. That's definitely a browser rendering bug. I worked around it now by adding this to the tween: strokeMiterlimit:Math.random(). Silly, I know, but changing the strokeMiterlimit is a way to force the browser to re-render the path/mask. Seems to work well for me now. I'll add this fix to DrawSVGPlugin itself in the next release as well. 

  • Like 3
Link to comment
Share on other sites

Yep - your demo seems fine in Edge now. I threw a rotation:0.1 onto my demo and that seemed to solve things too. Weirdly, everything works correctly in IE11 without any extra fixes so I assumed Edge would be okay, but that's what I get for assuming. Edge is really starting to get fussy.

  • Like 3
Link to comment
Share on other sites

Hello everyone,

Thanks for your help!

My rotator looks nice now!

All the best!

r1.jpg

  • Like 1
Link to comment
Share on other sites

Hello again,

 

To get this stroke for the rotator I've used in html multiple circles inside svg element and after I've used drawSVG plugin to obtain the right stroke.

Now, I want to create and append elements and masks with jQuery and after to animate them with drawSVG plugin.

I've created the elements but I couldn't animate them! Only the original element is animated.

Can anybody help me, please?

 

The mark-up:

 

<svg version="1.1" class="svg-rotator" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500">
            <defs>
                  <mask id="theMask1">
                         <circle class="reveal1" r="250" fill="none" cx="250" cy="250" stroke="#fff" stroke-width="6"/>
                  </mask>
            </defs>

            <g class="maskReveal" mask="url(#theMask1)">
                  <circle class="circle" cx="250" cy="250" r="250" fill="none" stroke="#ccc" stroke-width="6" stroke-dasharray="6"/>
            </g>

</svg>

 

Code in JS:

 

var recentDesf = $(svgRot).find("defs");

                for (var i = 2; i < rotatorLiSize + 1; i++) {
                    var newGroup = $("<g class='maskReveal' mask='url(#theMask"+i+")'><circle class='circle' cx='250' cy='250' r='250' fill='none' stroke='#ccc' stroke-width='6' stroke-dasharray='6' /></g>");
                    svgRot.append(newGroup);

                    var newMask = $("<mask id='theMask"+i+"'><circle class='reveal"+i+"' r='250' fill='none' cx='250' cy='250' stroke='#fff' stroke-width='6' /></mask>");
                    recentDesf.append(newMask)
                }

 

 

TweenMax.set($(this).closest(".top-side").find(".reveal" + idListItem), {
                        drawSVG: start + "%" + " " + end + "%"
                    });

 

Thanks a lot!

 

Link to comment
Share on other sites

Sorry, you've lost me now. I'm not sure you'd need multiple dashed circles and masks unless I've completely misunderstood the desired outcome here.

 

Do you happen to have a demo we could take a look at? Thanks.

:)

 

  • Like 2
Link to comment
Share on other sites

Yes, I need multiple dashed circles and masks. In html I have only one circle and one mask, but I've create and appended them in JS.

The problem is drawSVG plugin animate only one circle (the already existing in html).

Sorry, I can't show a link to the project!

Thanks again!

Link to comment
Share on other sites

You don't have to post your "real" project at all - just a super-simple reduced test case in codepen that shows the general concept(s). That'll exponentially increase the likelihood that you'll get a relevant, prompt answer. 

 

I don't really understand why you couldn't create as many circles and as many drawSVG animations as you want in your project. Maybe you just accidentally used the same mask for all of them instead of creating a new mask for each one? Again, a demo will really help clear this up. 

 

EDIT: I see that your JS does show that you're creating a mask for each circle, so that's good. 

  • Like 2
Link to comment
Share on other sites

Hi,

I've tried to create a codepen but I don't have access to all plugins.

The code is long in JS, a lot of variables, tweens and functions.

I've created in JS groups and masks. The problem is drawSVG plugin doesn't work on elements created by me in JS.

DrawSVG works only on existing element.

See the Pen BrZKGJ by ZenTao (@ZenTao) on CodePen

See the result:

 

rotator.jpg

Link to comment
Share on other sites

You can use any of the bonus plugins on codepen for free using these special URLs: 

See the Pen OPqpRJ by GreenSock (@GreenSock) on CodePen

 

And you forgot to load TweenMax :)

 

I bet the problem has to do with how you're creating your SVG elements and that they're not in the proper namespace. SVG elements are a different beast and for security reasons, most browsers prevent JS from interacting with it if it's not in the proper namespace. You must use createElementNS() instead of createElement(). Here's a function I made for myself that'll handle that (and a lot more) for me: 

 

function createElement(type, options) {
    options = options || {};
    var ns = (options.svg || "|path|circle|rect|g|line|polygon|polyline|text|ellipse|defs|use|svg|".indexOf("|" + type + "|") !== -1) ? "http://www.w3.org/2000/svg" : "http://www.w3.org/1999/xhtml",
        container = options.container,
        attr = options.attr,
        reg = /([a-z])([A-Z])/g,
        element = document.createElementNS ? document.createElementNS(ns, type) : document.createElement(type);
    if (container) {
        if (typeof(container) === "string") {
            container = document.querySelector(container);
        }
        container.appendChild(element);
    }
    if (type === "svg") {
        element.setAttribute("xmlns", ns);
        element.setAttribute("xmlns:xlink", ns);
    }
    if (options.css) {
        element.style.cssText = options.css;
    }
    if (attr) {
        for (var p in attr) {
            element.setAttributeNS(null, p.replace(reg, "$1-$2").toLowerCase(), attr[p]);
        }
    }
    return element;
}

//example usage:
var element = createElement("circle", {
    container:"#id",
    css:"stroke-width:3; stroke: red;", 
    attr:{
        cx:100,
        cy:150,
        r:50,
    }
});

 

I hope that helps.

  • Like 3
Link to comment
Share on other sites

Thank you very much!

Problem solved! :-)

  • Like 1
Link to comment
Share on other sites

Second time this week I've been 'GreenShocked' by @GreenSock;)

 

Just FYI - I have stolen your SVG creation function. :ph34r:

 

 

  • Like 1
Link to comment
Share on other sites

5 minutes ago, PointC said:

Second time this week I've been 'GreenShocked' by @GreenSock;)

 

Just FYI - I have stolen your SVG creation function. :ph34r:

 

 

LOL. Yeah, please do steal it - that's what it's there for. Warning: that's an un-tested edited version of something I've used in the past. I made it better to post here, so let me know if it breaks for you. 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×