destroy implemented
diff --git a/player/index.html b/player/index.html
index 274e192..f3374b8 100644
--- a/player/index.html
+++ b/player/index.html
@@ -37,6 +37,6 @@
 </head>
 <body style="background-color:#ccc; margin: 0px;height: 100%; font-family: sans-serif;font-size: 10px">
 
-<div style="width:800px;height:800px;background-color:#333;display:inline-block" class="bodymovin" data-bm-path="exports/render" data-bm-type="svg" data-bm-loop="false" data-bm-prerender="false"></div>
+<div style="width:800px;height:800px;background-color:#333;display:inline-block" class="bodymovin" data-bm-path="exports/render" data-bm-type="canvas" data-bm-loop="true" data-bm-prerender="false"></div>
 </body>
 </html>
diff --git a/player/js/animation/AnimationItem.js b/player/js/animation/AnimationItem.js
index 6dee9db..29c8f8a 100644
--- a/player/js/animation/AnimationItem.js
+++ b/player/js/animation/AnimationItem.js
@@ -25,6 +25,7 @@
     this.renderedFrameCount = 0;
     this.scaleMode = 'fit';
     this.math = Math;
+    this.removed = false;
 };
 
 AnimationItem.prototype.setParams = function(params) {
@@ -270,9 +271,21 @@
     this.setCurrentRawFrameValue(this.currentRawFrame+value);
 };
 
