Skip to content
Eric Rowell edited this page Jun 13, 2013 · 235 revisions

4.5.4 June 9 2013 (Current)

  • API Changes
    • Brought back Ellipse
  • New Features
    • new destroyChildren() method that destroys all children and descendants
    • new Tween destroy() method which appropriately cleans up memory when you're done with a tween
  • Enhancements
    • Points can now be tweened. This means that you can tween the geometry of shapes, such as lines, splines, polygons, and blobs
    • All applicable methods now return this
    • when a new stage is instantiated, its container DOM element is now emptied first
  • Bug Fixes
    • Worked around a Chrome 27 Bug which sometimes draws rectangles as circles when a stroke is applied
    • removeChildren() now works correctly when the children have children
    • stage.destroy() now correctly destroys children

4.5.3 May 31 2013

  • Bug Fixes
    • drag and drop no longer gets hung up in Chrome 27
    • custom builds that don't include the drag and drop module no longer throw a JS error

4.5.2 May 21 2013

  • API changes
    • Deprecated Ellipse shape. Ellipses can be made by stretching a circle. You can also maintain the stroke width using strokeScaleEnabled = false
    • changed getIntersections() method to getAllIntersections() to indicate that you may be getting more than you need. This is a very slow method, and should only be used for special situations. getIntersection() is a much better alternative
    • Label config API was rewritten. You now need to instantiate individual Text and Tag shapes, and then add them to the Label group. Please check the tutorials for examples.
    • LabelRect shape inside Label has changed to Tag. i.e., the Label group is now made up of a Text shape and a Tag shape
    • nodeType and shapeType properties have been removed from toJSON output in favor of className. when creating an element with Node.create, make sure that the json string contains a className property for each node
  • New features
    • add event is now fired when nodes are added. event object with child property is passed.
    • new setAttr() method which can be used to set Kinetic attrs, or even custom attrs. Custom attrs changes can also be subscribed to, just like Kinetic attrs. i.e. shape.on('myAttrChange', ...);
    • new getType() to get node type. Will return Stage, Layer, Group, or Shape
    • new getClassName() to get node class name. Will return Stage, Layer, Group, and shape class names such as Rect, Circle, Text, etc.
  • Enhancements
    • getChildren() and getLayers() now return a Kinetic.Collection
  • Performance improvements
    • attr and draw changes no longer bubble. This increases update/draw performance by about 25%
  • Bug fixes
    • stage tweens now work correctly
    • Label offsets now work correctly
    • Label serialization and deserialization now work correctly
    • When setting Layer visibility during instantiation, a JS error is no longer thrown
    • Tween onFinish now only fires once if you're tweening more than one property

4.5.1 May 11 2013

  • API Changes
    • new Tween class. The old Transition class has been retired. For advanced tweens, such as tweening things along curves, or constructing timelines, KineticJS recommends the GreenSock Animation Platform which integrates seemlessly.
  • Bug Fixes
    • Animations and Drag and drop now work correctly again in older versions of webkit that don't support requestAnimationFrame. This primarily applies to users with Safari 5.1.x
    • Animations instantiated with no layer array now correctly executes the user defined function
  • New Features
    • new Tween class. The old Transition class has been retired.

4.5.0 May 8 2013

  • API changes
    • The KineticJS Transition class has been deprecated in favor of GreenSock Transitions (GSAP). Please see the updated transition tutorials for the new API.
    • Filters no longer require a callback. They are now synchronous.
    • Filters now access parameters via getters, such as getFilterBrightness(). This was done to enable filter transitions
  • New features
    • New Skew transform (thanks Daniel Kur and Dave Whipps!)
    • You can now manipulate individual color components of fill, stroke, and shadowColor, i.e. setFillRGB(), setFillR(), setFillG(), and setFillB(), along with corresponding getter methods. This also makes it possible to transition colors, and individual color components
    • new image.clearFilter() method which clears the currently applied filter and returns the image back to its original state
    • new batchDraw() method which batches redraws together. Calling batchDraw() multiple times on the same node in between animation frames results in only one redraw per animation frame.
    • new stage getLayers() method which maps to getChildren()
  • Performance Gains
    • Increased rendering performance by about 17% by adding matrix transform caching
  • Enhancements
    • animations can now be tied to a single layer, or an array of layers
    • All point attrs now have individual component getters and setters. i.e. in addition to setScale() and getScale(), you can now also use setScaleX(), setScaleY(), getScaleX(), and getScaleY()
    • You can now run multiple independent transitions on a single node
  • Bug Fixes
    • point getters and setters, such as getScale(), and getOffset(), now return unique default attrs and aren't affected by other node defaults.

