colinmeinke / wilderness

An SVG animation API
https://wilderness.now.sh
MIT License
154 stars 8 forks source link

Applying matrix to points #61

Closed dalisoft closed 7 years ago

dalisoft commented 7 years ago

How to apply mattix transformation to points. Even it line or moveto. I first think of rotate and it worked fine, but first i need skew, second i have problem while parsing transform attribute, so i want do like this.

  1. Get transform matrix someway.
  2. Apply matrix to points.
  3. Flat matrix and remove attribute transform.

Thanks for very best library. I use it last 3-4month and its works amazing

colinmeinke commented 7 years ago

I don't think I understand. Can you provide a very short and simple code example of how that might look in wilderness?

dalisoft commented 7 years ago

I provide information. I do demo when have time.

Applying matrix like rotate to points

dalisoft commented 7 years ago

See commented lines for what i want, please http://codepen.io/dalisoft/pen/XpKMpo Sorry for not real pen (what i need that demo)

colinmeinke commented 7 years ago

I don't understand what the output of a getMatrix function should be?

<path d="M0,0L10,10" stroke="red" fill="none">
const matrix = getMatrix(document.querySelector('path'))

console.log(matrix)

// ?

I also don't understand what a matrix manipulation should do?

shape({
  type: 'path',
  d: document.querySelector('path').getAttribute('d'),
  matrix: ['flatten', matrix]
})

What would the points shape look like for this?

Help me understand!

dalisoft commented 7 years ago

https://gist.github.com/timo22345/9413158

This implementation for this js

colinmeinke commented 7 years ago

Give me the tl;dr...

dalisoft commented 7 years ago

i try. for users who cannot manipulate transform attribute of svg, especially for "Group" elements this feature is very useful.

colinmeinke commented 7 years ago

I can't see the benefit in this. Manipulations in Wilderness are applied through manipulation properties on the plain shape object.

dalisoft commented 7 years ago
import  toPoints from 'svg-points'; // maybe wrong syntax
var getMatrix = function getMatrix(pathDOM, svgDOM) {
            svgDOM = svgDOM || pathDOM.ownerSVGElement;
            return pathDOM.getTransformToElement !== undefined ? pathDOM.getTransformToElement(
                svgDOM) : (function () {
                return svgDOM !== null ? svgDOM.getScreenCTM().inverse().multiply(
                    pathDOM.getScreenCTM()) : {
                    a: 1,
                    b: 0,
                    c: 0,
                    d: 1,
                    e: 0,
                    f: 0
                };
            }
                ())
        };
        var setMatrix = function setMatrix(point, m, pt) {
            if (point.x !== undefined && point.y !== undefined) {
                pt.x = point.x;
                pt.y = point.y;
                var p = pt.matrixTransform(m),
                curve = point.curve,
                type;
                point.x = p.x;
                point.y = p.y;
                if (curve) {
                    type = curve.type;
                    if (type === 'quadratic' || type === 'cubic') {
                        var p2 = setMatrix({
                                x: curve.x1,
                                y: curve.y1
                            }, m, pt);
                        point.curve.x1 = p2.x;
                        point.curve.y1 = p2.y;
                    }
                    if (type === 'cubic') {
                        var p3 = setMatrix({
                                x: curve.x2,
                                y: curve.y2
                            }, m, pt);
                        point.curve.x2 = p3.x;
                        point.curve.y2 = p3.y;
                    }
                }
            }
            return point;
        };
        var flatten = function flatten(path, points) {
            if (path && path instanceof SVGPathElement) {
                var svgDOM = path.ownerSVGElement;
                var matrix = getMatrix(path, svgDOM);
                var pt = svgDOM.createSVGPoint();
                points = points || toPoints({
                        type: "path",
                        d: path.getAttribute("d")
                    });
                points = points.map(function (pp, i) {
                        return setMatrix(pp, matrix, pt);
                    });
                path.removeAttribute("transform");
                path.setAttribute("d", toPath(points));
                return {
                    path: path,
                    points: points
                }
            }
        };

Usage:

<path id="one" d="..." transform="rotate(45deg)"/>
var $ = document.querySelector.bind(document);
      flatten($('#one')) // or flatten($('#one'), points) if points available, optional