Skip to content

Commit

Permalink
Support parallel instance of Dmak FIX #18 Thx @konqi
Browse files Browse the repository at this point in the history
  • Loading branch information
mbilbille committed Feb 26, 2016
1 parent 727478b commit 6276bce
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 108 deletions.
20 changes: 11 additions & 9 deletions demo/basic.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@
<head>
<meta charset="utf-8">
<title>Draw Me A Kanji</title>
<link rel="stylesheet" href="../src/dmak.css"/>
<link rel="stylesheet" href="demo.css"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.2/raphael-min.js"></script>
<script src="../dist/dmak.js"></script>
<script src="../src/dmak.js"></script>
<script src="../src/dmakLoader.js"></script>
</head>
<body>
<div id="draw"></div>
<div id="konnichiha"></div>
<div id="sample-btn">
<button id="p"></button>
<button id="s"></button>
<button id="g"></button>
<button id="n"></button>
<button id="r"></button>
<button id="p">BACK</button>
<button id="s">STOP</button>
<button id="g">PLAY</button>
<button id="n">NEXT</button>
<button id="r">RESET</button>
</div>
<div id="sekai"></div>
<script>
var dmak = new Dmak('電車', {'element': "draw"});
var dmak = new Dmak('こんにちは', {'element': "konnichiha", "uri": "http://kanjivg.tagaini.net/kanjivg/kanji/"});
var p = document.getElementById("p");
p.onclick = function () {
dmak.eraseLastStrokes(1);
Expand All @@ -39,6 +40,7 @@
r.onclick = function () {
dmak.erase();
};
var dmak2 = new Dmak('世界', {'element': "sekai", "stroke": {"attr": {"stroke": "#FF0000"}}, "uri": "http://kanjivg.tagaini.net/kanjivg/kanji/"});
</script>
</body>
</html>
11 changes: 7 additions & 4 deletions demo/demo.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ body {
#sample-btn button {
background-color: #ededed;
border: 1px solid #bbbbbb;
font-size: 30px;
font-size: 15px;
height: 50px;
width: 50px;
cursor: pointer;
}

Expand All @@ -17,6 +16,10 @@ body {
}

svg.dmak-svg {
border: 1px solid #CCCCCC;
margin-right: 1px;
border: 1px solid #CCCCCC;
margin-right: 1px;
}

#konnichiha, #sekai {
margin-top: 30px;
}
109 changes: 62 additions & 47 deletions dist/dmak.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
// Create a safe reference to the DrawMeAKanji object for use below.
var Dmak = function (text, options) {
this.text = text;
this.options = extend(Dmak.options, options);
// Fix #18 clone `default` to support several instance in parallel
this.options = assign(clone(Dmak.default), options);
this.strokes = [];
this.papers = [];
this.pointer = 0;
Expand All @@ -31,7 +32,7 @@
self.prepare(data);

// Execute custom callback "loaded" here
self.options.loaded(self.kanjis);
self.options.loaded(self.strokes);

if (self.options.autoplay) {
self.render();
Expand All @@ -43,7 +44,7 @@
// Current version.
Dmak.VERSION = "0.2.0";

Dmak.options = {
Dmak.default = {
uri: "",
skipLoad: false,
autoplay: true,
Expand Down Expand Up @@ -87,10 +88,13 @@
}
},
loaded: function () {
// a callback
},
erased: function () {
// a callback
},
drew: function () {
// a callback
}
};

Expand All @@ -100,10 +104,10 @@
* Prepare kanjis and papers for rendering.
*/
prepare: function (data) {
this.kanjis = preprocessStrokes(data);
this.papers = giveBirthToRaphael(data.length);
this.strokes = preprocessStrokes(data, this.options);
this.papers = giveBirthToRaphael(data.length, this.options);
if (this.options.grid.show) {
showGrid(this.papers);
showGrid(this.papers, this.options);
}
},

Expand All @@ -127,7 +131,7 @@

do {
this.pointer--;
eraseStroke(this.kanjis[this.pointer], this.timeouts.erasing);
eraseStroke(this.strokes[this.pointer], this.timeouts.erasing, this.options);

// Execute custom callback "erased" here
this.options.erased(this.pointer);
Expand All @@ -147,13 +151,13 @@
}

if (typeof end === "undefined") {
end = this.kanjis.length;
} else if (end > this.kanjis.length) {
end = this.strokes.length;
} else if (end > this.strokes.length) {
return false;
}

var cb = function (that) {
drawStroke(that.papers[that.kanjis[that.pointer].char], that.kanjis[that.pointer], that.timeouts.drawing);
drawStroke(that.papers[that.strokes[that.pointer].char], that.strokes[that.pointer], that.timeouts.drawing, that.options);

// Execute custom callback "drew" here
that.options.drew(that.pointer);
Expand All @@ -171,12 +175,12 @@
}

for (i = this.pointer; i < end; i++) {
if (!Dmak.options.stroke.animated.drawing || delay <= 0) {
if (!this.options.stroke.animated.drawing || delay <= 0) {
cb(this);
} else {
this.timeouts.play.push(setTimeout(cb, delay, this));
}
delay += this.kanjis[i].duration;
delay += this.strokes[i].duration;
}
},

Expand Down Expand Up @@ -214,7 +218,7 @@
* - Maps to a character index
* - Calculates path length
*/
function preprocessStrokes(data) {
function preprocessStrokes(data, options) {
var strokes = [],
stroke,
length,
Expand All @@ -227,7 +231,7 @@
stroke = {
"char": i,
"length": length,
"duration": length * Dmak.options.step * 1000,
"duration": length * options.step * 1000,
"path": data[i][j].path,
"groups" : data[i][j].groups,
"text": data[i][j].text,
Expand All @@ -246,14 +250,14 @@
/**
* Init Raphael paper objects
*/
function giveBirthToRaphael(nbChar) {
function giveBirthToRaphael(nbChar, options) {
var papers = [],
paper,
i;

for (i = 0; i < nbChar; i++) {
paper = new Raphael(Dmak.options.element, Dmak.options.width + "px", Dmak.options.height + "px");
paper.setViewBox(Dmak.options.viewBox.x, Dmak.options.viewBox.y, Dmak.options.viewBox.w, Dmak.options.viewBox.h);
paper = new Raphael(options.element, options.width + "px", options.height + "px");
paper.setViewBox(options.viewBox.x, options.viewBox.y, options.viewBox.w, options.viewBox.h);
paper.canvas.setAttribute("class", "dmak-svg");
papers.push(paper);
}
Expand All @@ -263,19 +267,19 @@
/**
* Draw the background grid
*/
function showGrid(papers) {
function showGrid(papers, options) {
var i;

for (i = 0; i < papers.length; i++) {
papers[i].path("M" + (Dmak.options.viewBox.w / 2) + ",0 L" + (Dmak.options.viewBox.w / 2) + "," + Dmak.options.viewBox.h).attr(Dmak.options.grid.attr);
papers[i].path("M0," + (Dmak.options.viewBox.h / 2) + " L" + Dmak.options.viewBox.w + "," + (Dmak.options.viewBox.h / 2)).attr(Dmak.options.grid.attr);
papers[i].path("M" + (options.viewBox.w / 2) + ",0 L" + (options.viewBox.w / 2) + "," + options.viewBox.h).attr(options.grid.attr);
papers[i].path("M0," + (options.viewBox.h / 2) + " L" + options.viewBox.w + "," + (options.viewBox.h / 2)).attr(options.grid.attr);
}
}

/**
* Remove a single stroke ; deletion can be animated if set as so.
*/
function eraseStroke(stroke, timeouts) {
function eraseStroke(stroke, timeouts, options) {
// In some cases the text object may be null:
// - Stroke order display disabled
// - Stroke already deleted
Expand All @@ -295,9 +299,9 @@
timeouts.shift();
};

if (Dmak.options.stroke.animated.erasing) {
stroke.object.path.node.style.stroke = Dmak.options.stroke.attr.active;
timeouts.push(animateStroke(stroke, -1, cb));
if (options.stroke.animated.erasing) {
stroke.object.path.node.style.stroke = options.stroke.attr.active;
timeouts.push(animateStroke(stroke, -1, options, cb));
}
else {
cb();
Expand All @@ -307,16 +311,16 @@
/**
* Draw a single stroke ; drawing can be animated if set as so.
*/
function drawStroke(paper, stroke, timeouts) {
function drawStroke(paper, stroke, timeouts, options) {
var cb = function() {

// The stroke object may have been already erased when we reach this timeout
if (stroke.object.path === null) {
return;
}

var color = Dmak.options.stroke.attr.stroke;
if(Dmak.options.stroke.attr.stroke === "random") {
var color = options.stroke.attr.stroke;
if(options.stroke.attr.stroke === "random") {
color = Raphael.getColor();
}

Expand All @@ -328,14 +332,14 @@
};

stroke.object.path = paper.path(stroke.path);
stroke.object.path.attr(Dmak.options.stroke.attr);
stroke.object.path.attr(options.stroke.attr);

if (Dmak.options.stroke.order.visible) {
showStrokeOrder(paper, stroke);
if (options.stroke.order.visible) {
showStrokeOrder(paper, stroke, options);
}

if (Dmak.options.stroke.animated.drawing) {
animateStroke(stroke, 1, cb);
if (options.stroke.animated.drawing) {
animateStroke(stroke, 1, options, cb);
}
else {
cb();
Expand All @@ -345,18 +349,18 @@
/**
* Draw a single next to
*/
function showStrokeOrder(paper, stroke) {
function showStrokeOrder(paper, stroke, options) {
stroke.object.text = paper.text(stroke.text.x, stroke.text.y, stroke.text.value);
stroke.object.text.attr(Dmak.options.stroke.order.attr);
stroke.object.text.attr(options.stroke.order.attr);
}

/**
* Animate stroke drawing.
* Based on the great article wrote by Jake Archibald
* http://jakearchibald.com/2013/animated-line-drawing-svg/
*/
function animateStroke(stroke, direction, callback) {
stroke.object.path.attr({"stroke": Dmak.options.stroke.attr.active});
function animateStroke(stroke, direction, options, callback) {
stroke.object.path.attr({"stroke": options.stroke.attr.active});
stroke.object.path.node.style.transition = stroke.object.path.node.style.WebkitTransition = "none";

// Set up the starting positions
Expand All @@ -377,24 +381,35 @@
}

/**
* Simplistic helper function for extending objects
* Helper function to clone an object
*/
function extend(defaults, replacement) {
var result = defaults,
key;
function clone(object) {
if (object === null || typeof object !== "object") {
return object;
}

var temp = object.constructor(); // give temp the original object's constructor
for (var key in object) {
temp[key] = clone(object[key]);
}

return temp;
}

/**
* Helper function to copy own properties over to the destination object.
*/
function assign(source, replacement) {
if (arguments.length !== 2) {
throw new Error("Missing arguments in extend function");
throw new Error("Missing arguments in assign function");
}

for (key in replacement) {
if (typeof result[key] === "object") {
result[key] = extend(result[key], replacement[key]);
} else if (result.hasOwnProperty(key)) {
result[key] = replacement[key];
for (var key in source) {
if (replacement.hasOwnProperty(key)) {
source[key] = (typeof replacement[key] === "object") ? assign(source[key], replacement[key]) : replacement[key];
}
}
return result;
return source;
}

window.Dmak = Dmak;
Expand Down
Loading

0 comments on commit 6276bce

Please sign in to comment.