2011-05-13 14 views
6

Estoy realizando el mantenimiento de algunos javascript que hace uso de la propiedad .offsetParent. Los cambios recientes ahora tienen la aplicación usando elementos SVG, y están rompiendo el JavaScript, ya que mySvgElement.offsetParent es siempre undefined.¿Cómo se usa `element.offsetParent` con elementos HTML SVG?

¿Es .offsetParent estándar y no funciona con elementos SVG? Si es así, ¿cuál es una alternativa al .offsetParent cuando se trabaja con elementos HTML5 SVG?

Respuesta

6

offsetParent no existe en SVG.

Para obtener las coordenadas del cuadro delimitador de un nodo SVG, normalmente usaría el método getBox en el elemento SVG. Esto devuelve un bbox en el sistema de coordenadas local de ese elemento. Para determinar la ubicación del elemento SVG en coordenadas de pantalla, entonces, usa getScreenCTM en el elemento para obtener una matriz de transformación que transformará las coordenadas locales de ese elemento en coordenadas de pantalla. A continuación, transforma la bbox devuelta por la matriz de transformación devuelta. Aquí hay algo de código para hacer esto:

function getBoundingBoxInArbitrarySpace(element,mat){ 
    var svgRoot = element.ownerSVGElement; 
    var bbox = element.getBBox(); 

    var cPt1 = svgRoot.createSVGPoint(); 
    cPt1.x = bbox.x; 
    cPt1.y = bbox.y; 
    cPt1 = cPt1.matrixTransform(mat); 

    // repeat for other corner points and the new bbox is 
    // simply the minX/minY to maxX/maxY of the four points. 
    var cPt2 = svgRoot.createSVGPoint(); 
    cPt2.x = bbox.x + bbox.width; 
    cPt2.y = bbox.y; 
    cPt2 = cPt2.matrixTransform(mat); 

    var cPt3 = svgRoot.createSVGPoint(); 
    cPt3.x = bbox.x; 
    cPt3.y = bbox.y + bbox.height; 
    cPt3 = cPt3.matrixTransform(mat); 

    var cPt4 = svgRoot.createSVGPoint(); 
    cPt4.x = bbox.x + bbox.width; 
    cPt4.y = bbox.y + bbox.height; 
    cPt4 = cPt4.matrixTransform(mat); 

    var points = [cPt1,cPt2,cPt3,cPt4] 

    //find minX,minY,maxX,maxY 
    var minX=Number.MAX_VALUE; 
    var minY=Number.MAX_VALUE; 
    var maxX=0 
    var maxY=0 
    for(i=0;i<points.length;i++) 
    { 
     if (points[i].x < minX) 
     { 
      minX = points[i].x 
     } 
     if (points[i].y < minY) 
     { 
      minY = points[i].y 
     } 
     if (points[i].x > maxX) 
     { 
      maxX = points[i].x 
     } 
     if (points[i].y > maxY) 
     { 
      maxY = points[i].y 
     } 
    } 

    //instantiate new object that is like an SVGRect 
    var newBBox = {"x":minX,"y":minY,"width":maxX-minX,"height":maxY-minY} 
    return newBBox; 
} 

function getBBoxInScreenSpace(element){ 
    return getBoundingBoxInArbitrarySpace(element,element.getScreenCTM()); 
} 

Este código fue tomado de here, y es Apache-licencia. getBoundingBoxInArbitrarySpace ha sido probado, pero getBBoxInScreenSpace no lo ha hecho (pero creo que debería funcionar).

3

offsetParent no es una propiedad estándar de los elementos SVG, aunque algunos navegadores pueden proporcionar uno de todos modos.

Dependiendo de lo que quieras hacer con la información, usar getScreenCTM o getCTM probablemente funcione para ti. Por ejemplo, aquí es cómo se puede calcular la posición en píxeles de (0, 0) con respecto al elemento:

var 
     matrix = element.getScreenCTM(), 
     point = element.createSVGPoint(); 
    point.x = 0; 
    point.y = 0; 
    point = point.matrixTransform(matrix.inverse()); 
Cuestiones relacionadas