532 votes

HTML5 Canvas, SVG vs vs div

Quelle est la meilleure façon pour l'élément de la création à la volée et d'être en mesure de le déplacer? Disons que je veux créer un rectangle, un cercle et polygone puis je veux sélectionner les objets et les déplacer

Et quelle est la performance de ces trois sont en utiliser pour afficher une page web? Disons que je veux créer trois visuellement identiques web page et en-tête, pied de page, le widget et le contenu du texte. Le premier est créé à l'aide de pleine toile, le second est créé à l'aide de svg, et le troisième est créé à l'aide de la plaine div en html et css.

633voto

Simon Sarris Points 33799

La réponse courte:

SVG serait plus facile pour vous, puisque la sélection et la déplacer est déjà intégrée. SVG objets sont les objets DOM, de sorte qu'ils ont ", cliquez sur" gestionnaires, etc.

Les DIVs sont ok, mais maladroit et ont affreux performances de chargement à un grand nombre.

La toile a la meilleure performance mains vers le bas, mais vous avez à mettre en œuvre tous les concepts de la gestion de l'état (sélection de l'objet, etc) vous-même, ou l'utilisation d'une bibliothèque.


La réponse longue:

HTML5 Canvas est tout simplement une surface de dessin pour un peu-carte. Vous mis en place pour en tirer (à Dire avec une couleur et l'épaisseur de ligne), tirage de chose, et puis la Toile n'a pas connaissance de cette chose: Il ne sait pas où il est ni ce que c'est que vous venez de dessiner, c'est juste pixels. Si vous voulez dessiner des rectangles et des ont leur de déplacer ou être sélectionnable, alors vous avez le code tout cela à partir de zéro, y compris le code rappelez-vous que vous avez dessiné.

SVG sur l'autre main doit conserver des références pour chaque objet qu'il rend. Chaque SVG/VML élément que vous créez est un réel élément dans le DOM. Par défaut, cela vous permet de garder beaucoup de mieux suivre les éléments que vous créez et le fait de traiter avec des choses comme les événements de la souris plus facile par défaut, mais il ralentit considérablement lorsqu'il existe un grand nombre d'objets

Ceux SVG DOM références dire que certains le jeu de jambes de traiter avec les choses que vous dessinez est fait pour vous. Et SVG est plus rapide lorsque le rendu vraiment de gros objets, mais plus lent lors du rendu de nombreux objets.

Un jeu serait probablement plus rapide dans la Toile. Une carte énorme programme serait probablement plus rapide en SVG. Si vous voulez utiliser de la Toile, j'ai quelques tutoriels sur l'obtention d'objets mobiliers et en cours d'exécution ici.

La toile serait mieux pour les choses plus vite et lourd bitmap manipulation (animation), mais prendra plus de code si vous voulez que beaucoup d'interactivité.

J'ai rencontré un tas de chiffres sur le code HTML DIV dessin versus Toile-dessin. Je pourrais faire une énorme post sur les avantages de chacun, mais je vais donner les résultats de mes tests à prendre en compte pour votre application spécifique:

J'ai fait de Toile et de DIV HTML des pages de test, tous les deux avaient mobile "nœuds". Toile, les nœuds étaient des objets que j'ai créé et gardé la trace de en Javascript. HTML nœuds ont été mobiliers Divs.

J'ai ajouté de 100 000 nœuds pour chacun de mes deux tests. Ils ont joué de façon très différente:

Le test HTML onglet a pris une éternité à se charger (chronométré à légèrement moins de 5 minutes, chrome a demandé de tuer la page la première fois). Google Chrome, le gestionnaire des tâches indique que onglet prennent 168MB. Il prend de 12 à 13% de temps CPU quand je suis en train de regarder, 0% quand je ne suis pas à la recherche.

La Toile onglet chargé en une seconde et prend jusqu'à 30 MO. Il prend également en hausse de 13% de temps CPU à tout moment, indépendamment de si oui ou non on est en la regardant. (2013 edit: Ils ont généralement fixe)

Glisser sur la page HTML est plus lisse, ce qui est prévu par la conception, depuis la configuration actuelle est de redessiner TOUT toutes les 30 millisecondes dans la Toile de test. Il y a beaucoup d'optimisations pour les toiles pour cette. (toile d'invalidation étant le plus facile, aussi des régions de découpage sélectif de redessiner, etc.. tout dépend de combien vous vous sentez comme la mise en oeuvre)

