How to use transformation-matrix - 10 common examples

To help you get started, we’ve selected a few transformation-matrix examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github LLK / scratch-svg-renderer / src / transform-applier.js View on Github external
const parts = transform.split(/\(\s*/);
        const command = parts[0].trim();
        const v = parts[1].split(/[\s,]+/g);
        // Convert values to floats
        for (let j = 0; j < v.length; j++) {
            v[j] = parseFloat(v[j]);
        }
        switch (command) {
        case 'matrix':
            matrix = Matrix.compose(matrix, {a: v[0], b: v[1], c: v[2], d: v[3], e: v[4], f: v[5]});
            break;
        case 'rotate':
            matrix = Matrix.compose(matrix, Matrix.rotateDEG(v[0], v[1] || 0, v[2] || 0));
            break;
        case 'translate':
            matrix = Matrix.compose(matrix, Matrix.translate(v[0], v[1] || 0));
            break;
        case 'scale':
            matrix = Matrix.compose(matrix, Matrix.scale(v[0], v[1] || v[0]));
            break;
        case 'skewX':
            matrix = Matrix.compose(matrix, Matrix.skewDEG(v[0], 0));
            break;
        case 'skewY':
            matrix = Matrix.compose(matrix, Matrix.skewDEG(0, v[0]));
            break;
        default:
            log.error(`Couldn't parse: ${command}`);
        }
    }
    return matrix;
};
github LLK / scratch-svg-renderer / src / transform-applier.js View on Github external
const _parseTransform = function (domElement) {
    let matrix = Matrix.identity();
    const string = domElement.attributes && domElement.attributes.transform && domElement.attributes.transform.value;
    if (!string) return matrix;
    // https://www.w3.org/TR/SVG/types.html#DataTypeTransformList
    // Parse SVG transform string. First we split at /)\s*/, to separate
    // commands
    const transforms = string.split(/\)\s*/g);
    for (const transform of transforms) {
        if (!transform) break;
        // Command come before the '(', values after
        const parts = transform.split(/\(\s*/);
        const command = parts[0].trim();
        const v = parts[1].split(/[\s,]+/g);
        // Convert values to floats
        for (let j = 0; j < v.length; j++) {
            v[j] = parseFloat(v[j]);
        }
github chrvadala / react-svg-pan-zoom / src / features / zoom.js View on Github external
export function fitSelection(value, selectionSVGPointX, selectionSVGPointY, selectionWidth, selectionHeight) {
  let {viewerWidth, viewerHeight} = value;

  let scaleX = viewerWidth / selectionWidth;
  let scaleY = viewerHeight / selectionHeight;

  let scaleLevel = Math.min(scaleX, scaleY);

  const matrix = transform(
    scale(scaleLevel, scaleLevel),                      //2
    translate(-selectionSVGPointX, -selectionSVGPointY) //1
  );

  if(isZoomLevelGoingOutOfBounds(value, scaleLevel / value.d)) {
    // Do not allow scale and translation
    return set(value, {
      mode: MODE_IDLE,
      startX: null,
      startY: null,
      endX: null,
      endY: null
    });
  }

  return set(value, {
    mode: MODE_IDLE,
    ...limitZoomLevel(value, matrix),
github chrvadala / react-svg-pan-zoom / src / features / interactions-touch.js View on Github external
const previousPointDistance = hasPinchPointDistance(value) ? value.pinchPointDistance : pinchPointDistance;
  const svgPoint = getSVGPoint(value, (x1 + x2) / 2, (y1 + y2) / 2);
  let distanceFactor = pinchPointDistance/previousPointDistance;

  if (isZoomLevelGoingOutOfBounds(value, distanceFactor)) {
    // Do not change translation and scale of value
    return value;
  }

  if (event.cancelable) {
    event.preventDefault();
  }

  let matrix = transform(
    fromObject(value),
    translate(svgPoint.x, svgPoint.y),
    scale(distanceFactor, distanceFactor),
    translate(-svgPoint.x, -svgPoint.y)
  );

  return set(value, set({
    mode: MODE_ZOOMING,
    ...limitZoomLevel(value, matrix),
    startX: null,
    startY: null,
    endX: null,
    endY: null,
    prePinchMode: value.prePinchMode ? value.prePinchMode : value.mode,
    pinchPointDistance
  }));
}
github chrvadala / react-svg-pan-zoom / src / features / interactions-touch.js View on Github external
let distanceFactor = pinchPointDistance/previousPointDistance;

  if (isZoomLevelGoingOutOfBounds(value, distanceFactor)) {
    // Do not change translation and scale of value
    return value;
  }

  if (event.cancelable) {
    event.preventDefault();
  }

  let matrix = transform(
    fromObject(value),
    translate(svgPoint.x, svgPoint.y),
    scale(distanceFactor, distanceFactor),
    translate(-svgPoint.x, -svgPoint.y)
  );

  return set(value, set({
    mode: MODE_ZOOMING,
    ...limitZoomLevel(value, matrix),
    startX: null,
    startY: null,
    endX: null,
    endY: null,
    prePinchMode: value.prePinchMode ? value.prePinchMode : value.mode,
    pinchPointDistance
  }));
}
github chrvadala / react-svg-pan-zoom / src / features / pan.js View on Github external
export function pan(value, SVGDeltaX, SVGDeltaY, panLimit = undefined) {

  let matrix = transform(
    fromObject(value),              //2
    translate(SVGDeltaX, SVGDeltaY) //1
  );

  // apply pan limits
  if (panLimit) {
    let [{x: x1, y: y1}, {x: x2, y: y2}] = applyToPoints(matrix, [
      {x: value.SVGMinX + panLimit, y: value.SVGMinY + panLimit},
      {x: value.SVGMinX + value.SVGWidth - panLimit, y: value.SVGMinY + value.SVGHeight - panLimit}
    ]);

    //x limit
    let moveX = 0;
    if (value.viewerWidth - x1 < 0)
      moveX = value.viewerWidth - x1;
    else if (x2 < 0) moveX = -x2;
github chrvadala / react-svg-pan-zoom / src / features / interactions-touch.js View on Github external
const y2 = event.touches[1].clientY - Math.round(top);
  const pinchPointDistance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
  const previousPointDistance = hasPinchPointDistance(value) ? value.pinchPointDistance : pinchPointDistance;
  const svgPoint = getSVGPoint(value, (x1 + x2) / 2, (y1 + y2) / 2);
  let distanceFactor = pinchPointDistance/previousPointDistance;

  if (isZoomLevelGoingOutOfBounds(value, distanceFactor)) {
    // Do not change translation and scale of value
    return value;
  }

  if (event.cancelable) {
    event.preventDefault();
  }

  let matrix = transform(
    fromObject(value),
    translate(svgPoint.x, svgPoint.y),
    scale(distanceFactor, distanceFactor),
    translate(-svgPoint.x, -svgPoint.y)
  );

  return set(value, set({
    mode: MODE_ZOOMING,
    ...limitZoomLevel(value, matrix),
    startX: null,
    startY: null,
    endX: null,
    endY: null,
    prePinchMode: value.prePinchMode ? value.prePinchMode : value.mode,
    pinchPointDistance
  }));
github chrvadala / react-svg-pan-zoom / src / features / zoom.js View on Github external
export function fitSelection(value, selectionSVGPointX, selectionSVGPointY, selectionWidth, selectionHeight) {
  let {viewerWidth, viewerHeight} = value;

  let scaleX = viewerWidth / selectionWidth;
  let scaleY = viewerHeight / selectionHeight;

  let scaleLevel = Math.min(scaleX, scaleY);

  const matrix = transform(
    scale(scaleLevel, scaleLevel),                      //2
    translate(-selectionSVGPointX, -selectionSVGPointY) //1
  );

  if(isZoomLevelGoingOutOfBounds(value, scaleLevel / value.d)) {
    // Do not allow scale and translation
    return set(value, {
      mode: MODE_IDLE,
      startX: null,
      startY: null,
      endX: null,
      endY: null
    });
  }

  return set(value, {
github chrvadala / react-svg-pan-zoom / es / features / pan.js View on Github external
export function pan(value, SVGDeltaX, SVGDeltaY) {
  var panLimit = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;


  var matrix = transform(fromObject(value), //2
  translate(SVGDeltaX, SVGDeltaY) //1
  );

  // apply pan limits
  if (panLimit) {
    var _applyToPoints = applyToPoints(matrix, [{ x: panLimit, y: panLimit }, { x: value.SVGWidth - panLimit, y: value.SVGHeight - panLimit }]),
        _applyToPoints2 = _slicedToArray(_applyToPoints, 2),
        _applyToPoints2$ = _applyToPoints2[0],
        x1 = _applyToPoints2$.x,
        y1 = _applyToPoints2$.y,
        _applyToPoints2$2 = _applyToPoints2[1],
        x2 = _applyToPoints2$2.x,
        y2 = _applyToPoints2$2.y;

    //x limit
github LLK / scratch-svg-renderer / src / transform-applier.js View on Github external
if (focal) focal = Matrix.applyToPoint(matrix, focal);
    } else {
        const dot = (a, b) => (a.x * b.x) + (a.y * b.y);
        const multiply = (coefficient, v) => ({x: coefficient * v.x, y: coefficient * v.y});
        const add = (a, b) => ({x: a.x + b.x, y: a.y + b.y});
        const subtract = (a, b) => ({x: a.x - b.x, y: a.y - b.y});

        // The line through origin and gradientPerpendicular is the line at which the gradient starts
        let gradientPerpendicular = Math.abs(origin.x - destination.x) < 1e-8 ?
            add(origin, {x: 1, y: (origin.x - destination.x) / (destination.y - origin.y)}) :
            add(origin, {x: (destination.y - origin.y) / (origin.x - destination.x), y: 1});

        // Transform points
        gradientPerpendicular = Matrix.applyToPoint(matrix, gradientPerpendicular);
        origin = Matrix.applyToPoint(matrix, origin);
        destination = Matrix.applyToPoint(matrix, destination);

        // Calculate the direction that the gradient has changed to
        const originToPerpendicular = subtract(gradientPerpendicular, origin);
        const originToDestination = subtract(destination, origin);
        const gradientDirection = Math.abs(originToPerpendicular.x) < 1e-8 ?
            {x: 1, y: -originToPerpendicular.x / originToPerpendicular.y} :
            {x: -originToPerpendicular.y / originToPerpendicular.x, y: 1};

        // Set the destination so that the gradient moves in the correct direction, by projecting the destination vector
        // onto the gradient direction vector
        const projectionCoeff = dot(originToDestination, gradientDirection) / dot(gradientDirection, gradientDirection);
        const projection = multiply(projectionCoeff, gradientDirection);
        destination = {x: origin.x + projection.x, y: origin.y + projection.y};
    }

    // Put values back into svg