4.4.3 Apr 14 2013

  • Enhancements
    • transition callback is now executed within the context of the node, meaning that you can access the node that is being transitioned with the "this" keyword
  • Bug fixes
    • createImageHitRegion() now works correctly again
    • toDataURL() and toImage() now works correctly on devices when the pixel ratio != 1

4.4.2 Apr 13 2013

  • Bug Fixes
    • added support for iOS 5.1 by removing Function.prototype.bind() dependency
    • Destroying a node during drag and drop now works correctly
    • Shape color key is now unregistered on destroy(), not remove()
  • Performance Gains
    • improved node instantiation performance by improving the color key generation algorithm

4.4.1 Apr 7 2013

  • New Features
    • new Mask filter (Thanks nicomlas!)
  • Bug Fixes
    • Sprite shapes now correctly take the default index value of 0 if the index is not defined
    • custom builds that have not included the DragAndDrop module now work correctly
    • Stage clear() now works correctly (Thanks alexahn!)
    • Last word of multi line text now correctly wraps, and text wrapping now correctly takes into account padding (Thanks Louis Jolibois!)
    • Line, Spline, Blob, and Polygon points default now works correctly
    • hit graph is now redrawn correctly when calling drawHit()
    • drag and drop logic now works correctly when both the stage and a shape are draggable

4.4.0 Mar 26 2013

  • New features
    • container clipping regions which can be applied to layers and groups. Everything drawn on a container with a clipping region fits inside the region. Clipping regions can also be transformed since they are tied to the container transform
    • new Label plugin which can be used to create text with backgrounds, simple tooltips, or pointer tooltips.
    • new Blur filter. (Thanks Pavel Akhmetchanov!)
    • new Text wrap attribute which can be set to none, word, or char (Thanks Louis Jolibois!)
    • new strokeScaleEnabled property which enables you to configure whether or not a stroke style scales as a shape scales, or as its ancestors scale
    • new getAttr() method which enables you to get an attr by a dynamic key, rather then using the static getter method. i.e. getX() vs. getAttr('x');
    • new getNodeType() method which returns the node type, such as "Stage", "Layer", "Group", or "Shape".
    • new startDrag() and stopDrag() methods to programmatically start and stop drag and drop
    • new getShapeType() method which returns the shape type if the node is a shape, such as "Rect", "Circle", "Text", etc.
  • Enhancements
    • improved overall Node instantiation time by about 66%, which means that your KineticJS apps will start up much faster
    • improved transition performance
    • serialized objects (JSON) are now about 3x more compact
    • when using event delegation, the target event property changed from "shape" to "targetNode" for consistency because now any node type can fire events. i.e. var shape = evt.targetNode
    • now any node can use the draw() method, not just the stage and layers. If draw() is used with groups and shapes, the layer is cleared, and just that node is drawn.
    • removed stage.reset() to avoid confusion. If you'd like to start over with a new stage, just use stage.destroy() and then new Kinetic.Stage() again.
    • all canvas elements now have predefined padding, margin, border, and background style overrides.
    • Path, TextPath, RegularPolygon, and Star shapes are now classified as plugins. They will still exist in the Kinetic namespace.
    • TextPath fontSize is now in pixels like Text
    • Improved Text rendering performance (Thanks Louis Jolibois!)
    • removed simulate() method. added new paramter to fire() which enables you to control whether or not the event bubbles
    • setUserPosition() and getUserPosition() changed to setPointerPosition() and getPointerPosition()
    • dynamic drag and drop layer functionality has been removed. The performance benefit (very small) did not outweight the complexity that was being introduced into the code base to support it. Too many edge cases. High performance drag and drop can still be achieved by intelligently structuring your layers.
    • removed Collection apply() method to avoid confusion. For now, just use each()
    • removed beforeDraw and afterDraw methods. you can now listen for draw events via .on('draw') or .on('beforeDraw'). Draw events now bubble.
  • Bug fixes
    • Fixed Text wrapping issues (Thanks Louis Jolibois!)
    • firing event which has no binding no longer throws an exception
    • drag and drop on mobile no longer flickers (dynamic drag layer was removed)
    • beforeEvent event names are now correctly constructed
    • id selectors now work correctly during drag and drop
    • drag events now correctly bubble
    • dragend events now fire after mouseup/touchend events
    • transition callbacks are now executed after all sub-tweens have completed
    • mousedown on one shape, and mouseup on another shape, now correctly does not fire a click event on the second shape

