From 3ca059f4ceaf35c9aab2e7e4364b0759827e6df8 Mon Sep 17 00:00:00 2001 From: Rune Madsen Date: Wed, 17 May 2017 23:40:45 +0200 Subject: [PATCH] This implements changes to Grid to reflect problems in #23 --- CHANGELOG.md | 4 +++ package.json | 2 +- src/grid.js | 27 ++++++++------------ src/group.js | 45 ++++---------------------------- src/mixins/parent.js | 55 ++++++++++++++++++++++++++++++++++++++++ test/shared/grid.js | 14 +++++----- test/shared/rendering.js | 18 +++++++++++++ 7 files changed, 100 insertions(+), 65 deletions(-) create mode 100644 src/mixins/parent.js diff --git a/CHANGELOG.md b/CHANGELOG.md index fb207a2..e2926f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.0 + +- Renamed `Grid.modules` to `Grid.children` and combined functionality with `Rune.Group` + ## 0.4.5 - Added `Rune.map()` function. Thanks to [Yining Shi](http://1023.io/)! diff --git a/package.json b/package.json index ba394a9..87c10e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rune.js", - "version": "0.4.5", + "version": "1.0.0", "description": "A JavaScript library for programming graphic design systems with SVG", "repository": { "type": "git", diff --git a/src/grid.js b/src/grid.js index a4f46ca..48775a1 100644 --- a/src/grid.js +++ b/src/grid.js @@ -3,13 +3,14 @@ var map = require("lodash/collection/map"); var flatten = require("lodash/array/flatten"); var defaults = require("lodash/object/defaults"); var Shape = require("./mixins/shape"); +var Parent = require("./mixins/parent"); var Group = require('./group'); var svg = require('virtual-dom/virtual-hyperscript/svg'); var Grid = function(options) { this.shape(); - this.modules = []; + this.setupParent(); var req = defaults(options || {}, { x:0, @@ -57,44 +58,36 @@ Grid.prototype = { // index is x + (y * width) var index = (column-1) + ((row-1) * this.state.columns) - if(this.modules[index]) { - this.modules[index].add(child) + if(this.children[index]) { + this.children[index].add(child) } else { throw new Error("Column or row does not exist"); } }, getModule: function(column, row) { - // index is x + (y * width) var index = (column-1) + ((row-1) * this.state.columns) - - if(this.modules[index]) - return this.modules[index] + if(this.children[index]) + return this.children[index] else return undefined }, computeGrid: function() { - - this.modules = []; - for(var y = 0; y < this.state.rows; y++) { for(var x = 0; x < this.state.columns; x++) { - var groupX = (x * this.state.moduleWidth) + (x * this.state.gutterWidth); var groupY = (y * this.state.moduleHeight) + (y * this.state.gutterHeight); - - this.modules.push(new Group(groupX, groupY)); + this.addChild(new Group(groupX, groupY)) } } }, render: function(opts) { + if(!this.children || this.children.length == 0) return; var attr = this.shapeAttributes({}); - var groups = map(this.modules, function(module) { - return module.render(opts); - }); + var groups = this.renderChildren(opts); if(opts.debug) groups = groups.concat(this.renderDebug()); return svg('g', attr, flatten(groups, true)); }, @@ -128,6 +121,6 @@ Grid.prototype = { } -assign(Grid.prototype, Shape, { type: "grid" }); +assign(Grid.prototype, Shape, Parent, { type: "grid" }); module.exports = Grid; diff --git a/src/group.js b/src/group.js index 55c9a0e..48724ee 100644 --- a/src/group.js +++ b/src/group.js @@ -1,18 +1,15 @@ -var without = require("lodash/array/without"); var assign = require("lodash/object/assign"); -var flatten = require("lodash/array/flatten"); var each = require("lodash/collection/each"); var map = require("lodash/collection/map"); var Shape = require("./mixins/shape"); +var Parent = require("./mixins/parent"); var Utils = require('./utils'); var Vector = require('./vector'); var svg = require('virtual-dom/virtual-hyperscript/svg'); var Group = function(x, y) { this.shape(); - this.children = []; - this.changedChildren = []; - this.renderedChildren = []; + this.setupParent(); if(typeof x !== 'undefined') this.state.x = x; if(typeof y !== 'undefined') this.state.y = y; } @@ -20,30 +17,11 @@ var Group = function(x, y) { Group.prototype = { add: function(child) { - if(child.parent) child.parent.remove(child); - this.children.push(child); - child.parent = this; - child.childId = this.children.length-1; - child.changed(); + this.addChild(child); }, remove: function(child) { - this.children = without(this.children, child); - this.changedChildren = without(this.changedChildren, child.childId); - - // Lower id's of all children above by one - for(var i = child.childId; i < this.children.length; i++) { - this.children[i].childId--; - } - - // lower id's of all changedChildren by one - for(var i = 0; i < this.changedChildren.length; i++) { - if(this.changedChildren[i] > child.childId) this.changedChildren[i]--; - } - - child.childId = null; - child.parentNotified = false; - child.parent = false; + this.removeChild(child); }, copy: function(parent) { @@ -69,23 +47,10 @@ Group.prototype = { if(!this.children || this.children.length == 0) return; var attr = this.shapeAttributes({}); return svg('g', attr, this.renderChildren(opts)); - }, - - renderChildren: function(opts) { - - // loop through the changed children - while(this.changedChildren.length > 0) { - var childId = this.changedChildren.shift(); - this.renderedChildren[childId] = this.children[childId].render(opts); - this.children[childId].parentNotified = false; - } - - // FIGURE OUT HOW NOT TO FLATTEN EVERY TIME! - return flatten(this.renderedChildren, true); } } -assign(Group.prototype, Shape, {type: "group"}); +assign(Group.prototype, Shape, Parent, {type: "group"}); module.exports = Group; diff --git a/src/mixins/parent.js b/src/mixins/parent.js new file mode 100644 index 0000000..a55400f --- /dev/null +++ b/src/mixins/parent.js @@ -0,0 +1,55 @@ +var without = require("lodash/array/without"); +var flatten = require("lodash/array/flatten"); + +var Parent = { + + setupParent: function() { + this.children = []; + this.changedChildren = []; + this.renderedChildren = []; + }, + + addChild: function(child) { + if(child.parent) child.parent.remove(child); + this.children.push(child); + child.parent = this; + child.childId = this.children.length-1; + child.changed(); + }, + + removeChild: function(child) { + this.children = without(this.children, child); + this.changedChildren = without(this.changedChildren, child.childId); + + // Lower id's of all children above by one + for(var i = child.childId; i < this.children.length; i++) { + this.children[i].childId--; + } + + // lower id's of all changedChildren by one + for(var i = 0; i < this.changedChildren.length; i++) { + if(this.changedChildren[i] > child.childId) this.changedChildren[i]--; + } + + child.childId = null; + child.parentNotified = false; + child.parent = false; + }, + + renderChildren: function(opts) { + + // loop through the changed children + while(this.changedChildren.length > 0) { + var childId = this.changedChildren.shift(); + this.renderedChildren[childId] = this.children[childId].render(opts); + this.children[childId].parentNotified = false; + } + + // FIGURE OUT HOW NOT TO FLATTEN EVERY TIME! + return flatten(this.renderedChildren, true); + } + + +}; + +module.exports = Parent; diff --git a/test/shared/grid.js b/test/shared/grid.js index cafd79e..627cde8 100644 --- a/test/shared/grid.js +++ b/test/shared/grid.js @@ -39,13 +39,13 @@ describe("Rune.Grid", function() { expect(grid.state.width).toEqual(635); expect(grid.state.height).toEqual(280); - expect(grid.modules.length).toBe(50); - expect(grid.modules[0].type).toEqual("group"); - expect(grid.modules[0].state.x).toEqual(0); - expect(grid.modules[0].state.y).toEqual(0); - expect(grid.modules[14].type).toEqual("group"); - expect(grid.modules[14].state.x).toEqual(260); - expect(grid.modules[14].state.y).toEqual(60); + expect(grid.children.length).toBe(50); + expect(grid.children[0].type).toEqual("group"); + expect(grid.children[0].state.x).toEqual(0); + expect(grid.children[0].state.y).toEqual(0); + expect(grid.children[14].type).toEqual("group"); + expect(grid.children[14].state.x).toEqual(260); + expect(grid.children[14].state.y).toEqual(60); }); it("works with gutter shorthand", function() { diff --git a/test/shared/rendering.js b/test/shared/rendering.js index 6cbaad1..e661128 100755 --- a/test/shared/rendering.js +++ b/test/shared/rendering.js @@ -391,6 +391,24 @@ describe("Rendering", function() { }); + it("should rerender when shapes change", function() { + var g = r.grid() + var ellipse = new Rune.Circle(10, 15, 100); + g.add(ellipse, 1, 1) + r.draw(); + + ellipse.move(20, 25); + r.draw(); + + var jellipse = r.el.childNodes[0].childNodes[0].childNodes[0]; + expect(jellipse).toBeTag("circle"); + expect(jellipse).toHaveAttrs({ + cx: 20, + cy: 25 + }); + + }); + }); describe("Debug mode", function() {