Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Berry <bryan@olenepal.org>2009-12-31 12:57:05 (GMT)
committer Bryan Berry <bryan@olenepal.org>2009-12-31 12:57:05 (GMT)
commitfa546f4593ad03b0a51d33b186dd5bdc9a253e35 (patch)
tree2b7295ba1741e42d9a4e30cf7941e1c2c1321a7e
initial commitHEADmaster
-rwxr-xr-xassets/audio/correct.oggbin0 -> 12811 bytes
-rwxr-xr-xassets/image/img1/1.pngbin0 -> 17754 bytes
-rwxr-xr-xassets/image/img1/10.pngbin0 -> 21498 bytes
-rwxr-xr-xassets/image/img1/11.pngbin0 -> 26495 bytes
-rwxr-xr-xassets/image/img1/12.pngbin0 -> 32890 bytes
-rwxr-xr-xassets/image/img1/13.pngbin0 -> 21052 bytes
-rwxr-xr-xassets/image/img1/14.pngbin0 -> 26762 bytes
-rwxr-xr-xassets/image/img1/15.pngbin0 -> 29831 bytes
-rwxr-xr-xassets/image/img1/16.pngbin0 -> 24311 bytes
-rwxr-xr-xassets/image/img1/2.pngbin0 -> 20727 bytes
-rwxr-xr-xassets/image/img1/3.pngbin0 -> 18559 bytes
-rwxr-xr-xassets/image/img1/4.pngbin0 -> 22151 bytes
-rwxr-xr-xassets/image/img1/5.pngbin0 -> 18096 bytes
-rwxr-xr-xassets/image/img1/6.pngbin0 -> 19159 bytes
-rwxr-xr-xassets/image/img1/7.pngbin0 -> 21455 bytes
-rwxr-xr-xassets/image/img1/8.pngbin0 -> 28621 bytes
-rwxr-xr-xassets/image/img1/9.pngbin0 -> 24762 bytes
-rwxr-xr-xassets/image/img1/img1.pngbin0 -> 357550 bytes
-rwxr-xr-xassets/image/img2/1.pngbin0 -> 45701 bytes
-rwxr-xr-xassets/image/img2/10.pngbin0 -> 44321 bytes
-rwxr-xr-xassets/image/img2/11.pngbin0 -> 46721 bytes
-rwxr-xr-xassets/image/img2/12.pngbin0 -> 43808 bytes
-rwxr-xr-xassets/image/img2/13.pngbin0 -> 39899 bytes
-rwxr-xr-xassets/image/img2/14.pngbin0 -> 38773 bytes
-rwxr-xr-xassets/image/img2/15.pngbin0 -> 33499 bytes
-rwxr-xr-xassets/image/img2/16.pngbin0 -> 30825 bytes
-rwxr-xr-xassets/image/img2/2.pngbin0 -> 37293 bytes
-rwxr-xr-xassets/image/img2/3.pngbin0 -> 22713 bytes
-rwxr-xr-xassets/image/img2/4.pngbin0 -> 28222 bytes
-rwxr-xr-xassets/image/img2/5.pngbin0 -> 41372 bytes
-rwxr-xr-xassets/image/img2/6.pngbin0 -> 40929 bytes
-rwxr-xr-xassets/image/img2/7.pngbin0 -> 37334 bytes
-rwxr-xr-xassets/image/img2/8.pngbin0 -> 36705 bytes
-rwxr-xr-xassets/image/img2/9.pngbin0 -> 43462 bytes
-rwxr-xr-xassets/image/img2/img2.pngbin0 -> 610410 bytes
-rwxr-xr-xassets/image/img3/1.pngbin0 -> 31071 bytes
-rwxr-xr-xassets/image/img3/10.pngbin0 -> 42874 bytes
-rwxr-xr-xassets/image/img3/11.pngbin0 -> 44926 bytes
-rwxr-xr-xassets/image/img3/12.pngbin0 -> 45983 bytes
-rwxr-xr-xassets/image/img3/13.pngbin0 -> 47862 bytes
-rwxr-xr-xassets/image/img3/14.pngbin0 -> 48031 bytes
-rwxr-xr-xassets/image/img3/15.pngbin0 -> 48882 bytes
-rwxr-xr-xassets/image/img3/16.pngbin0 -> 41768 bytes
-rwxr-xr-xassets/image/img3/2.pngbin0 -> 26884 bytes
-rwxr-xr-xassets/image/img3/3.pngbin0 -> 33016 bytes
-rwxr-xr-xassets/image/img3/4.pngbin0 -> 33709 bytes
-rwxr-xr-xassets/image/img3/5.pngbin0 -> 40971 bytes
-rwxr-xr-xassets/image/img3/6.pngbin0 -> 40097 bytes
-rwxr-xr-xassets/image/img3/7.pngbin0 -> 41742 bytes
-rwxr-xr-xassets/image/img3/8.pngbin0 -> 44712 bytes
-rwxr-xr-xassets/image/img3/9.pngbin0 -> 45028 bytes
-rwxr-xr-xassets/image/img3/img3.pngbin0 -> 647727 bytes
-rwxr-xr-xcss/lesson.css51
-rwxr-xr-xindex.html28
-rwxr-xr-xindex.html~28
-rwxr-xr-xjs/karma.js1650
-rwxr-xr-xjs/lesson.js218
57 files changed, 1975 insertions, 0 deletions
diff --git a/assets/audio/correct.ogg b/assets/audio/correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/assets/audio/correct.ogg
Binary files differ
diff --git a/assets/image/img1/1.png b/assets/image/img1/1.png
new file mode 100755
index 0000000..228dee5
--- /dev/null
+++ b/assets/image/img1/1.png
Binary files differ
diff --git a/assets/image/img1/10.png b/assets/image/img1/10.png
new file mode 100755
index 0000000..fe2fcd5
--- /dev/null
+++ b/assets/image/img1/10.png
Binary files differ
diff --git a/assets/image/img1/11.png b/assets/image/img1/11.png
new file mode 100755
index 0000000..1ee13fa
--- /dev/null
+++ b/assets/image/img1/11.png
Binary files differ
diff --git a/assets/image/img1/12.png b/assets/image/img1/12.png
new file mode 100755
index 0000000..26bfe83
--- /dev/null
+++ b/assets/image/img1/12.png
Binary files differ
diff --git a/assets/image/img1/13.png b/assets/image/img1/13.png
new file mode 100755
index 0000000..520e86b
--- /dev/null
+++ b/assets/image/img1/13.png
Binary files differ
diff --git a/assets/image/img1/14.png b/assets/image/img1/14.png
new file mode 100755
index 0000000..b9fe502
--- /dev/null
+++ b/assets/image/img1/14.png
Binary files differ
diff --git a/assets/image/img1/15.png b/assets/image/img1/15.png
new file mode 100755
index 0000000..3240769
--- /dev/null
+++ b/assets/image/img1/15.png
Binary files differ
diff --git a/assets/image/img1/16.png b/assets/image/img1/16.png
new file mode 100755
index 0000000..60d1ba0
--- /dev/null
+++ b/assets/image/img1/16.png
Binary files differ
diff --git a/assets/image/img1/2.png b/assets/image/img1/2.png
new file mode 100755
index 0000000..ce9ac3c
--- /dev/null
+++ b/assets/image/img1/2.png
Binary files differ
diff --git a/assets/image/img1/3.png b/assets/image/img1/3.png
new file mode 100755
index 0000000..9531865
--- /dev/null
+++ b/assets/image/img1/3.png
Binary files differ
diff --git a/assets/image/img1/4.png b/assets/image/img1/4.png
new file mode 100755
index 0000000..f436bcd
--- /dev/null
+++ b/assets/image/img1/4.png
Binary files differ
diff --git a/assets/image/img1/5.png b/assets/image/img1/5.png
new file mode 100755
index 0000000..af7f7c4
--- /dev/null
+++ b/assets/image/img1/5.png
Binary files differ
diff --git a/assets/image/img1/6.png b/assets/image/img1/6.png
new file mode 100755
index 0000000..ed048ae
--- /dev/null
+++ b/assets/image/img1/6.png
Binary files differ
diff --git a/assets/image/img1/7.png b/assets/image/img1/7.png
new file mode 100755
index 0000000..b71da02
--- /dev/null
+++ b/assets/image/img1/7.png
Binary files differ
diff --git a/assets/image/img1/8.png b/assets/image/img1/8.png
new file mode 100755
index 0000000..5b32426
--- /dev/null
+++ b/assets/image/img1/8.png
Binary files differ
diff --git a/assets/image/img1/9.png b/assets/image/img1/9.png
new file mode 100755
index 0000000..ca2c60d
--- /dev/null
+++ b/assets/image/img1/9.png
Binary files differ
diff --git a/assets/image/img1/img1.png b/assets/image/img1/img1.png
new file mode 100755
index 0000000..4d0c15b
--- /dev/null
+++ b/assets/image/img1/img1.png
Binary files differ
diff --git a/assets/image/img2/1.png b/assets/image/img2/1.png
new file mode 100755
index 0000000..b85d3cf
--- /dev/null
+++ b/assets/image/img2/1.png
Binary files differ
diff --git a/assets/image/img2/10.png b/assets/image/img2/10.png
new file mode 100755
index 0000000..5b05c21
--- /dev/null
+++ b/assets/image/img2/10.png
Binary files differ
diff --git a/assets/image/img2/11.png b/assets/image/img2/11.png
new file mode 100755
index 0000000..2ad0a9d
--- /dev/null
+++ b/assets/image/img2/11.png
Binary files differ
diff --git a/assets/image/img2/12.png b/assets/image/img2/12.png
new file mode 100755
index 0000000..405154e
--- /dev/null
+++ b/assets/image/img2/12.png
Binary files differ
diff --git a/assets/image/img2/13.png b/assets/image/img2/13.png
new file mode 100755
index 0000000..21d5408
--- /dev/null
+++ b/assets/image/img2/13.png
Binary files differ
diff --git a/assets/image/img2/14.png b/assets/image/img2/14.png
new file mode 100755
index 0000000..632d9c8
--- /dev/null
+++ b/assets/image/img2/14.png
Binary files differ
diff --git a/assets/image/img2/15.png b/assets/image/img2/15.png
new file mode 100755
index 0000000..2acc8e3
--- /dev/null
+++ b/assets/image/img2/15.png
Binary files differ
diff --git a/assets/image/img2/16.png b/assets/image/img2/16.png
new file mode 100755
index 0000000..55603f1
--- /dev/null
+++ b/assets/image/img2/16.png
Binary files differ
diff --git a/assets/image/img2/2.png b/assets/image/img2/2.png
new file mode 100755
index 0000000..f9cecf8
--- /dev/null
+++ b/assets/image/img2/2.png
Binary files differ
diff --git a/assets/image/img2/3.png b/assets/image/img2/3.png
new file mode 100755
index 0000000..f72c8c9
--- /dev/null
+++ b/assets/image/img2/3.png
Binary files differ
diff --git a/assets/image/img2/4.png b/assets/image/img2/4.png
new file mode 100755
index 0000000..3baa0f1
--- /dev/null
+++ b/assets/image/img2/4.png
Binary files differ
diff --git a/assets/image/img2/5.png b/assets/image/img2/5.png
new file mode 100755
index 0000000..21e35dd
--- /dev/null
+++ b/assets/image/img2/5.png
Binary files differ
diff --git a/assets/image/img2/6.png b/assets/image/img2/6.png
new file mode 100755
index 0000000..96cbb6e
--- /dev/null
+++ b/assets/image/img2/6.png
Binary files differ
diff --git a/assets/image/img2/7.png b/assets/image/img2/7.png
new file mode 100755
index 0000000..b009529
--- /dev/null
+++ b/assets/image/img2/7.png
Binary files differ
diff --git a/assets/image/img2/8.png b/assets/image/img2/8.png
new file mode 100755
index 0000000..6e6d65e
--- /dev/null
+++ b/assets/image/img2/8.png
Binary files differ
diff --git a/assets/image/img2/9.png b/assets/image/img2/9.png
new file mode 100755
index 0000000..98b54eb
--- /dev/null
+++ b/assets/image/img2/9.png
Binary files differ
diff --git a/assets/image/img2/img2.png b/assets/image/img2/img2.png
new file mode 100755
index 0000000..cf91a83
--- /dev/null
+++ b/assets/image/img2/img2.png
Binary files differ
diff --git a/assets/image/img3/1.png b/assets/image/img3/1.png
new file mode 100755
index 0000000..d8aa161
--- /dev/null
+++ b/assets/image/img3/1.png
Binary files differ
diff --git a/assets/image/img3/10.png b/assets/image/img3/10.png
new file mode 100755
index 0000000..e5aa0b6
--- /dev/null
+++ b/assets/image/img3/10.png
Binary files differ
diff --git a/assets/image/img3/11.png b/assets/image/img3/11.png
new file mode 100755
index 0000000..a0006f3
--- /dev/null
+++ b/assets/image/img3/11.png
Binary files differ
diff --git a/assets/image/img3/12.png b/assets/image/img3/12.png
new file mode 100755
index 0000000..1ae0a06
--- /dev/null
+++ b/assets/image/img3/12.png
Binary files differ
diff --git a/assets/image/img3/13.png b/assets/image/img3/13.png
new file mode 100755
index 0000000..5018862
--- /dev/null
+++ b/assets/image/img3/13.png
Binary files differ
diff --git a/assets/image/img3/14.png b/assets/image/img3/14.png
new file mode 100755
index 0000000..f96e47a
--- /dev/null
+++ b/assets/image/img3/14.png
Binary files differ
diff --git a/assets/image/img3/15.png b/assets/image/img3/15.png
new file mode 100755
index 0000000..57fc10c
--- /dev/null
+++ b/assets/image/img3/15.png
Binary files differ
diff --git a/assets/image/img3/16.png b/assets/image/img3/16.png
new file mode 100755
index 0000000..67d4454
--- /dev/null
+++ b/assets/image/img3/16.png
Binary files differ
diff --git a/assets/image/img3/2.png b/assets/image/img3/2.png
new file mode 100755
index 0000000..782c956
--- /dev/null
+++ b/assets/image/img3/2.png
Binary files differ
diff --git a/assets/image/img3/3.png b/assets/image/img3/3.png
new file mode 100755
index 0000000..c9d9cd3
--- /dev/null
+++ b/assets/image/img3/3.png
Binary files differ
diff --git a/assets/image/img3/4.png b/assets/image/img3/4.png
new file mode 100755
index 0000000..741c750
--- /dev/null
+++ b/assets/image/img3/4.png
Binary files differ
diff --git a/assets/image/img3/5.png b/assets/image/img3/5.png
new file mode 100755
index 0000000..9babc2f
--- /dev/null
+++ b/assets/image/img3/5.png
Binary files differ
diff --git a/assets/image/img3/6.png b/assets/image/img3/6.png
new file mode 100755
index 0000000..de13592
--- /dev/null
+++ b/assets/image/img3/6.png
Binary files differ
diff --git a/assets/image/img3/7.png b/assets/image/img3/7.png
new file mode 100755
index 0000000..7689919
--- /dev/null
+++ b/assets/image/img3/7.png
Binary files differ
diff --git a/assets/image/img3/8.png b/assets/image/img3/8.png
new file mode 100755
index 0000000..fa5daba
--- /dev/null
+++ b/assets/image/img3/8.png
Binary files differ
diff --git a/assets/image/img3/9.png b/assets/image/img3/9.png
new file mode 100755
index 0000000..88cd312
--- /dev/null
+++ b/assets/image/img3/9.png
Binary files differ
diff --git a/assets/image/img3/img3.png b/assets/image/img3/img3.png
new file mode 100755
index 0000000..21099d1
--- /dev/null
+++ b/assets/image/img3/img3.png
Binary files differ
diff --git a/css/lesson.css b/css/lesson.css
new file mode 100755
index 0000000..a77a19b
--- /dev/null
+++ b/css/lesson.css
@@ -0,0 +1,51 @@
+body {
+ background: #affafc;
+ }
+
+#gamearea{
+ float:right;
+ width: 664px;
+ border: 5px gold dashed;
+ padding: 10px;
+}
+
+#feedback_image #img1,#img2,#img3 {
+ display: none;
+}
+
+.dragme {
+ width: 160px;
+ height: 120px;
+ padding: 1px 3px 0px 3px; /*top right bottom left*/
+ cursor: move;
+
+}
+
+#imageBar{
+ margin-left: 20px;
+ margin-top:15px;
+ float:left;
+ width: 225px;
+ height: 495px;
+ border: 2px solid red;
+
+}
+
+.imageThumb{
+ margin: 5px;
+ width: 200px;
+ height: 138px;
+ border: 2px groove #00FF00;
+ padding: 5px;
+ margin 1em;
+}
+
+.imgMain{
+ width: 640px;
+ height: 480px;
+ float : right;
+ padding : 10px;
+ visibility: hidden;
+ position:relative;
+}
+ \ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100755
index 0000000..46739d0
--- /dev/null
+++ b/index.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title> English_Alphabet Puzzle Solving Game </title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en-us" />
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal,image puzzle" />
+ <link type="image/ico" rel="icon" href="./assets/default/image/favicon.ico" />
+ <link rel="stylesheet" type="text/css" href="css/lesson.css" />
+ <script type="text/javascript" src="./js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="./js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+ </head>
+ <body>
+ <div id = "imageBar">
+ <a href="#" id="anchorImg1"><img class="imageThumb" src="assets/image/img1/img1.png" alt="" /></a>
+ <a href="#" id="anchorImg2"><img class="imageThumb" src="assets/image/img2/img2.png" alt="" /></a>
+ <a href="#" id="anchorImg3"><img class="imageThumb" src="assets/image/img3/img3.png" alt="" /></a>
+ </div>
+ <div id="gamearea">
+ <div id="feedback_image">
+ <img id="img1" src="assets/image/img1/img1.png" alt=""/>
+ <img id="img2" src="assets/image/img2/img2.png" alt=""/>
+ <img id="img3" src="assets/image/img3/img3.png" alt=""/>
+ </div>
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/index.html~ b/index.html~
new file mode 100755
index 0000000..f0cc0fa
--- /dev/null
+++ b/index.html~
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title> English_Alphabet Puzzle Solving Game </title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en-us" />
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal,image puzzle" />
+ <link type="image/ico" rel="icon" href="../../assets/default/image/favicon.ico" />
+ <link rel="stylesheet" type="text/css" href="css/lesson.css" />
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+ </head>
+ <body>
+ <div id = "imageBar">
+ <a href="#" id="anchorImg1"><img class="imageThumb" src="assets/image/img1/img1.png" alt="" /></a>
+ <a href="#" id="anchorImg2"><img class="imageThumb" src="assets/image/img2/img2.png" alt="" /></a>
+ <a href="#" id="anchorImg3"><img class="imageThumb" src="assets/image/img3/img3.png" alt="" /></a>
+ </div>
+ <div id="gamearea">
+ <div id="feedback_image">
+ <img id="img1" src="assets/image/img1/img1.png" alt=""/>
+ <img id="img2" src="assets/image/img2/img2.png" alt=""/>
+ <img id="img3" src="assets/image/img3/img3.png" alt=""/>
+ </div>
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/js/karma.js b/js/karma.js
new file mode 100755
index 0000000..97530d7
--- /dev/null
+++ b/js/karma.js
@@ -0,0 +1,1650 @@
+/* Documentation Note:
+ * Public methods and properties are commented with /** some text *\/
+ * and private methods and properties are commented with //
+ *
+ * Please leave it that way to keep this documentation sane
+ */
+
+
+/*
+* Karma Framework
+* http://karmaeducation.org
+*
+* Copyright (c) 2009
+* Bryan W Berry bryan@olenepal.org
+* Felipe López Toledo zer.subzero@gmail.com
+*
+* Under MIT License:
+* Permission is hereby granted, free of charge, to any person
+* obtaining a copy of this software and associated documentation
+* files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use,
+* copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following
+* conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+* @fileOverview Contains karma library
+* @author Bryan Berry <bryan@olenepal.org>
+* @author Felipe Lopez Toledo <zer.subzero@gmail.com>
+*/
+
+
+//common.js modules use exports object
+if(!this.exports) {
+ exports = {};
+}
+
+
+
+/** Karma is the namespace for the Karma library and Karma() is the constructor
+ * function for the Karma library object Karma.karma.
+ * Karma() checks if the current document type is set to HTML 5, throws
+ * an error if not. Otherwise, initializes the karma object and returns
+ * a reference to that object.
+ * @namespace Global namespace for Karma library
+ * @param {Object} [options={}] options for intializing Karma library
+ * @param {String} [options.locale=''] sets current locale Not Yet Implemented
+ * @param {Array} [options.image=[]] array of images to be converted into a collection
+ * @param {Array} [options.audio=[]] array of audio to be converted into a collection
+ * @param {Array} [options.video=[]] NYI array of videos to be converted into a collection
+ * @param {Array} [options.svg=[]] array of SVG elements to be
+ * converted into a collection. Each SVG element must already exist in the html document
+ * @param {Array} [options.canvas=[]] array of canvas elements
+ * to be converted into a collection. Each canvas element must already exist in the
+ * html document and width and height of each element must be set as attributes
+ * @throws {Error} if the document type declaration is not set to HTML 5, e.g.
+ * <!DOCTYPE html>
+ * @throws {Error} If any of the initialization parameters are invalid values
+ * @returns {Object} Karma.karma -- reference to the initialized Karma library
+ * @example
+ *
+ * var k = Karma({
+ * image: [
+ * {name: "ninja", file: "ninja.png"},
+ * {name: "cowboy", file: "cowboy.png"}
+ * ],
+ * audio: [
+ * {name: "woosh", file: "woosh.ogg"},
+ * {name: "yeehaw", file: "yeehaw.ogg"}
+ * ],
+ * video: [ //Not Yet Implemented
+ * {name: "attack", file: "attack.ogv"},
+ * {name: "ride", file: "ride.ogv"}
+ * ]
+ * canvas: [
+ * {name: "ninja", domId: "ninjaCanvas"},
+ * {name: "cowboy", domId: "cowboyCanvas"}
+ * ],
+ * svg: [
+ * {name: "ninja", domId: "ninjaSvg"},
+ * {name: "cowboy", domId: "cowboySvg"}
+ * ],
+ * });
+ * Next, call the ready function with a callback to your program code
+ *
+ * k.ready(function () { ... your application code . . . }
+ *
+ * after that you can access each asset like so
+ * k.image.ninja;
+ * k.svg.cowboy;
+ * k.audio.yeehaw.play();
+ * k.canvas.ninja.drawImage(k.image.ninja, 0, 0);
+ *
+ */
+var Karma = exports.Karma = function (options) {
+ Karma._isHtml5(document.doctype.nodeName);
+
+ if ( Karma.karma._initialized === true ) {
+ return Karma.karma;
+ } else {
+ return Karma.karma._init(options);
+ }
+};
+
+
+//helper functions
+
+/**This emulates the Object.create method in ecmascript 5 spec
+ * This isn't a full implementation as it doesn't support an all of Object.create's features
+ * This has the same functionality as Crockford's beget method
+ * and this primary building block for prototypal inheritance in
+ * this library
+ * @param {Object} parent that the new object's prototype should point to
+ * @returns {Object} a new object whose prototype is parent
+ * @example
+ *
+ * var ninja = { weapon : "sword" };
+ * var ninja1 = Karma.create(ninja);
+ * ninja1.weapon === "sword"
+ */
+Karma.create = function (parent){
+ function F () {};
+ F.prototype = parent;
+ return new F();
+};
+
+/** Returns a shallow copy of the passed in object
+ * @param {Object} target to be copied
+ * @returns {Object} a shallow copy of target
+ */
+Karma.clone = function (target){
+ var copy = {};
+ for ( var i in target ) {
+ if(target.hasOwnProperty(i)){
+ copy[i] = target[i];
+ }
+ }
+ return copy;
+};
+
+/** Extends properties of the target object with those of
+ * the source object
+ * @param {Object} target object to be extended
+ * @param {Object} source whose properties will extend target
+ * @returns {Object} target extended by source
+ */
+Karma.objectPlus = function (target, source){
+ for ( var i in source){
+ if (source.hasOwnProperty(i)){
+ target[i] = source[i];
+ }
+ }
+ return target;
+};
+
+/** Creates a new object that is a prototype of the first argument
+ * then extends it with the properties of the second argument
+ * @param {Object} parent1 will be prototype of returned object
+ * @param {Object} parent2 will extend properties of returned object
+ * @returns {Object} object that whose prototype is parent1 and has
+ * been extended with properties of parent2
+ */
+Karma.copyObjectPlus = function (parent1, parent2){
+ function F () {};
+ F.prototype = parent1;
+ var G = new F();
+ return Karma.objectPlus(G, parent2);
+};
+
+
+//Throws big ugly error if doctype isn't html5
+Karma._isHtml5 = function (doctype){
+ var regex = new RegExp('^html$', 'i');
+ if(!regex.test(doctype)){
+ var errorMsg = "ERROR: The doctype must be set to <!DOCTYPE html> " +
+ "in order to use Karma. Karma require you use html5";
+ var errorElem = document.createElement('div');
+ errorElem.setAttribute('id', 'errorDoctype');
+ errorElem.innerText = errorMsg;
+ document.body.appendChild(errorElem);
+ throw new Error(errorMsg);
+ }
+};
+
+
+/** Stores global settings for the Karma library
+ * @class This object stores the global settings for the Karma library
+ */
+Karma.karma = {
+ /** This is the global locale as passed to Karma(),
+ * such as "en", "es_SP"
+ * @property {string} locale This is the global locale as passed to Karma()
+ * @default undefined
+ */
+ locale : undefined,
+ /** Collection of images with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ image : {},
+ /** Collection of audio files with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ audio : {},
+ /** Collection of html 5 canvases with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ canvas : {},
+ /** Collection of svgs with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ svg : {},
+ /** Collection of videos with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ video : {},
+ _localized : false,
+ _assetPath : "assets/",
+ _localePath : "",
+ _initialized : false,
+ _statusDiv: undefined,
+ _loaderDiv : undefined,
+ _counters : { total : 0, errors : 0, loaded : 0},
+
+ //This constructs the Karma.karma object per values provided by the user
+ _init: function(options) {
+ this._initialized = true;
+
+ //set up message that show count of assets loaded
+ //and has an ordered list to append error messages to
+ var _statusDiv = this._statusDiv = document.createElement('div');
+ this._loaderDiv = this._loaderDiv = document.createElement('div');
+ var errorList = document.createElement('ol');
+
+ _statusDiv.setAttribute('id', 'karma-status');
+ _statusDiv.setAttribute('style', 'position:absolute;');
+ _statusDiv.innerHTML = 'Karma is loading ...';
+ this._loaderDiv.setAttribute('id', 'karma-loader');
+ this._loaderDiv.setAttribute('class', 'status');
+ errorList.setAttribute('id', 'errorList');
+
+ _statusDiv.appendChild(this._loaderDiv);
+ this._statusDiv.appendChild(errorList);
+ document.body.appendChild(_statusDiv);
+
+ //regular expression that matches the name of aprivate property
+ // the karma object
+ var regexPrivate = new RegExp('^_.*');
+
+ for ( var option in options ) {
+ if (options.hasOwnProperty(option)){
+ if (option === "image" || option === "audio" || option ===
+ "svg" || option === "video" || option === "canvas"){
+
+ if(!(options[option] instanceof Array)){
+ throw new Error("" + option + " must be an array");
+ } else if (options[option].length === 0){
+ continue;
+ }
+ } else if (regexPrivate.test(option)){
+ //don't overwrite a private property of karma object
+ continue;
+ }
+
+ switch (option){
+ case "locale":
+
+ if (this._isValidLocale(options[option])){
+ this.locale = this._normalizeLocale(options[option]);
+ this._localized = true;
+ this._localePath = Karma._computeLocalePath(this.locale);
+ } else {
+ throw new Error("locale provided to karma._init() is invalid");
+ }
+
+ break;
+ case "image":
+ options[option]._type = 'image';
+ Karma._makeCollection(options[option], 'image');
+ break;
+ case "audio":
+ options[option]._type = 'audio';
+ Karma._makeCollection(options[option], 'audio');
+ break;
+ case "video":
+ options[option]._type = 'video';
+ Karma._makeCollection(options[option], 'video');
+ break;
+ case "svg":
+ options[option]._type = 'svg';
+ Karma._makeCollection(options[option], 'svg');
+ break;
+ case "canvas":
+ options[option]._type = 'canvas';
+ Karma._makeCollection(options[option], 'canvas');
+ break;
+ }
+ }
+ }
+
+
+
+ return this;
+ },
+
+ /** Waits until all assets loaded(ready), then calls callback cb
+ * @param {Function} [cb] callback function
+ * @returns this
+ * @throws {Error} if Karma.karma is not initialized with the
+ * Karma({ options }) function
+ * @example
+ *
+ * var k = Karma({ . . . your assets here . . . });
+ * k.ready(function(){ .. your code here . . .});
+ *
+ * your code will not be called until all assets have been loaded
+ * into collections
+ *
+ */
+ ready : function( cb ) {
+ var that = this;
+ if (Karma.karma._initialized !== true){
+ throw new Error("Karma.karma not initialized");
+ }
+
+ if (this._counters.loaded !== this._counters.total){
+ setTimeout(function(){ that.ready(cb);}, 5);
+ } else if (cb) {
+ //hide the "Karma is loading..." message
+ this._statusDiv.setAttribute('style', 'display:none;');
+
+ cb();
+ } else if (!cb) {
+ //hide the "Karma is loading..." message
+ this._statusDiv.setAttribute('style', 'display:none;');
+
+ //if no options passed, show it works message
+ this._showStarterMessage();
+ }
+
+
+
+
+ return this;
+ },
+
+ //Display Apache-like "It works" message if no options
+ _showStarterMessage : function (){
+ var starterMsg = document.createElement('div');
+ starterMsg.setAttribute('id', 'starterMsg');
+ starterMsg.innerHTML = "<h1>It Works</h1>";
+ document.body.appendChild(starterMsg);
+ },
+
+ //Updates visible counter of how many assets are loaded
+ _updateStatus : function (errorMsg) {
+ var loaded = this._counters.loaded;
+ var total = this._counters.total;
+ var errors = this._counters.errors;
+ this._loaderDiv.innerHTML = "Loaded " + loaded + " / " + total +
+ "" + (errors > 0 ? " Errors [ " + errors +" ]" : '');
+ if (errorMsg) {
+ var liError = document.createElement('li');
+ liError.innerHTML = errorMsg;
+ var errorList = document.getElementById('errorList');
+ errorList.appendChild(liError);
+ }
+ },
+
+ //matches 2 letter country code then optionally
+ //a dash or underscore followed by a country or language identifier
+ //i currently only allow a language identifier 2-3 chars long
+ _isValidLocale : function (locale) {
+ var localeRegex = new RegExp('^[a-zA-Z][a-zA-Z]([-_][a-zA-z]{2,3})?$');
+ return localeRegex.test(locale);
+ },
+
+ _normalizeLocale : function(locale) {
+ var lang = "";
+ var country = "";
+ var divider = "";
+
+ lang = locale.slice(0, 2).toLowerCase();
+ divider = "_";
+ country = locale.slice(3, 6).toUpperCase();
+
+ return locale.length > 2 ? "" + lang + divider + country : lang;
+ },
+
+ // Below are geometry and math helper methods
+
+ /**
+ * Converts a value from degrees to radians.
+ * @param {Number} angle The angle in degrees
+ * @returns {Number} The angle in radians
+ */
+ radians : function( angle ){
+ return ( angle / 180 ) * Math.PI;
+ },
+ /**
+ * Gets the square of the Euclidian (ordinary) distance between 2 points.
+ * @param {Object} Point No. 0
+ * @param {Number} Point0.x
+ * @param {Number} Point0.y
+ * @param {Object} Point No. 1
+ * @param {Number} Point1.x
+ * @param {Number} Point1.y
+ * @returns {Number} The square of the Euclidian distance
+ * @example
+ *
+ * p0 = {x:0, y:1};
+ * p1 = {x:50, y:70};
+ * var d = distance2(p0, p1);
+ *
+ */
+ distance2 : function ( p0, p1 ) {
+ return (p1.x - p0.x) * (p1.x - p0.x) + (p1.y - p1.y) * (p1.y - p1.y);
+ },
+ /**
+ * Gets the Euclidian (ordinary) distance between 2 points.<br>
+ * <b>Warning:</b> It's slower than distance2 function
+ * @param {Object} Point No. 0
+ * @param {Number} Point0.x
+ * @param {Number} Point0.y
+ * @param {Object} Point No. 1
+ * @param {Number} Point1.x
+ * @param {Number} Point1.y
+ * @returns {Number} The Euclidian distance
+ * @example
+ *
+ * p0 = {x:0, y:1};
+ * p1 = {x:50, y:70};
+ * var d = distance2(p0, p1);
+ *
+ */
+ distance : function ( p0, p1 ) {
+ return Math.sqrt( this.distance2( p0, p1 ) );
+ },
+ /** Returns a random number within the range provided
+ * @param {Number} lower limit of the range, lowest number that can be returned
+ * @param {Number} upper limit of the range, highest number that can be returned
+ * @returns {Number} number that is >= lower and <= upper
+ * @example
+ *
+ * var num = rand(0, 10);
+ *
+ * //num could be 0, 1, 2, 3 ... or 10
+ *
+ */
+ rand : function ( lower, upper ){
+ return Math.round( Math.random() * (upper - lower) + lower );
+ }
+
+};
+
+//Helper functions for creating assets
+
+Karma._isLocalized = function (boolLocalized) {
+ if (typeof boolLocalized === "boolean" ) {
+ if(boolLocalized === true &&
+ Karma.karma.locale === undefined){
+ throw new Error("You cannot localize a media asset" +
+ " if the global locale for Karma isn't set");
+ } else {
+ return boolLocalized;
+ }
+ } else if (typeof boolLocalized === undefined){
+ return false;
+ } else{
+ throw new Error("This is not a valid value for the localized option");
+ }
+};
+
+Karma._computeLocalePath = function(locale) {
+ return Karma.karma._assetPath + locale + "/";
+};
+
+
+
+
+Karma._makeCollection = function (configs, type){
+ var makeAsset = function (config){
+ var asset = undefined;
+ var target = undefined;
+ switch(type){
+ case "image":
+ target = Karma.kImage;
+ break;
+ case "audio":
+ target = Karma.kAudio;
+ break;
+ case "video":
+ target = Karma.kVideo;
+ break;
+ case "svg":
+ target = Karma.kSvg;
+ break;
+ case "canvas":
+ target = Karma.kCanvas;
+ break;
+ }
+
+ asset = Karma.create(target)._init(config);
+ Karma.karma[type][config.name] = asset;
+ };
+
+ configs.forEach(function(config){ makeAsset(config);});
+};
+
+
+
+
+
+//Prototype objects for assets
+
+
+/** Prototype object for images
+ * @class This object is the prototype for images submitted to Karma in the
+ * Karma() method
+ * @ throws {Error} if the image asset is set to be localized but
+ * the global locale is not set on the Karma.karma object
+ * @ throws {Error} if the name and file properties are not supplied
+ * @example
+ * kImage is the prototype object for images. This 'media' asset is loaded
+ * in a distinctly different way from the canvas or svg assets.
+ *
+ */
+Karma.kImage =
+ {
+ /** file location of image
+ * @type String
+ * @default ""
+ */
+ file : "",
+ /** media object
+ * @type Image
+ * @default undefined
+ */
+ media : undefined,
+ //actual path to the file
+ _path : "",
+ //if using localized version of this image
+ _localized : false,
+ _type : "image",
+ //initializes kImage instance with values provided by user
+ _init : function (image) {
+ image._localized = image._localized || false;
+ Karma.karma._counters.total++;
+
+ if (image.name === undefined || image.file === undefined){
+ throw new Error("properties name and file have to be defined");
+ } else {
+ this.name = image.name;
+ this.file = image.file;
+ }
+
+ this.media = new Image();
+
+ if(Karma._isLocalized(image._localized)){
+ this._localized = image._localized;
+ this._path = Karma.karma._localePath + "image/";
+ } else {
+ this._path = Karma.karma._assetPath + "image/";
+ }
+
+ //IMPORTANT: This one magic line loads the file
+ this.media.src = this.src = this._path + this.file;
+
+ //add event handlers
+ this._addEventHandlers();
+
+
+ return this;
+ },
+ //Adds event handlers to update the counters when
+ //the image is successfully or unsuccessfully loaded
+ _addEventHandlers : function () {
+ var that = this;
+
+ that.media.addEventListener(
+ "load",
+ function (e) {
+ Karma.karma._counters.loaded++;
+ Karma.karma._updateStatus();
+ that.status = "loaded";}, false);
+
+ that.media.addEventListener(
+ "error",
+ function (e) {
+ Karma.karma._counters.errors++;
+ that.status = "error";
+ var errorMsg = "Error: " + that._type.toUpperCase() +
+ " " + that.name + " cannot be loaded.";
+ Karma.karma._updateStatus(errorMsg);
+ },
+ false);
+ that.media.addEventListener(
+ "abort",
+ function (e) {
+ Karma.karma._counters.total++;
+ that.status = "aborted";
+ var errorMsg = "ABORT: " + that._type.toUpperCase() +
+ " " + that.name + " loading was aborted.";
+ Karma.karma._updateStatus(errorMsg);
+
+ }, false);
+ }
+
+};
+
+/** Prototype object for audio files
+ * @class This object is the prototype for audio files submitted to Karma in the
+ * Karma() method
+ * @ throws {Error} if the individual audio asset is set to be localized but
+ * the globale locale is not set on the Karma.karma object
+ * @ throws {Error} if the name and file properties are not supplied
+ * @example
+ * kAudio is the prototype object for audio
+ * The audio assets are loaded in a distinctly different way
+ * from the canvas or svg assets. They also have distinctly different
+ * helper methods
+ *
+ * You initialize the kAudio assets by passing an array of objects
+ */
+Karma.kAudio = {
+ /** file location of asset
+ * @type String
+ * @default ""
+ */
+ file : "",
+ /** Media object. You can access the src, autobuffer, autoplay, loop, and
+ * controls attributes
+ * via the media property of kAudio. Read more about the properties of the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#media-element-attributes">HTML 5 media element</a>
+ * @type Audio
+ * @default undefined
+ */
+ media : undefined,
+ //actual path to the file
+ _path : "",
+ //if using localized version of this asset
+ _localized : false,
+ _type : "audio",
+ //initializes kAudio instance with values provided by user
+ _init : function (audio) {
+ audio._localized = audio._localized || false;
+ Karma.karma._counters.total++;
+
+ if (audio.name === undefined || audio.file === undefined){
+ throw new Error("properties name and file have to be defined");
+ } else {
+ this.name = audio.name;
+ this.file = audio.file;
+ }
+
+ this.media = new Audio();
+
+ if(Karma._isLocalized(audio._localized)){
+ this._localized = audio._localized;
+ this._path = Karma.karma._localePath + "audio/";
+ } else {
+ this._path = Karma.karma._assetPath + "audio/";
+ }
+
+
+ //IMPORTANT: This one magic line loads the file
+ this.media.src = this.src = this._path + this.file;
+
+ //add event handlers
+ this._addEventHandlers();
+
+ if (this._type === "audio"){
+ this.media.autobuffer = true;
+ this.media.load();
+ }
+
+
+ return this;
+ },
+ //Adds event handlers to update the counters when
+ //the asset is successfully or unsuccessfully loaded
+ _addEventHandlers : function () {
+ var that = this;
+ //'canplaythrough' event is a Browser Hack recommended by chromium devs
+ //http://code.google.com/p/chromium/issues/detail?id=20251&q=loading%20audio&colspec=ID%20Stars%20Pri%20Area%20Type%20Status%20Summary%20Modified%20Owner%20Mstone%20OS#c4
+
+ that.media.addEventListener(
+ "canplaythrough",
+ function (e) {
+ Karma.karma._counters.loaded++;
+ Karma.karma._updateStatus();
+ that.status = "loaded";}, false);
+
+ that.media.addEventListener(
+ "error",
+ function (e) {
+ Karma.karma._counters.errors++;
+ that.status = "error";
+ var errorMsg = "Error: " + that._type.toUpperCase() +
+ " " + that.name + " cannot be loaded.";
+ Karma.karma._updateStatus(errorMsg);
+ },
+ false);
+ that.media.addEventListener(
+ "abort",
+ function (e) {
+ Karma.karma._counters.total++;
+ that.status = "aborted";
+ var errorMsg = "ABORT: " + that._type.toUpperCase() +
+ " " + that.name + " loading was aborted.";
+ Karma.karma._updateStatus(errorMsg);
+
+ }, false);
+
+ },
+ /** Plays the audio file */
+ play : function () {
+ this.media.play();
+ }
+
+};
+
+/** NYI:Prototype object for Video files
+ * @class Not Yet Implemented:This object is the prototype for video files submitted
+ * to Karma in the Karma() method
+ * @ throws {Error} if the individual video asset is set to be localized but
+ * the globale locale is not set on the Karma.karma object
+ * @ throws {Error} if the name and file properties are not supplied
+ */
+Karma.kVideo = {
+ /** file location of asset
+ * @type String
+ * @default ""
+ */
+ file : "",
+ /** media object
+ * @type Video
+ * @default undefined
+ */
+ media : undefined,
+ //actual path to the file
+ _path : "",
+ //if using localized version of this asset
+ _localized : false,
+ _type : "video",
+ //initializes kVideo instance with values provided by user
+ _init : function (video) {
+ //Not Yet Implemented
+ Karma.karma._counters.errors++;
+ throw new Error("Video is not Yet Implemented");
+
+ video._localized = video._localized || false;
+ Karma.karma._counters.total++;
+
+ if (video.name === undefined || video.file === undefined){
+ throw new Error("properties name and file have to be defined");
+ } else {
+ this.name = video.name;
+ this.file = video.file;
+ }
+
+ this.media = new Video();
+
+ if(Karma._isLocalized(video._localized)){
+ this._localized = video._localized;
+ this._path = Karma.karma._localePath + "video/";
+ } else {
+ this._path = Karma.karma._assetPath + "video/";
+ }
+
+
+ //IMPORTANT: This one magic line loads the file
+ this.media.src = this.src = this._path + this.file;
+
+ //add event handlers
+ this._addEventHandlers();
+
+ return this;
+ },
+ //Adds event handlers to update the counters when
+ //the asset is successfully or unsuccessfully loaded
+ _addEventHandlers : function () {
+ var that = this;
+ //'canplaythrough' event is a Browser Hack recommended by chromium devs
+ //http://code.google.com/p/chromium/issues/detail?id=20251&q=loading%20audio&colspec=ID%20Stars%20Pri%20Area%20Type%20Status%20Summary%20Modified%20Owner%20Mstone%20OS#c4
+
+ that.media.addEventListener(
+ "canplaythrough",
+ function (e) {
+ Karma.karma._counters.loaded++;
+ Karma.karma._updateStatus();
+ that.status = "loaded";}, false);
+
+ that.media.addEventListener(
+ "error",
+ function (e) {
+ Karma.karma._counters.errors++;
+ that.status = "error";
+ var errorMsg = "Error: " + that._type.toUpperCase() +
+ " " + that.name + " cannot be loaded.";
+ Karma.karma._updateStatus(errorMsg);
+ },
+ false);
+ that.media.addEventListener(
+ "abort",
+ function (e) {
+ Karma.karma._counters.total++;
+ that.status = "aborted";
+ var errorMsg = "ABORT: " + that._type.toUpperCase() +
+ " " + that.name + " loading was aborted.";
+ Karma.karma._updateStatus(errorMsg);
+
+ }, false);
+
+ }
+
+};
+
+
+
+/** Prototype object for each canvas element submitted to Karma in the
+ * Karma() method
+ * @throws {Error} if the name and domId for the canvas element are not specified
+ * @thows {Error} if the supplied domId does not match an element in the DOM
+ * @class This object is the prototype for each canvas element submitted to Karma in the
+ * Karma() method
+ */
+Karma.kCanvas = {
+ /** Name of the canvas, used internally by karma.js
+ * @type String
+ * @default ''
+ */
+ name : '',
+ /** Width of canvas element
+ * @type Number
+ * @default 0
+ */
+ width: 0,
+ /** Height of canvas element
+ * @type Number
+ * @default 0
+ */
+ height: 0,
+ /** Whether canvas is visible
+ * @type boolean
+ * @default true
+ */
+ visible: true,
+ /** Element ID for canvas element in html document. This value is read-only
+ * @type String
+ * @default undefined
+ */
+ domId: undefined,
+ /** Reference to the DOM element
+ * @type DOMElement
+ * @default undefined
+ * @example
+ * //You can access all properties and methods of the underlying DOM element
+ * //using the 'node' property
+ * Karma.karma.canvas.someCanvas.node.dispatchEvent( ... some event ...);
+ * var stuff = Karma.karma.canvas.someCanvas.node.innerHTML;
+ *
+ */
+ node: undefined,
+ /** The 2 Dimensional Rendering context property for this canvas
+ * @type 2DRenderingContext
+ * @default undefined
+ * @example
+ * //Almost all of the context attributes and methods are wrapped in helper functions
+ * //but you can also access them directly using the ctx property
+ * Karma.karma.canvas.someCanvas.ctx.drawImage(someImage, x, y);
+ * Karma.karma.canvas.someCanvas.ctx.fillStyle = "#ffffff";
+ */
+ ctx: undefined,
+
+ //initializes object with values provides by user
+ _init: function (config) {
+ for (var option in config){
+ if (config.hasOwnProperty(option)){
+ switch (option){
+ case "name":
+ this.name = config[option];
+ break;
+ case "domId":
+ this.domId = config[option];
+ break;
+ case "width":
+ if(!this.height){
+ throw new Error("If you specify a width you must also" +
+ "specify a height");
+ }
+ this.width = config[option];
+ break;
+ case "height":
+ if(!this.width){
+ throw new Error("If you specify a height you must also" +
+ "specify a width");
+ }
+ this.height = parseInt(config.option, 10);
+ break;
+ case "fps":
+ this.fps = parseInt(config.option, 10);
+ break;
+ }
+ }
+ }
+
+ if(this.domId && document.getElementById(this.domId)){
+ this.node = document.getElementById(this.domId);
+ this.ctx = this.node.getContext('2d');
+ } else {
+ throw new Error('you must specify a valid domId that' +
+ 'is in your html page');
+ }
+
+ if(!config.height && !config.width){
+ this.width = parseInt(this.node.getAttribute('width'), 10);
+ this.height = parseInt(this.node.getAttribute('height'), 10);
+ }
+
+ return this;
+ },
+ /** Clear area of canvas element specified by parameters, if no
+ * parameters supplied, clears entire canvas
+ * @param {Number} [x=0] x coordinate, defaults to zero if left blank
+ * @param {Number} [y=0] y coordinate, defaults to zero if left blank
+ * @param {Number} [width=0] width of area to be cleared, defaults
+ * entire width of canvas
+ * @param {Number} [height=0] height of area to be cleared, defaults
+ * entire height of canvas
+ * @returns this
+ * @example
+ *
+ * k.canvas.ninja.clear();
+ * // clears the entire ninja canvas
+ *
+ * k.canvas.ninja.clear(0, 10, 20, 30);
+ * //clears a specific portion of the ninja canvas
+ *
+ */
+ clear : function ( x, y, width, height ) {
+ var that = this;
+ that.ctx.clearRect(
+ x || 0,
+ y || 0,
+ width || that.width,
+ height || that.height
+ );
+ return that;
+ },
+
+ /** The globalAlpha attribute gives an alpha value that is applied to shapes
+ * and images before they are composited onto the canvas
+ * @param {Number} number in the range from 0.0 to 1.0
+ * @returns this
+ */
+ globalAlpha : function (attribute){
+ var name = 'globalAlpha';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Sets the globalCompositeOperation attribute, which sets how shapes and images
+ * are drawn onto the existing bitmap, once they have had globalAlpha and the
+ * current transformation matrix applied.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String} globalCompositeOperation source-atop,
+ * source-in, source-out,
+ * source-over, destination-atop, destination-in, destination-out, destination-over,
+ * lighter
+ * @returns this
+ */
+ globalCompositeOperation: function (attribute){
+ var name = ' globalCompositeOperation';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Sets the lineWidth attribute which gives the width of lines, in coordinate space
+ * units.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {Number} lineWidth
+ * @returns this
+ */
+ lineWidth: function (attribute){
+ var name = 'lineWidth';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** The lineCap attribute defines the type of endings that UAs will place on
+ * the end of lines.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String} type butt, round, square
+ * @returns this
+ */
+ lineCap: function (attribute){
+ var name = 'lineCap';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** The lineJoin attribute defines the type of corners that UAs will place
+ * where two lines meet. The three valid values are bevel, round, and miter.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String} type
+ * @returns this
+ */
+ lineJoin: function (attribute){
+ var name = 'lineJoin';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Sets the miter limit
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {Number} number
+ * @returns this
+ */
+ miterLimit: function (attribute){
+ var name = 'miterLimit';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** Sets the font property and takes the same syntax as setting the font property
+ * in CSS
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String}
+ * @returns this
+ */
+ font: function (attribute){
+ var name = 'font';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Changes the text alignment. The possible values are start, end, left, right,
+ * and center. The default is start. Other values are ignored.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {string} alignment
+ * @returns this
+ */
+ textAlign: function (attribute){
+ var name = 'textAlign';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Changes the baseline alignment. If the value is one of top, hanging, middle,
+ * alphabetic, ideographic, or bottom, then the value must be changed to the new value.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String} alignment
+ * @returns this
+ */
+ textBaseline: function (attribute){
+ var name = 'textBaseline';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Save the current state of the context
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ save : function ( ){
+ var name = 'save';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Restore the saved context
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ restore : function ( ){
+ var name = 'restore';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Perform a scale transformation
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ scale : function ( ){
+ var name = 'scale';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Perform a rotation transformation
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ rotate : function ( ){
+ var name = 'rotate';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Performa a translation transformation
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ translate : function ( ){
+ var name = 'translate';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Transform the identity matrix
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ transform : function ( ){
+ var name = 'transform';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Set the transform
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ setTransform : function ( ){
+ var name = 'setTransform';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Clear a rectangular area
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ clearRect : function ( ){
+ var name = 'clearRect';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Fill a rectangular area
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ fillRect : function ( ){
+ var name = 'fillRect';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Draw the outline of the rectangle
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ strokeRect : function ( ){
+ var name = 'strokeRect';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Begin a path
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ beginPath : function ( ){
+ var name = 'beginPath';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** End a path
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ closePath : function ( ){
+ var name = 'closePath';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Move to specified coordinates
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ moveTo : function ( ){
+ var name = 'moveTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+
+ /** Draw a line to the given coordinates
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ lineTo : function ( ){
+ var name = 'lineTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Draw a quadratic curve to given coordinates
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ quadraticCurveTo : function ( ){
+ var name = 'quadraticCurveTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Draw a bezier curve to given coordinates
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ bezierCurveTo : function ( ){
+ var name = 'bezierCurveTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Draw an arc to the given points
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ arcTo : function ( ){
+ var name = 'arcTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Create an arc
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ arc : function ( ){
+ var name = 'arc';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Create a rectangle
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ rect : function ( ){
+ var name = 'rect';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** fill in the current subpaths with the current fillstyle
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ fill : function ( ){
+ var name = 'fill';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Stroke the subpaths
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ stroke : function ( ){
+ var name = 'stroke';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ clip : function ( ){
+ var name = 'clip';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ fillText : function ( ){
+ var name = 'fillText';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ strokeText : function ( ){
+ var name = 'strokeText';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ measureText : function ( ){
+ var name = 'measureText';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ isPointInPath : function ( ){
+ var name = 'isPointInPath';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Sets the stroke style
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ strokeStyle: function (attribute){
+ var name = 'strokeStyle';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Sets the fill style
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ fillStyle: function (attribute){
+ var name = 'fillStyle';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ createLinearGradient : function ( ){
+ var name = 'createLinearGradient';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ createRadialGradient : function ( ){
+ var name = 'createRadialGradient';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ createPattern : function ( ){
+ var name = 'createPattern';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ shadowOffsetX: function (attribute){
+ var name = 'shadowOffsetX';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ shadowOffsetY: function (attribute){
+ var name = 'shadowOffsetY';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ shadowBlur: function (attribute){
+ var name = 'shadowBlur';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ shadowColor: function (attribute){
+ var name = 'shadowColor';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ drawImage : function ( ){
+ var name = 'drawImage';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ getImageData : function ( ){
+ var name = 'getImageData';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ putImageData : function ( ){
+ var name = 'putImageData';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ createImageData : function ( ){
+ var name = 'createImageData';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ drawWindow : function ( ){
+ var name = 'drawWindow';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+
+
+
+};
+
+
+/** Prototype object for each svg element submitted to Karma in the
+ * Karma() method
+ * @throws {Error} if the name and domId for the svg element are not specified
+ * @thows {Error} if the supplied domId does not match an element in the DOM
+ * @class This object is the prototype for each svg element submitted to Karma in the
+ * Karma() method
+ */
+Karma.kSvg = {
+ /** name of instance, used internally
+ * @typeof string
+ * @default ""
+ */
+ name : "",
+ /** width of element
+ * @type number
+ * @default 0
+ */
+ width: 0,
+ /** height of element
+ * @type number
+ * @default 0
+ */
+ height: 0,
+ /** Status of element, either "loaded" or "error"
+ * @type string
+ * @default ""
+ */
+ status: "",
+ /** Whether canvas is visible. This value is read-only
+ * @type boolean
+ * @default true
+ */
+ visible: true,
+ /** Element ID for canvas element in html document.
+ * @type String
+ * @default undefined
+ */
+ domId: undefined,
+ /** Reference to the DOM element.
+ * @type DOMElement
+ * @default undefined
+ * @example
+ * //You can access all properties and methods of the underlying DOM element
+ * //using the 'node' property
+ * Karma.karma.svg.someSvg.node.dispatchEvent;
+ * Karma.karma.svg.someSvg.node.addEvenListener(...);
+ */
+ node: undefined,
+ /** Reference to the SVGDocument. You can use the this.doc to manipulate
+ * the SVG document
+ * @type SVGDocument
+ * @default undefined
+ * @example
+ * var myElem = Karma.karma.svg.someSvg.doc.getElementById('foobar');
+ * Karma.karma.svg.someSvg.doc.createElement(...);
+ * Karma.karma.svg.someSvg.doc.removeChild(someNode);
+ *
+ */
+ doc: undefined,
+ /** Reference to the root element of the SVG Document
+ * @type DocumentElement
+ * @default undefined
+ * @example
+ * // The root element is equivalent to "document" in a regular html document
+ * // The root attribute is used frequently with the jQuery SVG plugin for CSS selectors
+ * $('#someId', Karma.karma.svg.someSvg.root).css(.. manipulate css attributes ...);
+ */
+ root: undefined,
+ _localized : undefined,
+ _init: function (config) {
+ Karma.karma._counters.total++;
+
+ for (var option in config){
+ if (config.hasOwnProperty(option)){
+ switch (option){
+ case "name":
+ this.name = config[option];
+ break;
+ case "domId":
+ this.domId = config[option];
+ break;
+ case "width":
+ if(!this.height){
+ throw new Error("If you specify a width you must also" +
+ "specify a height");
+ }
+ this.width = parseInt(config[option], 10);
+ break;
+ case "height":
+ if(!this.width){
+ throw new Error("If you specify a height you must also" +
+ "specify a width");
+ }
+ this.height = config[option];
+ break;
+ }
+ }
+ }
+
+ if(this.domId && document.getElementById(this.domId)){
+ this.node = document.getElementById(this.domId);
+ } else {
+ throw new Error('you must specify a valid domId that' +
+ 'is in your html page');
+ }
+
+ if(!config.height && !config.width){
+ this.width = parseInt(this.node.getAttribute('width'), 10);
+ this.height = parseInt(this.node.getAttribute('height'), 10);
+ }
+
+ var that = this;
+ that._addEventHandlers();
+
+ return this;
+
+
+ },
+ _addEventHandlers : function () {
+ var that = this;
+ that.doc = that.node.getSVGDocument();
+ that.node.addEventListener(
+ "load",
+ function (e) {
+ that.doc = that.node.getSVGDocument();
+ that.root = that.doc.documentElement;
+ Karma.karma._counters.loaded++;
+ Karma.karma._updateStatus();
+ that.status = "loaded";
+ }, false);
+
+ that.node.addEventListener(
+ "error",
+ function (e) {
+ Karma.karma._counters.loaded--;
+ Karma.karma._counters.errors++;
+ that.status = "error";
+ var errorMsg = "Error: " + that._type.toUpperCase() +
+ " " + that.name + " cannot be loaded.";
+ Karma.karma._updateStatus(errorMsg);
+ },
+ false);
+ that.node.addEventListener(
+ "abort",
+ function (e) {
+ that.status = "aborted";
+ var errorMsg = "ABORT: " + that._type.toUpperCase() +
+ " " + that.name + " loading was aborted.";
+ Karma.karma._updateStatus(errorMsg);
+
+ }, false);
+
+ }
+};
diff --git a/js/lesson.js b/js/lesson.js
new file mode 100755
index 0000000..2e2018a
--- /dev/null
+++ b/js/lesson.js
@@ -0,0 +1,218 @@
+$(document).ready(function() {
+ var k = Karma({
+ audio: [{'name':'correct','file':'correct.ogg'}]});
+
+ k.ready(function(){
+
+ //initialize the variables used and display initial value
+ var drag_no = 0; //store the current dragged no
+ var drop_no = 0; //store the current dropped on no
+ var imgrand = []; //stores the random variables generated
+ var imgPosition = []; //stores the position of the random variable
+ var drag_position = 0; //position of dragged object
+ var drop_position = 0; //position of dropped object
+ var flag, i ,j;
+ var moves_count = 0;
+ var imgPath;
+
+
+ var feedbackImage = $('#feedback_image');
+ for(var i=0; i<16; i++){
+ feedbackImage.append("<img class='dragme' id='imgdrag" +
+ i + "' draggable='true' src='' alt='' />");
+ }
+
+
+ game("img1");
+
+ $('a#anchorImg1').click(function(){
+ $("#"+imgPath+"").hide();
+ $(".dragme").show();
+ game("img1");
+
+
+ });
+
+ $('a#anchorImg2').click(function(){
+ $("#"+imgPath+"").hide();
+ $(".dragme").show();
+ game("img2");
+
+ });
+
+ $('a#anchorImg3').click(function(){
+ $("#"+imgPath+"").hide();
+ $(".dragme").show();
+ game("img3");
+
+ });
+
+ function generate_random_no() { //generate random number
+ var rand_no = Math.ceil(16*Math.random());
+ return rand_no;
+ }
+
+ //update the Random variable number according to the position
+ //update number according to the position and the value
+ function update_Numbers_position(){
+ imgrand[drag_position] = drop_no;
+ imgrand[drop_position] = drag_no;
+ }
+
+ //Check the game over
+ function check_game_over(){
+ var x = 0;
+ for(i=0;i<16;i++){
+ if(imgrand[i] == i+1){
+ x++;
+ }
+ }
+ if(x == 16){ //puzzle solved . Hurray
+ k.audio.correct.play();
+ $(".dragme").hide();
+ $("#"+imgPath+"").fadeIn(5000);
+
+
+ }
+ }
+
+ function game(imgPuzzle){ //draws the necessary random numbers for the game
+ imgPath = imgPuzzle;
+ imgrand[0]=generate_random_no(); //1 number generated, 3 different numbers to be generated
+ for(i=1; i<16; i++){
+ do{
+ flag = 0;
+ imgrand[i] = generate_random_no();
+ for(j=0; j<i; j++){
+ if(imgrand[i]===imgrand[j]){
+ flag++;
+ }
+ }
+ }while(flag != 0 ); //end of do while loop
+ }
+
+ for(i=0; i<16; i++){
+ imgPosition[i] = i;
+ document.getElementById("imgdrag"+i+"").src = "assets/image/"+imgPath+"/"+imgrand[i]+".png";
+ }
+
+ } //end of game()
+ $('#feedback_image').bind('dragstart', function(ev) {
+ if (!$(ev.target).hasClass('dragme'))
+ return true;
+ switch (ev.target.id) {
+ case 'imgdrag0':
+ drag_no = imgrand[0]; drag_position = 0; break;
+ case 'imgdrag1':
+ drag_no = imgrand[1]; drag_position = 1; break;
+ case 'imgdrag2':
+ drag_no = imgrand[2]; drag_position = 2; break;
+ case 'imgdrag3':
+ drag_no = imgrand[3]; drag_position = 3; break;
+ case 'imgdrag4':
+ drag_no = imgrand[4]; drag_position = 4; break;
+ case 'imgdrag5':
+ drag_no = imgrand[5]; drag_position = 5; break;
+ case 'imgdrag6':
+ drag_no = imgrand[6]; drag_position = 6; break;
+ case 'imgdrag7':
+ drag_no = imgrand[7]; drag_position = 7; break;
+ case 'imgdrag8':
+ drag_no = imgrand[8]; drag_position = 8; break;
+ case 'imgdrag9':
+ drag_no = imgrand[9]; drag_position = 9; break;
+ case 'imgdrag10':
+ drag_no = imgrand[10]; drag_position = 10; break;
+ case 'imgdrag11':
+ drag_no = imgrand[11]; drag_position = 11; break;
+ case 'imgdrag12':
+ drag_no = imgrand[12]; drag_position = 12; break;
+ case 'imgdrag13':
+ drag_no = imgrand[13]; drag_position = 13; break;
+ case 'imgdrag14':
+ drag_no = imgrand[14]; drag_position = 14; break;
+ case 'imgdrag15':
+ drag_no = imgrand[15]; drag_position = 15; break;
+ }
+
+ //document.display.dragBox.value = drag_no;
+ //document.display.dragPos.value = drag_position;
+
+ return true;
+ });
+
+ // Set up the drop zone.
+ $('#feedback_image').bind('dragenter', function(ev) { // Update the drop zone class on drag enter/leave
+ if (!$(ev.target).hasClass('dragme')) return true;
+ $(ev.target).addClass('dragover'); return false;
+ })
+
+ .bind('dragleave', function(ev) {
+ if (!$(ev.target).hasClass('dragme')) return true;
+ $(ev.target).removeClass('dragover'); return false;
+ })
+
+ // Allow drops of any kind into the zone.
+ .bind('dragover', function(ev) {
+ if (!$(ev.target).hasClass('dragme')) return true;
+ return false;
+ })
+
+ // Handle the final drop...
+ .bind('drop', function(ev) {
+ if (!$(ev.target).hasClass('dragme')) return true;
+ switch (ev.target.id) {
+ case 'imgdrag0':
+ drop_no = imgrand[0]; drop_position = 0; break;
+ case 'imgdrag1':
+ drop_no = imgrand[1]; drop_position = 1; break;
+ case 'imgdrag2':
+ drop_no = imgrand[2]; drop_position = 2; break;
+ case 'imgdrag3':
+ drop_no = imgrand[3]; drop_position = 3; break;
+ case 'imgdrag4':
+ drop_no = imgrand[4]; drop_position = 4; break;
+ case 'imgdrag5':
+ drop_no = imgrand[5]; drop_position = 5; break;
+ case 'imgdrag6':
+ drop_no = imgrand[6]; drop_position = 6; break;
+ case 'imgdrag7':
+ drop_no = imgrand[7]; drop_position = 7; break;
+ case 'imgdrag8':
+ drop_no = imgrand[8]; drop_position = 8; break;
+ case 'imgdrag9':
+ drop_no = imgrand[9]; drop_position = 9; break;
+ case 'imgdrag10':
+ drop_no = imgrand[10]; drop_position = 10; break;
+ case 'imgdrag11':
+ drop_no = imgrand[11]; drop_position = 11; break;
+ case 'imgdrag12':
+ drop_no = imgrand[12]; drop_position = 12; break;
+ case 'imgdrag13':
+ drop_no = imgrand[13]; drop_position = 13; break;
+ case 'imgdrag14':
+ drop_no = imgrand[14]; drop_position = 14; break;
+ case 'imgdrag15':
+ drop_no = imgrand[15]; drop_position = 15; break;
+ }
+
+ moves_count++;
+ //document.display.dropBox.value = drop_no;
+ //document.display.dropPos.value = drop_position;
+ //document.display.moves.value = moves_count;
+
+ document.getElementById("imgdrag"+imgPosition[drag_position]+"").src = "assets/image/"+imgPath+"/"+drop_no+".png";
+ document.getElementById("imgdrag"+imgPosition[drop_position]+"").src = "assets/image/"+imgPath+"/"+drag_no+".png";
+
+ update_Numbers_position();
+
+
+ //Game over condition
+ check_game_over();
+
+ ev.stopPropagation();
+ return false;
+ });
+
+ });
+}); //end of document.ready