4.3.3 Feb 12 2013

  • Bug fixes
    • Kinetic.Text events are now working correctly
    • Fixed scaling issue when drawing directly onto a layer canvas on mobile devices with a pixelRatio > 1
    • Wedge clockwise property is now correctly defaulted to false.

4.3.2 Feb 06 2013

  • New Features
    • New enabler and disabler functions for shape attributes that can be used toggle properties on and off, such as fill, stroke, shadow, and dashArray. The new respective attributes are fillEnabled, strokeEnabled, shadowEnabled, and dashArrayEnabled. The new enabler and disabler methods are enableFill(), disableFill(), enableStroke(), disableStroke(), enableShadow(), disableShadow(), enableDashArray(), disableDashArray()
    • new fillPriority attribute which makes it easy to switch between different fill types. Can be color, pattern, linear-gradient, or radial-gradient
  • Enhancements
    • When both a node and one of its ancestors are draggable, the node will now have priority over the ancestor. For example, when both the stage and a shape are draggable, and you drag and drop the shape, just the shape will move. When you drag and drop the stage, the whole stage will move.
    • drag and drop completes when a mouseup or touchend event is detected anywhere on the page. This means that when dragging a node, a user can mouseout of the stage, mouse back in, and the drag and drop will continue. If a user mouses up outside of the stage, the drag and drop will end.
    • dynamic drag layer now does deep copy for Groups and Layers when reconstructing Node tree
    • added line dash support for Firefox and Safari (Thanks nokturnal!)
  • Bug Fixes
    • shadows are now correctly applied to shapes with pattern or gradient fills.
    • TextPath shadows now work correctly
    • drag and drop dragend event is now fired after drag and drop animation is stopped
    • mouseup and click events now work correctly after dragging and dropping

4.3.1 Jan 13 2013

  • New features
    • added new dragOnTop attr to enable or disable moving the node to a temp top layer when dragging
    • new Node destroy() method which removes and destroys node
    • new stage.getDragLayer() method returns the dedicated drag and drop layer
    • new Animation isRunning() method returns true if the animation is running and false otherwise.
  • Enhancements
    • points attr now supports an array of arrays (thanks Arthaey Angosii!)
    • remove() method now only detaches a node from the stage, it no longer destroys it. This means that you can also re add a node via the add() method after you've removed it
    • changed getDOM() to getContent()
  • Bug fixes
    • drag and drop no longer flickers on mobile devices
    • setting draggable=false on dragend no longer throws a JS error
    • stage.remove() now correctly removes content div element
    • dragging and dropping nodes inside transformed groups now works correctly

4.3.0 Jan 06 2013

Note: This release addresses all of the API changes that I've been wanting to make for awhile. Therefore, it's very likely that you'll need to make changes to your existing application when upgrading. Significant API changes have been made with Kinetic.Text attrs, shadow attrs, and fill attrs.

  • New Features
    • new Spline shape
    • new Blob shape
  • Enhancements
    • big changes to Kinetic.Text shape. Rectangle component has been removed to simplify the API. textFill is now fill, textStroke is now stroke, textStrokeWidth is now strokeWidth, and textShadow is now shadow. If you want to have a rectangle behind the text, you need to group the text with a Kinetic.Rect shape. Text fontSize units are now in pixels (used to be in points). The lineHeight attr is now defaulted to 1 (used to be defaulted to 1.2).
    • drag and drop operations now automatically dynamically create a temporary top layer, and place nodes there for groups and shapes to greatly improve drag and drop performance. When the drag and drop operation is completed, the layer is removed and the node is placed back into its container
    • cornerRadius attr moved to rect shape
    • when dragging and dropping, if the mouse goes outside of the stage, and then returns, the the drag and drop operation is no longer cancelled
    • shadow object attr has been flattened into shadowColor, shadowBlur, shadowOffset, and shadowOpacity attrs
    • It's now possible for shapes to extend other shapes
    • flattened fill attr object.
    • removed excessive lineDash warnings
  • Bug Fixes
    • toDataUrl now correctly counters pixel ratio scaling