+AnimationItem.prototype.remove = function (name) {
+    if(name && this.name != name){
+        return;
+    }
+    this.renderer.destroy();
+};
+
+AnimationItem.prototype.destroy = function (name) {
+    if(name && this.name != name){
+        return;
+    }
+    this.renderer.destroy();
+};
+
 AnimationItem.prototype.setCurrentRawFrameValue = function(value){
-
-
     this.currentRawFrame = value;
     if (this.currentRawFrame >= this.totalFrames) {
         if(this.loop === false){
diff --git a/player/js/animation/AnimationManager.js b/player/js/animation/AnimationManager.js
index 2207101..5aa985d 100644
--- a/player/js/animation/AnimationManager.js
+++ b/player/js/animation/AnimationManager.js
@@ -67,7 +67,13 @@
         var elapsedTime = nowTime - initTime;
         var i;
         for(i=0;i<len;i+=1){
-            registeredAnimations[i].animation.advanceTime(elapsedTime);
+            if(registeredAnimations[i].animation.renderer.destroyed) {
+                registeredAnimations.splice(i,1);
+                i -= 1;
+                len -= 1;
+            }else{
+                registeredAnimations[i].animation.advanceTime(elapsedTime);
+            }
         }
         initTime = nowTime;
         //setTimeout(resume,10);
diff --git a/player/js/elements/BaseElement.js b/player/js/elements/BaseElement.js
index 715195f..fdd6279 100644
--- a/player/js/elements/BaseElement.js
+++ b/player/js/elements/BaseElement.js
@@ -1,5 +1,4 @@
-var BaseElement = function (data, animationItem,parentContainer,globalData){
-    this.animationItem = animationItem;
+var BaseElement = function (data,parentContainer,globalData){
     this.globalData = globalData;
     this.data = data;
     this.ownMatrix = new Matrix();
@@ -190,6 +189,17 @@
     return this.isVisible;
 };
 
+BaseElement.prototype.destroy = function(){
+    this.layerElement = null;
+    this.parentContainer = null;
+    if(this.matteElement) {
+        this.matteElement = null;
+    }
+    if(this.maskManager) {
+        this.maskManager.destroy();
+    }
+};
+
 BaseElement.prototype.getDomElement = function(){
     return this.layerElement;
 };
diff --git a/player/js/elements/CompElement.js b/player/js/elements/CompElement.js
index 934098f..0830824 100644
--- a/player/js/elements/CompElement.js
+++ b/player/js/elements/CompElement.js
@@ -1,5 +1,5 @@
-function ICompElement(data, animationItem,parentContainer,globalData){
-    this.parent.constructor.call(this,data, animationItem,parentContainer,globalData);
+function ICompElement(data,parentContainer,globalData){
+    this.parent.constructor.call(this,data,parentContainer,globalData);
     this.layers = data.layers;
 }
 createElement(BaseElement, ICompElement);
@@ -46,4 +46,12 @@
 
 ICompElement.prototype.getElements = function(){
     return this.elements;
+};
+
+ICompElement.prototype.destroy = function(){
+    this.parent.destroy.call();
+    var i,len = this.layers.length;
+    for( i = 0; i < len; i+=1 ){
+        this.elements[i].destroy();
+    }
 };
\ No newline at end of file
diff --git a/player/js/elements/ImageElement.js b/player/js/elements/ImageElement.js
index 052e76e..6906dee 100644
--- a/player/js/elements/ImageElement.js
+++ b/player/js/elements/ImageElement.js
@@ -1,8 +1,7 @@
-function IImageElement(data, animationItem,parentContainer,globalData){
-    this.animationItem = animationItem;
-    this.assetData = this.animationItem.getAssetData(data.id);
-    this.path = this.animationItem.getPath();
-    this.parent.constructor.call(this,data, animationItem,parentContainer,globalData);
+function IImageElement(data,parentContainer,globalData){
+    this.assetData = globalData.getAssetData(data.id);
+    this.path = globalData.getPath();
+    this.parent.constructor.call(this,data,parentContainer,globalData);
 }
 createElement(BaseElement, IImageElement);
 
@@ -13,7 +12,6 @@
     var imageLoaded = function(){
         self.image.setAttributeNS('http://www.w3.org/1999/xlink','href',self.path+self.assetData.p);
         self.maskedElement = self.image;
-        self.animationItem.elementLoaded();
     };
 
     var img = new Image();
@@ -66,4 +64,9 @@
             this.image.setAttribute('opacity',renderedFrameData.o);
         }
     }
+};
+
+IImageElement.prototype.destroy = function(){
+    this.parent.destroy.call();
+    this.image =  null;
 };
\ No newline at end of file
diff --git a/player/js/elements/ShapeElement.js b/player/js/elements/ShapeElement.js
index 66237d2..7830d34 100644
--- a/player/js/elements/ShapeElement.js
+++ b/player/js/elements/ShapeElement.js
@@ -1,6 +1,6 @@
-function IShapeElement(data, animationItem,parentContainer,globalData){
+function IShapeElement(data,parentContainer,globalData){
     this.shapes = [];
-    this.parent.constructor.call(this,data, animationItem,parentContainer,globalData);
+    this.parent.constructor.call(this,data,parentContainer,globalData);
 }
 createElement(BaseElement, IShapeElement);
 
@@ -34,4 +34,9 @@
     }else{
         this.mainShape.renderShape(num,this.finalTransform);
     }
+};
+
+IShapeElement.prototype.destroy = function(){
+    this.parent.destroy.call();
+    this.mainShape.destroy();
 };
\ No newline at end of file
diff --git a/player/js/elements/ShapeItemElement.js b/player/js/elements/ShapeItemElement.js
index c01883a..8e497cd 100644
--- a/player/js/elements/ShapeItemElement.js
+++ b/player/js/elements/ShapeItemElement.js
@@ -290,4 +290,42 @@
         viewData.lastData.da = dasharray;
         viewData.lastData.do = dashoffset;
     }
+};
+
+ShapeItemElement.prototype.destroy = function(items, data){
+    this.shape = null;
+    this.data = null;
+    this.viewData = null;
+    /*if(!items){
+        items = this.data;
+    }
+    if(!data){
+        data = this.viewData;
+    }
+    var i, len = items.length;
+    var groupTransform,groupMatrix;
+    groupTransform = parentTransform;
+    for(i = 0; i < len; i += 1){
+        if(items[i].ty == 'tr'){
+        }else if(items[i].ty == 'sh'){
+            this.renderPath(items[i],data[i],num,groupTransform);
+        }else if(items[i].ty == 'el'){
+            this.renderPath(items[i],data[i],num,groupTransform);
+            //this.renderEllipse(items[i],data[i],num,groupTransform);
+        }else if(items[i].ty == 'rc'){
+            if(items[i].trimmed){
+                this.renderPath(items[i],data[i],num,groupTransform);
+            }else{
+                this.renderRect(items[i],data[i],num,groupTransform);
+            }
+        }else if(items[i].ty == 'fl'){
+            this.renderFill(items[i],data[i],num,groupTransform);
+        }else if(items[i].ty == 'st'){
+            this.renderStroke(items[i],data[i],num,groupTransform);
+        }else if(items[i].ty == 'gr'){
+            this.renderShape(num,groupTransform,items[i].it,data[i].it);
+        }else if(items[i].ty == 'tm'){
+            //
+        }
+    }*/
 };
