From 18cc30fe744ce6150a459d69001183379a90cc66 Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Fri, 3 Aug 2018 14:20:28 +0200 Subject: [PATCH] :construction: Part cloning --- src/attributes.js | 8 ++++++++ src/part.js | 39 +++++++++++++++++++++++++++++++++++++++ src/path.js | 26 ++++++++++++++++++++++++++ src/pattern.js | 2 +- src/point.js | 8 ++++++++ src/snippet.js | 8 ++++++++ src/svg.js | 2 -- 7 files changed, 90 insertions(+), 3 deletions(-) diff --git a/src/attributes.js b/src/attributes.js index d6393e7901a..ab8789c4bfc 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -48,4 +48,12 @@ attributes.prototype.renderIfPrefixIs = function(prefix = "") { return svg; }; +/** Returns a deep copy of this */ +attributes.prototype.clone = function() { + let clone = new attributes(); + clone.list = JSON.parse(JSON.stringify(this.list)); + + return clone; +}; + export default attributes; diff --git a/src/part.js b/src/part.js index b65c2888c5a..3dbfbc49c3b 100644 --- a/src/part.js +++ b/src/part.js @@ -15,6 +15,8 @@ function part(id) { this.freeId = 0; this.topLeft = false; this.bottomRight = false; + this.width = false; + this.height = false; this.render = id.substr(0, 1) === "_" ? false : true; this.points.origin = new point(0, 0); for (let k in hooklib) this[k] = hooklib[k]; @@ -77,6 +79,8 @@ part.prototype.boundary = function() { // Add 10mm margin this.topLeft = new point(topLeft.x - 10, topLeft.y - 10); this.bottomRight = new point(bottomRight.x + 10, bottomRight.y + 10); + this.width = this.bottomRight.x - this.topLeft.x; + this.height = this.bottomRight.y - this.topLeft.y; return this; }; @@ -100,4 +104,39 @@ part.prototype.attr = function(name, value) { return this; }; +/** Returns a (deep) clone of this part object */ +part.prototype.clone = function() {}; + +/** Returns a deep copy of this */ +part.prototype.clone = function(id = false) { + let clone = new part(id); + clone.freeId = 0; + clone.width = this.width; + clone.height = this.height; + clone.attributes = this.attributes.clone(); + clone.render = this.render; + + if (!id) clone.id = this.id; + if (this.topLeft) clone.topLeft = this.topLeft.clone(); + else clone.topLeft = false; + if (this.bottomRight) clone.bottomRight = this.bottomRight.clone(); + else clone.bottomRight = false; + + clone.points = {}; + clone.paths = {}; + clone.snippets = {}; + for (let i in this.points) clone.points[i] = this.points[i].clone(); + for (let i in this.paths) clone.paths[i] = this.paths[i].clone(); + for (let i in this.snippets) clone.snippets[i] = this.snippets[i].clone(); + for (let k in hooklib) clone[k] = hooklib[k]; + + clone.point = point; + clone.path = path; + clone.snippet = snippet; + clone.round = round; + + clone.context = this.context; + + return clone; +}; export default part; diff --git a/src/path.js b/src/path.js index 5b7215abb7c..ebf01173fb7 100644 --- a/src/path.js +++ b/src/path.js @@ -152,4 +152,30 @@ path.prototype.boundary = function() { return this; }; + +/** Returns a deep copy of this */ +path.prototype.clone = function() { + let clone = new path(); + clone.render = this.render = true; + if (this.topLeft) clone.topLeft = this.topLeft.clone(); + else clone.topLeft = false; + if (this.bottomRight) clone.bottomRight = this.bottomRight.clone(); + else clone.bottomRight = false; + clone.attributes = this.attributes.clone(); + clone.ops = []; + for (let i in this.ops) { + let op = this.ops[i]; + clone.ops[i] = { type: op.type }; + if (op.type === "move" || op.type === "line") { + clone.ops[i].to = op.to.clone(); + } else if (op.type === "curve") { + clone.ops[i].to = op.to.clone(); + clone.ops[i].cp1 = op.cp1.clone(); + clone.ops[i].cp2 = op.cp2.clone(); + } + } + + return clone; +}; + export default path; diff --git a/src/pattern.js b/src/pattern.js index 2c125b728b7..6bb780d029e 100644 --- a/src/pattern.js +++ b/src/pattern.js @@ -85,7 +85,7 @@ pattern.prototype.render = function() { this.hooks.attach("postRenderSvg", this.svg); //this.hooks.attach('insertText', this.svg); - return this.svg.render(this); + return this.pack().svg.render(this); }; pattern.prototype.on = function(hook, method) { diff --git a/src/point.js b/src/point.js index 395b0fe3a63..113ae14f383 100644 --- a/src/point.js +++ b/src/point.js @@ -108,4 +108,12 @@ point.prototype.shiftOutwards = function(that, distance) { return this.shiftTowards(that, this.dist(that) + distance); }; +/** Returns a deep copy of this */ +point.prototype.clone = function() { + let clone = new point(this.x, this.y); + clone.attributes = this.attributes.clone(); + + return clone; +}; + export default point; diff --git a/src/snippet.js b/src/snippet.js index 00f98ba34a9..2e94324d702 100644 --- a/src/snippet.js +++ b/src/snippet.js @@ -9,4 +9,12 @@ function snippet(def, anchor, description = "") { return this; } +/** Returns a deep copy of this */ +snippet.prototype.clone = function() { + let clone = new snippet(this.def, this.anchor.clone(), this.description); + clone.attributes = this.attributes.clone(); + + return clone; +}; + export default snippet; diff --git a/src/svg.js b/src/svg.js index 7b1e7f4dace..81dbd6be4cd 100644 --- a/src/svg.js +++ b/src/svg.js @@ -41,8 +41,6 @@ svg.prototype.insertText = function() {}; /** Renders a draft object as SVG */ svg.prototype.render = function(pattern) { this.preRenderSvg(); - // this needs to run after the preSvgRender hook as it might add stuff - pattern.pack(); this.attributes.add("width", pattern.width + "mm"); this.attributes.add("height", pattern.height + "mm"); this.attributes.add("viewBox", `0 0 ${pattern.width} ${pattern.height}`);