SVG Physical Attraction (with Dart and Box2D)

A Box2D demo to show how to hook the physics engine up with SVG and the DOM.

The following code demonstrates how to 'hook-up' the SVG with box engine. An advantage of this approach is that SVG elements can revceive events (e.g. hover to change opacity).

import 'dart:html';
import 'dart:svg';
import 'dart:math';
import 'package:box2d/box2d.dart';  

//hint: add the package to your dart editor project by opening the 
//pubspec.yaml; adding Box2D under dependencies and then 
//running pub install via the link that will be at the top right of page    

World _world;
Map<String,TransformItem> _items = new Map<String,TransformItem>();    
main {    

  //use css selector to create a collection of svg elements to animate
  //(shapes defined in html doc as <path id="path_138" ... d="..."/> )
  queryAll("[id^="path"]").forEach((SvgElement e){
    //set the shape and position of the shape in the box2d world
    var rect = e.getBoundingClientRect();
    fixDef.shape = new CircleShape();
    fixDef.shape.radius = 5.0/SCALE;    
    bodyDef.position.x = (rect.left+rect.width/2)/SCALE;
    bodyDef.position.y =;
    //link the svg element to the fixture via the id attribute
    bodyDef.userData =;
    //TransformItem is a helper class for operating on the SVG Element
    //and is held in a Map for easy access, note the position is on 
    //SVG canvas not at world scale.
    TransformItem item = new TransformItem(e); = new Vector(
    _items[] = item;
    //add the item to world
    Body b = _world.createBody(bodyDef);
    item.orginalMass = b.mass; //playing with mass to add the jitter effect
    //and add some user interaction
    e.onMouseOver.listen((_)=> _.currentTarget.attributes["opacity"] = "0.2");



...and the update method for each animation frame...

dynamic update(num highResTime){

  requestAnimationFrame().then(update); //keep the show running
  //iterate through each box body
  for(Body b = _world.bodyList; b != null; b ={
      //set up the relationship between body and point of attraction 
      Vector itemPosition = b.position;
      Vector targetPosition = _targetPointOfAttraction;
      Vector targetDistance = new; 
      num finalDistance = targetDistance.length;
      //divsors reduce the magnitude of force
      targetDistance = new Vector(targetDistance.x/50,targetDistance.y/50);

      //get the svg element's helper object
      TransformItem path = _items[b.userData]; 
      //playing around with mass
      double multiplier = 1+1.1755*(_random.nextBool()?1:-1);
      b.mass = _random.nextBool()? b.mass * multiplier: path.orginalMass;
      //apply the attraction (comment this out for falling elements)      
      b.applyForce(targetDistance, b.position);
      //translate the position of the svg Element
          new Vector(b.position.x, b.position.y),
      //play around with opacity for effect
      double opacity = double.parse(path.element.attributes["opacity"]);
      path.element.attributes["opacity"] = "${opacity + 0.02 * (_random.nextBool()?-1:1)}";

Currently having problems running in IE (as at 2013-07-06).

View the full source code here and see the references below for tutrials on working with Box2D. For more info on the Dart Programming Language see


Our Google+ SVG-Developers community is brand new and looking for members. There is also a space here for your SVG links, examples and tutorials.