\ No newline at end of file
diff --git a/player/js/elements/SolidElement.js b/player/js/elements/SolidElement.js
index f085a9c..d907645 100644
--- a/player/js/elements/SolidElement.js
+++ b/player/js/elements/SolidElement.js
@@ -1,5 +1,5 @@
-function ISolidElement(data, animationItem,parentContainer,globalData){
-    this.parent.constructor.call(this,data, animationItem,parentContainer,globalData);
+function ISolidElement(data,parentContainer,globalData){
+    this.parent.constructor.call(this,data,parentContainer,globalData);
 }
 createElement(BaseElement, ISolidElement);
 
@@ -53,4 +53,9 @@
             this.rectElement.setAttribute('opacity',renderedFrameData.o);
         }
     }
+};
+
+ICompElement.prototype.destroy = function(){
+    this.parent.destroy.call();
+    this.rectElement = null;
 };
\ No newline at end of file
diff --git a/player/js/elements/canvasElements/CVBaseElement.js b/player/js/elements/canvasElements/CVBaseElement.js
index 42446d2..2bb7f23 100644
--- a/player/js/elements/canvasElements/CVBaseElement.js
+++ b/player/js/elements/canvasElements/CVBaseElement.js
@@ -132,3 +132,13 @@
     }
 };
 
+
+CVBaseElement.prototype.destroy = function(){
+    this.canvasContext = null;
+    this.data = null;
+    this.globalData = null;
+    if(this.maskManager) {
+        this.maskManager.destroy();
+    }
+};
+
diff --git a/player/js/elements/canvasElements/CVCompElement.js b/player/js/elements/canvasElements/CVCompElement.js
index f21ecea..0252a65 100644
--- a/player/js/elements/canvasElements/CVCompElement.js
+++ b/player/js/elements/canvasElements/CVCompElement.js
@@ -35,4 +35,14 @@
 
 CVCompElement.prototype.getElements = function(){
     return this.elements;
+};
+
+CVCompElement.prototype.destroy = function(){
+    var i,len = this.layers.length;
+    for( i = len - 1; i >= 0; i -= 1 ){
+        this.elements[i].destroy();
+    }
+    this.layers = null;
+    this.elements = null;
+    this.parent.destroy.call();
 };
\ No newline at end of file
diff --git a/player/js/elements/canvasElements/CVImageElement.js b/player/js/elements/canvasElements/CVImageElement.js
index 81b698a..222f8f4 100644
--- a/player/js/elements/canvasElements/CVImageElement.js
+++ b/player/js/elements/canvasElements/CVImageElement.js
@@ -42,4 +42,10 @@
     this.globalData.renderer.ctxOpacity(this.finalTransform.opacity);
     ctx.drawImage(this.img,0,0);
     this.globalData.renderer.restore(this.data.hasMask);
