2017-07-24 5 views
3

J'espère que vous pourrez m'aider avec ce problème. Dans mon application, j'utilise globalCompositionOperation défini sur 'source-atop' pour masquer les images et les objets svg sur un objet de base. L'objet de base est le premier objet ajouté au canevas et tous les autres objets doivent s'y attacher.Masquage avec "globalCompositionOperation" défini sur "source-atop" ne fonctionnant pas lorsque "objectCaching" est faux

Le problème se produit lorsque j'ajoute un svg au canevas et que sa propriété objectCaching est définie sur false. L'objet ne se clipse alors pas sur l'objet de base et globalCompositionOperation défini sur 'source-atop' n'a aucun effet. Dès que j'ai défini objectCaching sur true, globalCompositionOperation fonctionne correctement.

fabric.loadSVGFromString(svgString, function(objects, opts) { 

     var svg = fabric.util.groupSVGElements(objects, opts); 

     svg.set({ 
      objectCaching : false, // <--- PROBLEM HERE ! , change to true to see how globalCompositeOperation works fine when objectCaching is set to "true" 
      globalCompositeOperation : 'source-atop' 
     }); 

Dans mon cas, je dois mettre objectCaching pour les objets svg à faux, puisque je dois changer plus tard les couleurs du svg sur, et pour cela, il semble fonctionner que lorsque objectCaching est faux.

S'il existe un moyen de "nettoyer" manuellement le cache de l'objet après qu'il ait été manipulé, ce serait génial mais je ne pense pas que l'API actuelle le permette. De cette façon, je pourrais mettre objectCaching à true, et le clipping en utilisant globalCompositionOperation fonctionnera, et après avoir changé les couleurs des svgs, je pourrais effacer/rafraîchir son cache.

Exemple ici: http://jsfiddle.net/josefano09/hk1on32n/

MISE À JOUR:

La raison pour laquelle j'utilisais objectCaching la valeur false est parce que mon svg ne rendait correctement quand il a été défini sur true. J'ai découvert que c'était dû à un bug dans mon code quand on obtenait les couleurs svg. Une fois que j'ai corrigé ce bogue, j'ai pu profiter des meilleures performances en utilisant objectCaching défini sur true et le découpage de l'objet en utilisant globalCompositionOperation a bien fonctionné. Ensuite, tout ce dont j'avais besoin était de pouvoir mettre à jour le svg juste après avoir changé la couleur de certains chemins du svg. Mettre le drapeau "dirty" à true et faire un canvas.renderAll() a parfaitement fonctionné.

+0

qui ressemble à un bug, mais il semble aussi bizarre qu'ils ne sont pas mis en œuvre une méthode 'updateCache' ... Certains des mainteneurs de la lib ne viennent ici assez souvent, donc ils vont donner une réponse correcte , mais néanmoins, voici une solution de contournement rapide et moche de mon: http://jsfiddle.net/hk1on32n/3/ (l191) – Kaiido

+0

Ne pas désactiver la mise en cache, si vous avez besoin de rendre l'objet à nouveau (c'est à dire un changement de une propriété qui n'est pas la liste 'object.stateProperties') puis définissez le sémaphore' object.dirty = true; '. Cela forcera une mise à jour du cache lors de l'appel de rendu suivant. – Blindman67

+0

Merci @Kaiido Oui, il m'a vraiment semblé bizarre que certaines fonctions comme effacer le cache ne soient pas explicitement implémentées. Et je vois ce que tu as fait là, malheureusement, l'utilisateur est capable de changer les couleurs dynamiquement après que le svg soit ajouté au canevas, donc je ne peux pas vraiment supprimer et rajouter le svg. Merci beaucoup. –

Répondre

4

Pour le rendre un peu plus clair

Conserve la mise en cache.

svg.objectCaching = true; // default so dont need to set just here to show its val 
svg.globalCompositeOperation = 'source-atop'; 

Lorsque vous changez la couleur, réglez le drapeau sale sur true.

svg.dirty = true; 
canvas.renderAll(); // you can force rendering or if you are rendering 
        // already you only have to set dirty, it will be 
        // re rendered the next time it is displayed 

Ajouter ce qui suit à votre violon afin que cela se fasse.

svg.objectCaching = true; 
svg.globalCompositeOperation = 'source-atop'; 

const cols = ["red","green","blue","yellow","black","orange"]; 
var colCount = 0; 
setInterval(()=>{ 
    svg.paths.forEach(p=>{ p.fill = cols[colCount % cols.length] }) 
    colCount += 1; 
    svg.dirty = true; 
    canvas.renderAll(); 
},500) 
+0

Ah c'est ce que 'dirty' est ... – Kaiido

+0

@Kaiido Je n'ai jamais su quelle était l'option sale pour xD. Merci à Blindman67 –