v4.2.0 Dec 16 2012

  • New Features
    • pixel ratio optimization to sharpen text and image rendering on devices with a pixel ratio > 1
    • new Wedge shape
    • AMD support
    • Fill patterns can now be translated, rotated, scaled, and offset, similarly to nodes
    • KineticJS is now hosted on a CDN which means you can hotlink to the download url and still get wicked fast http responses.
  • Enhancements
    • shape draw functions are now passed a Canvas renderer, not a canvas context. If your application uses custom shapes, please be sure to check out the custom shape tutorial to see what changes will need to be made.
    • moved dashArray attr to Shape level. Dash arrays are now rendered using the canvas API setLineDash() method, which enables dashed lines for any type of stroke, not just straight lines. This was also done in preparation for the new spline feature for the next release. Since not all browsers support dash arrays at the moment, a warning will be issued when trying to render a dash array in a browser which hasn't implemented it yet
    • toImage() now accepts x and y params so that you can define the cache rectangle position
  • Bug Fixes
    • toImage() now works correctly with the stage and layers
    • animation frame object time, timeDiff, and lastTime properties are now updated correctly when multiple animations are running at the same time.
    • nodes are now correctly removed in cases where node.remove() is called from a mousedown or click handler on self, and the node is draggable

v4.1.2 Nov 28 2012

  • Enhancements
    • changed createImageBuffer() to createImageHitRegion() for consistency
  • Bug Fixes
    • createImageHitRegion() now correctly renders the hit graph for images with transparent pixels
    • Image hit drawing functions now correctly render the image stroke
    • added Kinetic warning for cases when toDataURL() fails due to security error

v4.1.1 Nov 27 2012

  • Bug Fixes
    • hit graph now correctly renders for non Webkit browsers, including Firefox and IE9.

v4.1.0 Nov 26 2012

  • New Features
    • you can now create custom hit detection drawing algorithms by setting the drawHitFunc attr
    • stage now has access to drawScene() and drawHit() methods
    • Shape constructors now accept custom drawFunc and drawHitFunc properties
    • new textShadow attr
    • new fillStroke() method which fills, strokes, and applies shadows to the current path
  • Enhancements
    • scene, hit, and buffer graph drawing performance have been greatly improved, especially for the Image and Sprite shapes
    • Improved drag and drop performance by skipping hit func redraws on drag move
    • Kinetic.Animation constructor now takes in a function and optional node, rather than a config object
    • Image.applyFilter() now takes in a required filter function, optional config object, and optional callback, rather than a config object that contained these three properties.
  • Bug Fixes
    • when node.remove() is called, parent property is unset

v4.0.5 Nov 4 2012

  • New Features
    • new Brighten filter (Thanks for getting this started Witali Mik!)
    • new Invert filter
    • new fire() method fires synthetic events without event bubbling
    • animation objects now contain frameRate property for convenience
  • Enhancements
    • Greatly improved animation, transition, and drag and drop performance by introducing dynamic switching between fixed frame rates and dynamic frame rates
    • simulate() method is now used to simulate user events, such as click, mousemove, mouseover, etc. When events are simulated, they can bubble up the Node tree.
  • Bug Fixes
    • setDraggable(false) now correctly cancels stage drag and drop when dragging
    • isListening() now takes into account ancestor listening status
    • Kinetic.Global.warn() now works correctly in IE9 running on Windows 7 64bit (Thanks soulBit!)
    • Sprite cloning now works correctly

v4.0.4 Oct 19 2012

  • New Features
    • new custom build configurator support which enables you to specify the exact modules needed for your application in order to reduce the JavaScript file size as much as possible