+};
+
+CVImageElement.prototype.destroy = function(){
+    this.img = null;
+    this.animationItem = null;
+    this.parent.destroy.call();
 };
\ No newline at end of file
diff --git a/player/js/elements/canvasElements/CVMaskElement.js b/player/js/elements/canvasElements/CVMaskElement.js
index 4bcbd7a..bf9d5e7 100644
--- a/player/js/elements/canvasElements/CVMaskElement.js
+++ b/player/js/elements/canvasElements/CVMaskElement.js
@@ -48,4 +48,8 @@
     path.lineTo(this.globalData.compWidth, this.globalData.compHeight);
     path.lineTo(0, this.globalData.compHeight);
     path.lineTo(0, 0);
+};
+
+CVMaskElement.prototype.destroy = function(){
+    this.ctx = null;
 };
\ No newline at end of file
diff --git a/player/js/elements/canvasElements/CVShapeElement.js b/player/js/elements/canvasElements/CVShapeElement.js
index 0303fed..84b4e20 100644
--- a/player/js/elements/canvasElements/CVShapeElement.js
+++ b/player/js/elements/canvasElements/CVShapeElement.js
@@ -30,4 +30,9 @@
 
 CVShapeElement.prototype.drawShapes = function(parentTransform){
     this.mainShape.renderShape(parentTransform);
+};
+
+CVShapeElement.prototype.destroy = function(){
+    this.mainShape.destroy();
+    this.parent.destroy.call();
 };
\ No newline at end of file
diff --git a/player/js/elements/canvasElements/CVShapeItemElement.js b/player/js/elements/canvasElements/CVShapeItemElement.js
index 1ff5cfa..8d00ad7 100644
--- a/player/js/elements/canvasElements/CVShapeItemElement.js
+++ b/player/js/elements/canvasElements/CVShapeItemElement.js
@@ -342,4 +342,10 @@
     this.stylesList.push(this.stylesPool[this.currentStylePoolPos]);
     this.ownStylesList.push(this.stylesList[this.stylesList.length -1]);
     this.currentStylePoolPos += 1;
+};
+
+CVShapeItemElement.prototype.destroy = function(){
+    this.data = null;
+    this.globalData = null;
+    this.canvasContext = null;
 };
\ No newline at end of file
diff --git a/player/js/mask.js b/player/js/mask.js
index 09367c5..e5af841 100644
--- a/player/js/mask.js
+++ b/player/js/mask.js
@@ -6,7 +6,8 @@
     this.paths = [];
     this.registeredEffects = [];
     this.masksProperties = [];
-    this.maskElement = document.createElementNS(svgNS, 'mask');
+    this.maskElement = null;
+    this.layerSize = null;
 }
 
 MaskElement.prototype.init = function () {
@@ -164,4 +165,14 @@
         }
         storedData.lastPath = pathString;
     }
+};
+
+MaskElement.prototype.destroy = function(){
+    this.element = null;
+    this.globalData = null;
+    this.maskElement = null;
+    this.data = null;
+    this.paths = null;
+    this.registeredEffects = null;
+    this.masksProperties = null;
 };
\ No newline at end of file
diff --git a/player/js/renderers/CanvasRenderer.js b/player/js/renderers/CanvasRenderer.js
index 673a1af..a0a01cc 100644
--- a/player/js/renderers/CanvasRenderer.js
+++ b/player/js/renderers/CanvasRenderer.js
@@ -235,6 +235,9 @@
 };
 
 CanvasRenderer.prototype.prepareFrame = function(num){
+    if(this.destroyed) {
+        return;
+    }
     var i, len = this.elements.length;
     for (i = 0; i < len; i++) {
         this.elements[i].prepareFrame(num - this.layers[i].startTime);
@@ -248,8 +251,23 @@
     }
 };
 