Il n'y a aucun doute que vous pourriez obtenir en Toile pour être plus rapide lors de la manipulation d'objets comme des divs dans ce test simple, et bien sûr beaucoup plus rapide dans le temps de chargement. Dessin/de chargement est plus rapide dans la Toile et a beaucoup plus de place pour les optimisations, trop (c'est à dire, à l'exclusion des choses qui sont hors de l'écran est très facile).

Conclusion:

  • SVG est probablement mieux pour les applications et les applications avec peu d'éléments (moins de 1000? Dépend vraiment)
  • La toile est mieux pour des milliers d'objets et de soin dans la manipulation, mais beaucoup plus de code (ou une bibliothèque) est nécessaire pour l'obtenir sur le sol.
  • HTML Divs sont maladroit et ne sont pas à l'échelle, faire un cercle n'est possible qu'avec des coins arrondis, de réaliser des formes complexes est possible mais implique des centaines de minuscules minuscules pixels de large divs. La folie s'ensuit.

41voto

knut Points 66

Pour ajouter à cela, j'ai fait un schéma de l'application, et qui a commencé avec la toile. Le schéma se compose de beaucoup de nœuds, et ils peuvent être assez grande. L'utilisateur peut faire glisser des éléments dans le schéma autour de.

Ce que j'ai constaté, c'est que sur mon Mac, pour de très grandes images, SVG est supérieure. J'ai un MBP 2013 13" Retina, et il fonctionne à jouer du violon en dessous de tout à fait bien. L'image est 6000x6000 pixels, et dispose de 1000 objets. Une construction similaire en toile a été impossible de les animer pour moi, lorsque l'utilisateur est en faisant glisser les objets dans le diagramme.

Sur moderne affiche, vous devez également tenir compte des différentes résolutions, et ici SVG vous donne tout cela gratuitement.

Violon: http://jsfiddle.net/knutsi/PUcr8/16/

Plein écran: http://jsfiddle.net/knutsi/PUcr8/16/embedded/result/

var wiggle_factor = 0.0;
nodes = [];

// create svg:
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute('style', 'border: 1px solid black');
svg.setAttribute('width', '6000');
svg.setAttribute('height', '6000');
svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
document.body.appendChild(svg);


function makeNode(wiggle) {
    var node = document.createElementNS("http://www.w3.org/2000/svg", "g");
    var node_x = (Math.random() * 6000);
    var node_y = (Math.random() * 6000);
    node.setAttribute("transform", "translate(" + node_x + ", " + node_y +")");

    // circle:
    var circ = document.createElementNS("http://www.w3.org/2000/svg", "circle");
    circ.setAttribute( "id","cir")
    circ.setAttribute( "cx", 0 + "px")
    circ.setAttribute( "cy", 0 + "px")
    circ.setAttribute( "r","100px");
    circ.setAttribute('fill', 'red');
    circ.setAttribute('pointer-events', 'inherit')

    // text:
    var text = document.createElementNS("http://www.w3.org/2000/svg", "text");
    text.textContent = "This is a test! ÅÆØ";

    node.appendChild(circ);
    node.appendChild(text);

    node.x = node_x;
    node.y = node_y;

    if(wiggle)
        nodes.push(node)
    return node;
}

// populate with 100 nodes:
for(var i = 0; i < 1000; i++) {
    var node = makeNode(true);
    svg.appendChild(node);
}

// make  one mapped to mouse:
var bnode = makeNode(false);
svg.appendChild(bnode);

document.body.onmousemove=function(event){
    bnode.setAttribute("transform","translate(" + (event.clientX + window.pageXOffset) + ", " + (event.clientY + window.pageYOffset) +")");
};

setInterval(function() {
    wiggle_factor += 1/60;
    nodes.forEach(function(node) {

        node.setAttribute("transform", "translate(" 
                          + (Math.sin(wiggle_factor) * 200 + node.x) 
                          + ", " 
                          + (Math.sin(wiggle_factor) * 200 + node.y) 
                          + ")");        
    })
},1000/60);

19voto

Ümit Points 9802

Je suis d'accord avec Simon Sarris conclusions:

J'ai comparé une visualisation en Protovis (SVG) à Processingjs (Toile) qui affichent > 2000 points et processingjs est beaucoup plus rapide que protovis.

La gestion des événements avec SVG est bien sûr le plus flexible car vous pouvez les attacher à des objets. En Toile vous devez le faire manuellement (vérifier la position de la souris, etc), mais pour la simple interaction, il ne devrait pas être dur.

Il y a aussi le dojo.gfx bibliothèque du dojo toolkit. Il fournit une couche d'abstraction et vous pouvez spécifier le moteur de rendu (SVG, Canvas, Silverlight). Qui peut aussi être un choix viable, bien que je ne sais pas combien-dessus de la couche d'abstraction supplémentaire ajoute, mais il le rend facile pour code interactions et animations convertisseur agnostique.

Voici quelques intéressant de référence:

13voto

Gaurav Points 3968

Pour vos besoins, je vous recommande d'utiliser le format SVG, puisque vous obtenez DOM événements, comme la manipulation de la souris, y compris le glisser-déposer, inclus, vous n'avez pas à mettre en place votre propre redessiner, et vous n'avez pas à garder une trace de l'état de vos objets. Utiliser de la Toile lorsque vous avez à faire bitmap de manipulation de l'image et utiliser un div lorsque vous souhaitez manipuler des trucs créé en HTML. Concernant les performances, vous trouverez que les navigateurs modernes sont maintenant accélérer tous les trois, mais que la toile a reçu le plus d'attention jusqu'à présent. D'autre part, la façon dont vous écrivez votre javascript est essentiel pour obtenir les meilleures performances, avec de la toile, donc je voudrais encore vous recommandons d'utiliser le format SVG.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X