snap.format and isFunc

51 views
Skip to first unread message

Vincent Boulet

unread,
Nov 7, 2022, 8:40:01 AM11/7/22
to Snapsvg
Hi, 

I've got a square cropped on his bottom-right angle.

Snap.format("m {mx},{my} h {dim.x0} v {dim.y0} l -15,15 h -{dim.x1} v -{dim.y1} z",
   {
         mx: 0,
         my: 0,
         dim: {
              x0: 100,
              x1: 85,
              y0: 55,
              y1: 70
          }
      })

My question is : can I calc the new dim of the right v line and bottom h line based on x0 and y1 dim like this :

Snap.format("m {mx},{my} h {dim.x0} v {dim.y1}-15 l -15,15 h -{dim.x0}+15 v -{dim.y1} z",
   {
         mx: 0,
         my: 0,
         dim: {
              x0: 100,
              y0: 70
          }
      })

The syntaxe {dim.y1}-15 doesn't work, neither {dim.y1-15}. 

I saw in the src code that the replace function (https://github.com/adobe-webplatform/Snap.svg/blob/master/src/svg.js (line 216)) has isFunc param.

Is it possible to sepcify a function in the dim obj ?

Vincent Boulet

unread,
Nov 8, 2022, 10:33:57 AM11/8/22
to Snapsvg
Hi, 

I rewrite the Snap.format function with a new regex that can support group match with this format {{dim.x0}-15} and evaluate the arithmetic operation after dim.x0 replace.
Here is the code :

Snap.format = (function () {
  var tokenRegex = /\{(.[^{]+)\}/g,  // new regex to match {{dim.x0}-15} group
    objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, // matches .xxxxx or ["xxxxx"] to run over object properties

// no change on replacer function
  replacer = function (all, key, obj) {
    var res = obj;
    key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) {
      name = name || quotedName;
        if (res) {
          if (name in res) {
            res = res[name];
          }
          typeof res == "function" && isFunc && (res = res());
       }
     });
    res = (res == null || res == obj ? all : res) + "";
    return res;
  };

  return function (str, obj) {
    return Str(str).replace(tokenRegex, function (all, key) {
      if (!key.match(tokenRegex)) {
        return replacer(all, key, obj);
      } else {
        var arithmeticExp = key.replace(tokenRegex, function(match, group) {
          return replacer(match, group, obj);
        });
        return eval(arithmeticExp);
      }
    });
  };
})();

With this update you can have the path : 

"m {mx},{my} h {dim.x0} v {{dim.y0}-15} l -15,15 h -{{dim.x0}-15} v -{dim.y0} z",
   {
         mx: 0,
         my: 0,
         dim: {
              x0: 100,
              y0: 70
          }
      }

evaluate like that : "m 0,0 h 100 v 55 l -15,15 h -85 v -70 z"
Reply all
Reply to author
Forward
0 new messages