+CanvasRenderer.prototype.destroy = function () {
+    if(this.renderConfig.clearCanvas) {
+        this.animationItem.wrapper.innerHTML = '';
+    }
+    var i, len = this.layers.length;
+    for (i = len - 1; i >= 0; i-=1) {
+        this.elements[i].destroy();
+    }
+    this.elements.length = 0;
+    this.globalData.bmCtx = null;
+    this.globalData.canvasContext = null;
+    this.animationItem.container = null;
+    this.destroyed = true;
+};
+
 CanvasRenderer.prototype.renderFrame = function(num){
-    if(this.lastFrame == num && this.renderConfig.clearCanvas === true){
+    if((this.lastFrame == num && this.renderConfig.clearCanvas === true) || this.destroyed){
         return;
     }
     this.lastFrame = num;
diff --git a/player/js/renderers/SVGRenderer.js b/player/js/renderers/SVGRenderer.js
index d09890b..c632b53 100644
--- a/player/js/renderers/SVGRenderer.js
+++ b/player/js/renderers/SVGRenderer.js
@@ -6,6 +6,7 @@
         frameNum: -1
     };
     this.elements = [];
+    this.destroyed = false;
 }
 
 SVGRenderer.prototype.buildItems = function(layers,parentContainer,elements){
@@ -43,28 +44,28 @@
 };
 
 SVGRenderer.prototype.createBase = function (data,parentContainer) {
-    return new BaseElement(data, this.animationItem,parentContainer,this.globalData);
+    return new BaseElement(data, parentContainer,this.globalData);
 };
 
 SVGRenderer.prototype.createShape = function (data,parentContainer) {
-    return new IShapeElement(data, this.animationItem,parentContainer,this.globalData);
+    return new IShapeElement(data, parentContainer,this.globalData);
 };
 
 SVGRenderer.prototype.createText = function (data,parentContainer) {
-    return new ITextElement(data, this.animationItem,parentContainer,this.globalData);
+    return new ITextElement(data, parentContainer,this.globalData);
 };
 
 SVGRenderer.prototype.createImage = function (data,parentContainer) {
-    return new IImageElement(data, this.animationItem,parentContainer,this.globalData);
+    return new IImageElement(data, parentContainer,this.globalData);
 };
 
 SVGRenderer.prototype.createComp = function (data,parentContainer) {
-    return new ICompElement(data, this.animationItem,parentContainer,this.globalData);
+    return new ICompElement(data, parentContainer,this.globalData);
 
 };
 
 SVGRenderer.prototype.createSolid = function (data,parentContainer) {
-    return new ISolidElement(data, this.animationItem,parentContainer,this.globalData);
+    return new ISolidElement(data, parentContainer,this.globalData);
 };
 
 SVGRenderer.prototype.configAnimation = function(animData){
@@ -82,6 +83,9 @@
     var defs = document.createElementNS(svgNS, 'defs');
     this.globalData.defs = defs;
     this.animationItem.container.appendChild(defs);
+    this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+    this.globalData.getPath = this.animationItem.getPath.bind(this.animationItem);
+    this.globalData.elementLoaded = this.animationItem.elementLoaded.bind(this.animationItem);
     var maskElement = document.createElementNS(svgNS, 'clipPath');
     var rect = document.createElementNS(svgNS,'rect');
     rect.setAttribute('width',animData.animation.compWidth);
@@ -131,11 +135,23 @@
     }
 };
 
+SVGRenderer.prototype.destroy = function () {
+    this.animationItem.wrapper.innerHTML = '';
+    this.animationItem.container = null;
+    this.globalData.defs = null;
+    var i, len = this.layers.length;
+    for (i = 0; i < len; i++) {
+        this.elements[i].destroy();
+    }
+    this.elements.length = 0;
+    this.destroyed = true;
+};
+
 SVGRenderer.prototype.updateContainerSize = function () {
 };
 
 SVGRenderer.prototype.renderFrame = function(num){
-    if(this.lastFrame == num){
+    if(this.lastFrame == num || this.destroyed){
         return;
     }
     this.lastFrame = num;