v4.0.3 Oct 11 2012

  • New Features
    • new mouseenter and mouseleave events. This enables more flexibility with event delegation
  • Enhancements
    • you can now remove groups of listeners via a name selector with the off() method (Thanks David Johansson!)
    • toJSON() method can now serialize any node, including the stage, layers, groups, and shapes.
    • removed stage.load() method. You can now deserialize any node, including the stage, layers, groups, and shapes, by creating a node from a json string using Kinetic.Node.create()
    • line caps styles are now enabled for paths
    • get() now also supports shape type selectors (Thanks David Johansson!)
    • moved width and height attrs to the node level. Created getters and setters that use bounding boxes around select nodes. For example, to define the size of an ellipse, you could set its width and height rather than setting the radius.
    • Kinetic.Text getWidth() and getHeight() now return calculated width and height. Removed getBoxWidth() and getBoxHeight() methods.
  • Bug Fixes
    • layer children events no longer fire when layer is hidden (Thanks Adam Wróbel for getting this started!)
    • setZIndex() now correctly reorders layer canvases
    • opacity can now be applied to the stage (Thanks David Johansson!)
    • text shadow offset now works correctly
    • layer.toDataURL() and stage.toDataURL() now work correctly when using hidden layers

v4.0.2 Sep 27 2012

  • New Features
    • New Collections class enables you to apply methods to all of the nodes returned from get(). e.g. stage.get('.foo').apply('setX', 400);. The Collections class also has a handy each() method for quickly iterating over an array of nodes. You can also use stage.get('.foo').on('click', '...') (Thanks David Johansson for getting this going!)
    • new dragBoundFunc property which enables you to define the drag and drop bounds function. In addition to constraining the drag and drop motion vertically and horizontally, you can also create custom functions that constrain the motion diagonally, radially, or whatever you can come up with. The dragBoundFunc property has replaced the dragBounds and dragConstraint properties because they are no redundant. (Thanks David Johansson!)
  • Enhancements
    • remove() method now only requires the node that needs to be removed. i.e. to remove a node, you no longer use node.getParent().remove(node). Now you just use node.remove();
    • improved attr setting performance
    • clone() now does a deep copy by also cloning children nodes (Thanks David Johansson!)
    • when calling layer.show() or hide(), the physical canvas element is shown or hidden rather than drawing or clearing the context. This greatly improves layer hide and show performance. (Thanks Adam Wróbel!)
    • added isListening and isDraggable aliases for consistency
  • Bug Fixes
    • Fix Layer.moveToBottom() when only one layer is present (Thanks Adam Wróbel!)
    • setting text to an integer via setText() no longer fails
    • If a framework extending the DOM is used (like MooTools or prototype) toJSON now serializes "Number"-object correctly (Thanks David Johansson!)
    • You can now dynamically switch between different fill types, including colors, linear gradients, radial gradients, and patterns
    • text shadows now work correctly with text paths (Thanks David Johansson!)
    • Corrected Kinetic.Path.getPointOnLine() to work in negative x direction (Thanks David Johansson!)

v4.0.1 Aug 26 2012

  • Enhancements
    • Dependency on Class utility has been removed because it was really slowing down Node instantiations. New custom solution is about 2x faster
    • Reintroduced full Circle shape, in which Kinetic.Circle no longer points to Kinetic.Ellipse.
  • Bug Fixes
    • layer moveToTop(), moveToBottom(), moveUp(), and moveDown() now correctly reorder the scene canvases
    • Sprite afterFrame function now only executes once because its purpose is for animation key switching. Once the key has switched, it doesn't make sense to continue executing the afterFrame function because the sprite is now on a different animation.
    • getIntersections now returns the correct shapes that intersect a point
    • radius property is now transitionable
    • now removing color key from shapes hash when a shape is removed from stage
    • multi line text now correctly supports shadows
    • event detection now works correctly for stages below the fold on mobile devices
    • FF should no longer fail when using non integer coordinates with methods dependent on getImageData() because the pixel coordinates are now rounded

v4.0.0 Aug 21 2012

  • New Features
    • new drawBuffer() method which only redraws the buffer canvas
    • new drawScene() method which only redraws the scene
    • new getIntersection() method returns an object with shape and pixel data
    • new createBufferImage() method generates a special image to be drawn on the buffer which enables high precision event detections for images
    • new clearBufferImage() method clears the buffer image and return to the default buffer rectangle
  • Enhancements
    • new hit detection algorithm with complexity of O(1), which means that hit detection performance is constant regardless of the number of shapes. i.e. you can have tens or hundreds of thousands of nodes, and event detection will still be lightning fast. Thanks to Ben and the Platfora team for suggesting the color key hash technique!
    • Kinetic.Animation is no longer tied to the stage. You can now create as many animations as you like using new Kinetic.Animation()
    • drag and drop is now hooked into the animation engine to leverage dynamic frame rates. This greatly improves performance on mobile devices
    • There's no longer a distinction between path detection and pixel detection. The event engine now uses one strategy
    • removed saveImageData() and clearImageData() methods
    • alpha property has changed to opacity
  • Bug Fixes
    • Animation last time is now correctly calculated after stopping and restarting an animation
    • stage.toDataURL() now works correctly with jpg layers (thanks jfollas!)

