mapa lite interactivo con svg raphael background-image

lite - svg maps wordpress



¿Cómo hacer que un patrón de relleno de Rafael se mueva con el elemento?(posición de la imagen de fondo relativa al elemento) (2)

Recientemente me encontré con un problema similar. No pude encontrar una solución funcional en ninguna parte, así que se me ocurrió la mía. Utilicé la respuesta por @ user568458 como punto de partida. Primero cambié la función updatePosition así:

updatePosition = function (o) { if(!o.data("relativeFill")) { //data is a custom store for user''s properties var bbox = o.getBBox(1); $(o.pattern, {patternTransform: o.matrix.invert() + " translate(" + bbox.x + "," + bbox.y + ")"}); } },

También cambié el caso de setFillAndStroke función setFillAndStroke así:

var relativeFill = o.data("relativeFill"), isURL = Str(value).match(R._ISURL); if (isURL) { el = $("pattern"); var ig = $("image"); el.id = R.createUUID(); $(el, {x: 0, y: 0, patternUnits: relativeFill ? "objectBoundingBox" : "userSpaceOnUse", height: 1, width: 1}); $(ig, {x: 0, y: 0, "xlink:href": isURL[1]}); el.appendChild(ig); (function (el) { R._preload(isURL[1], function () { var w = this.offsetWidth, h = this.offsetHeight, bbox = o.getBBox(); $(el, {width: 1, height: 1}); $(ig, {width: relativeFill ? bbox.width : w, height: relativeFill ? bbox.height : h}); o.paper.safari(); }); })(el); o.paper.defs.appendChild(el); $(node, {fill: "url(#" + el.id + ")"}); o.pattern = el; o.pattern && updatePosition(o); break; }

Entonces, siempre que quiera usarlo, debe configurar yourElement.data({ relativeFill: true })

Aquí hay un ejemplo de trabajo con relleno relativo y repetido: https://codepen.io/mmazur/pen/Gmebrj?editors=0010

Estoy de acuerdo con @ user568458, esta solución es muy fea y podría dejar de funcionar con una futura actualización de Raphael. Sin embargo, Raphael no ha cambiado mucho últimamente, así que estoy bien asumiendo este riesgo.

EDITAR: Corregido un error descrito aquí: Imagen borrosa cuando se usa el patrón de relleno de url para svg circle

¿Cómo puedo darle a un elemento de Rafael un relleno que se mueve a medida que se mueve el elemento, como la background-image de background-image CSS de una position: absolute; ¿El elemento HTML mantendría la misma posición relativa a su ubicación a medida que se movía?

Aquí hay una demostración de ejemplo: ¿cómo puedo hacer que el patrón de la imagen de fondo del elemento Raphael (la ruta triangular) se comporte igual mientras se arrastra como el elemento HTML (el div cuadrado)?

http://jsbin.com/oxuyeq/8/edit

Esta pregunta es esencialmente lo opuesto a ¿Cómo hacer un patrón "fijo" en Raphael.js / IE? con el simulador de gafas polarizadas: quiero hacer que el comportamiento específico de IE que intentaban evitar suceda de forma coherente en todos los navegadores (incluido IE8).

Como se detalla en esa otra pregunta, solo en IE8 (VML), el elemento Raphael se comporta como yo quiero; pero incluso esto es errático: varias cosas, como llamar a setSize en el elemento de paper o redefinir el relleno (en esencia, cualquier cosa que fuerce un redibujado) hace que cambie al otro comportamiento.

Hay una pregunta similar a esto para SVG puro , pero sin ninguna buena respuesta al momento de escribir, y ciertamente ninguna que funcione para Raphael.

Edición 2 : Viendo lo que sucede en el modo SVG, parece que cada transformación de Rafael también hace automáticamente la misma transformación de matriz al elemento svg <pattern> . Creo que esto es lo que causa el comportamiento que trato de evitar, creo que las patternContentUnits y patternUnits no están relacionadas. Hay un problema sin resolver que parece relacionado aquí (destacando el mismo problema con el clip-rect, junto a la línea this.pattern && updatePosition(this); ) - https://github.com/DmitryBaranovskiy/raphael/issues/638

Entonces, una posibilidad podría ser definir un atributo personalizado que aplique una transformación al elemento sin aplicarlo también al patrón. Suena difícil: podría ser necesario hackear a Raphael o duplicar muchos códigos de transformación de Rafael. Espero que haya alguna otra forma. Y que Dios nos ayude a hacer que esto funcione en VML ...

Edición 3: alguna información potencialmente relevante, no son solo los rellenos de ruta los que tienen este problema. Los elementos de image Rafael creados con paper.image() no tienen este problema en modo SVG, pero tienen un problema muy similar que es realmente malo en el modo IE8 VML. Aquí hay una demostración de varias maneras de hacer que los elementos de la imagen se muevan, y aquí hay una comparación de lado a lado que muestra cómo funcionan perfectamente en no-IE y todos fallan en IE:


Editar:

Hay una solución aproximada para esto que no requiere la piratería del código central de Raphael, pero sí depende de un error de IE no completamente estable, descrito https://github.com/DmitryBaranovskiy/raphael/issues/177

Funciona al ocultar el objeto de patrón SVG de Raphael al renombrarlo en el objeto Raphael, lo que updatePosition() que no se llame a updatePosition() . Esto detiene a Raphael moviendo la imagen de fondo en modo SVG. En el modo VML, IE8 tiene un error por el cual, aunque el código mueve el elemento <fill> , esto no se actualiza en la pantalla hasta que se fuerza un redraw.

path.patternTmp = path.pattern; delete path.pattern;

Esto tiene el mismo inconveniente que la sugerencia a continuación de que en el modo VML se basa en un error de IE. Pero funciona para casos simples. No he probado lo suficiente como para ver si hay otros efectos secundarios de esta corrección, pero no debería ser así: mirado el código fuente de Raphael, parece que updatePosition() es la única función de Raphael que usa element.pattern .

http://jsbin.com/oxuyeq/10/edit

Tenga en cuenta que path.pattern tiene que renombrarse de esta manera cada vez que se aplica un relleno de imagen, por lo que si vuelve a aplicar el relleno por alguna razón, debe volver a hacer esta corrección, y si vuelve a aplicar el relleno se "arreglará" el IE bug dependemos de hacer que la imagen se deslice fuera de sincronización con el objeto.

Respuesta original: Aquí hay una especie de solución. Es feo de dos maneras:

  • Para SVG, depende de piratear el código central de Raphael (pero solo un pequeño truco)
  • Para VML, depende de un error de redibujado de Internet Explorer, y fallará si su código causa un redibujado

Pero puede obtener posiciones relativas, siempre y cuando su código no desencadene un rediseño de IE (por ejemplo, volviendo a configurar el relleno del elemento).

Idealmente, habría una forma de hacerlo que funcione de manera robusta en IE VML en lugar de depender de un error.

Usted puede hacer esta fea corrección casi al desactivar la función de updatePosition() alguna manera . El comportamiento descrito anteriormente no es un valor predeterminado de SVG, es una función de Rafael definida en la función updatePosition() que parece diseñada para hacer que el comportamiento de los elementos SVG de Raphael coincida con el comportamiento de los elementos VML si Internet Explorer no fuera un conjunto de errores junto con los errores. Tenga en cuenta que la función updatePosition() solo se llama en el modo SVG: se supone que los rellenos VML se comportan de esta manera por defecto (pero no de manera confiable debido al error de redibujado descrito en la pregunta vinculada anterior ...).

Mi (fea) forma de hacerlo es modificar el código de la función updatePosition() a esto:

updatePosition = function (o) { if(!o.relativeFill) { // <<< added this condition var bbox = o.getBBox(1); $(o.pattern, {patternTransform: o.matrix.invert() + " translate(" + bbox.x + "," + bbox.y + ")"}); } },

... entonces, para cada elemento que desea tener un relleno relativo, establece someElement.relativeFill = true;

Tenga en cuenta que esta no es una buena práctica , por ejemplo, una futura actualización de Raphael podría usar el espacio de nombre relativeFill para otra cosa. Es solo un ejemplo de una solución pegajosa de yeso que (casi) funciona.

re. Modo VML: En teoría, es posible que pueda hacer que este arreglo sea robusto y no dependa de errores al agregar una condición similar al lugar en las funciones de Raphael del modo VML setFillAndStroke y / o setCoords que establecen fill.position en un cálculo dinámico. Estos parecen ser el equivalente VML de updatePosition() . En teoría, VML debería establecer el relleno relativo a la forma siempre que alignshape = true para el elemento de relleno, que en teoría debería ser cierto de manera predeterminada .

Pero, no parece funcionar así en la práctica. A partir de mis pruebas, confiar en el error IE como el anterior parece ser más sólido que tratar de hacer que IE VML funcione como está documentado. En mis pruebas, es bastante difícil hacer que IE8 vuelva a dibujar el relleno: parece que solo restablecer el relleno lo hace.