开发者

Raphael SVG VML Implement Multi Pivot Points for Rotation

Over the last two days I've effectively figured out how NOT to rotate Raphael Elements.

Basically I am trying to implement a multiple pivot points on element to rotate it by mouse.

When a user enters rotation mode 5 pivots are created. One for each corner of the bounding box and one in the center of the box.

When the mouse is down and moving it is simple enough to rotate around the pivot using Raphael elements.rotate(degrees, x, y) and calculating the degrees based on the mouse positions and atan2 to the pivot point.

The problem arises after I've rotated the element, bbox, and the other pivots. There x,y position in the same only there viewport is different.

In an SVG enabled browser I can create new pivot points based on matrixTransformation and getCTM. However after creating the first set of new pivots, every rotation after the pivots get further away from the transformed bbox due to rounding errors.

Raphael SVG VML Implement Multi Pivot Points for Rotation

The above is not eve开发者_StackOverflown an option in IE since in is VML based and cannot account for transformation.

Is the only effective way to implement element rotation is by using rotate absolute or rotating around the center of the bounding box?

Is it possible at all the create multi pivot points for an object and update them after mouseup to remain in the corners and center of the transformed bbox?

UPDATE: I've attempted to use jQuery offset to find the pivot after it's been rotated, and to use that offset location as the pivot point.

Demo site ... http://weather.speedfetishperformance.com/dev/raphael/rotation.html


The best cross-browser way I can think of to do what you want is to implement the rotation yourself rather than let SVG do it. Rotating x,y coordinates is fairly simple and I've been using this (tcl) code whenever I need to do 2D rotation: Canvas Rotation.

The upside to this is you have maximum control of the rotation since you're doing it manually. This solves the problems you're having trying to guess the final coordinates after rotation. Also, this should be cross browser compatible.

The downside is you have to use paths. So no rects (though it should be easy to convert them to paths) or ellipses (a little bit harder to convert to path but doable). Also, since you're doing it manually, it should be slower than letting SVG do it for you.

Here's a partial implementation of that Tcl code in javascript:

first we need a regexp to tokenize SVG paths:

var svg_path_regexp = (function(){
  var number = '-?[0-9.]+';
  var comma = '\s*[, \t]\s*';
  var space = '\s+';
  var xy = number + comma + number;
  var standard_paths = '[mlcsqt]';
  var horiz_vert = '[hv]\s*' + number;
  var arc = 'a\s*' + xy + space + number + space + xy + space + xy;
  var OR = '\s*|';

  return new RegExp(
    standard_paths +OR+
    xy +OR+
    horiz_vert +OR+
    arc,

    'ig'
  );
})();

now we can implement the rotate function:

function rotate_SVG_path (path, Ox, Oy, angle) {
  angle = angle * Math.atan(1) * 4 / 180.0; // degrees to radians

  var tokens = path.match(svg_path_regexp);

  for (var i=0; i<tokens.length; i++) {
    var token = tokens[i].replace(/^\s+|\s+$/g,''); // trim string

    if (token.match(/\d/)) { // assume it's a coordinate
      var xy = token.split(/[, \t]+/);
      var x = parseFloat(xy[0]);
      var y = parseFloat(xy[1]);
      x = x - Ox;  // Shift to origin
      y = y - Oy;
      var xx = x * Math.cos(angle) - y * Math.sin(angle); // Rotate
      var yy = x * Math.sin(angle) + y * Math.cos(angle);
      x = xx + Ox; // Shift back
      y = yy + Oy;

      token = x + ',' + y;
    }
    else if (token.match(/^[hv]/)) {
      // handle horizontal/vertical line here
    }
    else if (token.match(/^a/)) {
      // handle arcs here
    }

    tokens[i] = token;
  }
  return tokens.join('');
}

The above rotate function implements everything except horizontal/vertical lines (you need to keep track of previous xy value) and arcs. Neither should be too hard to implement.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