v3.10.5 Aug 2 2012

  • New Features
    • new TextPath plugin lets you write text along arbitrary paths (Thanks jfollas!! This was quite an undertaking)
  • Enhancements
    • animations are now silky smooth
    • Improved drag and drop performance by introducing dragThrottle
    • improved drawing performance
    • removed layer draw throttling and event throttling because they weren't working very well with the dynamic animation
    • transition callback is now executed immediately after node draw frame rates, and were causing uncessary problems.
  • Bug Fixes
    • layer canvas context is now correctly removed from the dom when a layer is removed from the stage
    • text fill now works correctly when text shadow has been applied and no textbox fill has been applied
    • changing the font size now correctly updates the text data
    • stage.stop() no longer throws a JS error if an animation has been started and restarted several times

v3.10.4 Jul 22 2012

  • New Features
    • new toImage() method converts any node into an image for the purpose of caching which can greatly improve drawing performance (as much as 4x faster for simple shapes)
    • new applyFilter() method which enables you to apply filter logic to images (e.g. grayscale, inverting colors, etc.)
    • on attr change handler event object now contains oldVal and newVal property
  • Enhancements
    • toDataURL can now be used synchronously with layers, groups, and shapes. Stage toDataURL() is still asynchronous
    • saveData() has changed to saveImageData(), and clearData() has changed to clearImageData()
    • saveImageData() and clearImageData() now work with any node, including the stage, layers, and groups
    • new on beforeAttrChange event handler which fires immediately before setting an attribute (in contrast to on attrChange, which fires immediately after an attr is updated)
    • custom shapes draw functions are now passed a context to draw onto.
  • Bug Fixes
    • getTransform() now takes into account center offset which fixes a bug related to the getAbsoluteTransform method not working correctly when parent nodes had an offset (Thanks Vijai!)
    • the stage ids and names hashes are now updated correctly whenever a node's id or name changes (thanks Andreas Gerstmayr for getting this started!)
    • Image getWidth() and getHeight() now correctly return width and height regardless if the width and height were set or not during instantiation
    • getContentPosition now correctly takes into account CSS styling (Thanks Yannick!)

v3.10.3 Jul 8 2012

  • New Features
    • new inheritiance model which enables you to more easily extend or add custom methods to Kinetic classes
    • new Text newline support '\n'
    • new clone method which clones any Kinetic object, including the object's user defined event listeners (kicked off by matteo78)
  • Enhancements
    • getIntersections can now be called from any Container, including Groups and Layers.
    • greatly improved Sprite animation performance by hooking into the global animation object
  • Bug Fixes
    • RegularPolygon Shape now generates the correct getters and setters
    • Container remove() method now correctly removes children nodes
    • mouseout is no longer triggered when moving from one node to another node inside the same container
    • stage.on() now correctly binds events
    • getIntersections no longer returns invisible shapes
    • attr change events no longer bubble
    • afterFrame Sprite event handler now correctly fires on the defined index

v3.10.2 Jul 1 2012

  • New Features
    • Text automatic wordwrap is now supported based on width and height properties
    • new Text lineHeight property
    • Text boxes can now have rounded corners
    • Text width and height properties now define the text box width and height
    • new Text getBoxWidth() and getBoxHeight() return the text box dimensions
    • new clearBeforeDraw layer attribute which allows you to skip layer clearing on each draw
  • Enhancements
    • Text align property now reffers to the text alignment inside of the text box. The verticalAlign property has been removed
    • Text shape detection type is now defaulted to path.
    • improved drawing performance
    • you can now unset any attribute with null, 0, or ''. Setting an attribute to undefined will have no effect
    • transition attr updates now trigger attr change events
  • Bug Fixes
    • toJSON() no longer unsets attr functions and images (thanks Jonathan Griggs!)
    • attr change event now correctly fires for root attrs when setting child attr
    • Ellipse radius change no longer fires duplicate attr change event
Clone this wiki locally