diff --git a/assets/wordBuildGrid.png b/assets/wordBuildGrid.png new file mode 100755 index 0000000..1c5cf6d Binary files /dev/null and b/assets/wordBuildGrid.png differ diff --git a/editor/help.md b/editor/help.md new file mode 100644 index 0000000..53d6f62 --- /dev/null +++ b/editor/help.md @@ -0,0 +1,26 @@ +**Scribble Pad** + +This will acts a scribble pad (slate) for a child. Use this to teach letter tracing or just scribble any shape. + +--- + +***Change color*** Use color picker to change color and transparency + +***Transparency*** Go to more settings in color picker to set transparency. Make the scribble pad transparent to use it for tracing. + + +--- + +***Actions*** + +Objects on a stage can perform various actions in the content player when user clicks on them. Each action requires a target object to complete the action. Please ensure the target object is present before adding an action. + +We suggest not to attach actions to a scribble pad + +***Pro tip*** + +Place scribble pad over a shape, an image or a text to teach tracing of shapes, letters, and alphabets. + +***Are you a developer?*** + +To get started visit EkStep Developer Community diff --git a/editor/plugin.js b/editor/plugin.js new file mode 100644 index 0000000..8f3321e --- /dev/null +++ b/editor/plugin.js @@ -0,0 +1,97 @@ +/** + * + * Simple plugin to create wordBuildGrid + * @class wordBuildGrid + * @extends EkstepEditor.basePlugin + * + * @author Gourav + * @fires object:modified + */ +EkstepEditor.basePlugin.extend({ + type: "org.ekstep.wordBuildGrid", + initialize: function() {}, + /** + * + * invoked by framework when instantiating plugin instance. + * Creates and adds wordBuildGrid shape to stage. + * @memberof wordBuildGrid + */ + newInstance: function() { + var props = this.convertToFabric(this.attributes), + host = EkstepEditorAPI.getConfig('useProxyForURL') ? EkstepEditorAPI.getConfig('baseURL') : EkstepEditorAPI.getConfig('absURL'); + props.stroke = 1; + props.strokeWidth = 2; + props.strokeDashArray = [5, 5]; + props.fill = this.attributes.fill; + if (this.attributes.type === 'roundrect') { + this.editorObj = new fabric.Rect(props); + this.addMedia({ + id: "org.ekstep.scribblepad.eraser", + src: host + "/assets/public/content/1460624453530trash.png", + assetId: "org.ekstep.scribblepad.eraser", + type: "image", + preload: true + }); + } + }, + /** + * update attributes with shape properties from editorObj. + * + * + * @memberof scribblePad + */ + + updateAttributes: function() { + var instance = this; + var dataList = { "radius": "radius", "opacity": "opacity", "stroke": "stroke", "stroke-width": "stroke-width", "scaleX": "scaleX", "scaleY": "scaleY" }; + if (instance) { + EkstepEditorAPI._.forEach(dataList, function(val, key) { + instance.attributes[key] = instance.editorObj.get(val); + }) + } + }, + /** + * + * update editorObj properties on config change + * + * + * @memberof scribblePad + */ + + onConfigChange: function(key, value) { + if (key === 'color') { + this.editorObj.setFill(value); + this.attributes.fill = value; + } + EkstepEditorAPI.render(); + EkstepEditorAPI.dispatchEvent('object:modified', { target: EkstepEditorAPI.getEditorObject() }); + }, + /** + * set scribblepad properties for ECML + * @override + * @returns {Object} + * ECML properties for scribblepad + * @memberof scribblePad + */ + getAttributes: function() { + var attr = this._super(); + delete attr.strokeDashArray; + attr['stroke-width'] = 1; + attr.thickness = 2; + return attr; + }, + /** + * + * get config data plugin instance + * @returns {Object} + * config object + * @memberof scribblePad + */ + getConfig: function() { + var config = this._super(); + config.color = this.attributes.fill; + config.opacity = this.attributes.opacity * 100; + return config; + } +}); +//# sourceURL=scribblepadplugin.js diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..374902e --- /dev/null +++ b/manifest.json @@ -0,0 +1,66 @@ +{ + "id": "org.ekstep.wordBuildGrid", + "ver": "1.0", + "author": "Gourav More", + "title": "wordBuildGrid Plugin", + "description": "", + "displayName": "wordBuildGrid", + "publishedDate": "", + "editor": { + "main": "editor/plugin.js", + "dependencies": [ + ], + "menu": [{ + "id": "wordBuildGrid", + "category": "main", + "type": "icon", + "toolTip": "Add wordBuildGrid", + "title": "wordBuildGrid", + "iconClass": "icon-wordgrid icon", + "onclick": { + "id": "org.ekstep.wordBuildGrid:create", + "data": { + "type": "roundrect", + "y": 20, + "x": 25, + "fill": "#3399FF", + "w": 27, + "h": 60, + "stroke": "rgba(255, 255, 255, 0)", + "strokeWidth": 1, + "opacity": 0.3 + } + }, + "media": [{ + "id": "eraserImage", + "src": "assets/wordgrid.png", + "type": "image" + }] + }], + "configManifest": [{ + "propertyName": "color", + "title": "Fill color", + "description": "Choose a color from the color picker", + "dataType": "colorpicker", + "required": true, + "defaultValue": "#3399FF" + },{ + "propertyName": "opacity", + "title": "Transparency", + "description": "Set the transparency for element", + "dataType": "rangeslider", + "labelSuffix": "%", + "required": true, + "defaultValue": 30, + "minimumValue": 0, + "maximumValue": 100 + }], + "help": { + "src": "editor/help.md", + "dataType": "text" + } + }, + "renderer": { + "main": "renderer/scribblepadplugin.js" + } +} diff --git a/renderer/wordbuildgridplugin.js b/renderer/wordbuildgridplugin.js new file mode 100644 index 0000000..ffe2f0c --- /dev/null +++ b/renderer/wordbuildgridplugin.js @@ -0,0 +1,113 @@ +Plugin.extend({ + _type: 'org.ekstep.wordgrid', + _isContainer: false, + _render: true, + initPlugin: function(data) { + this.id = _.uniqueId('org.ekstep.wordgrid'); + var instance = this; + var fontsize = data.fontsize || 20; + var dims = this.relativeDims(); + // var solve = true; + + if (div) { + jQuery("#" + data.id).remove(); + } + var div = document.getElementById(data.id); + div = document.createElement('div'); + div.style.width = "100%"; + div.innerHTML = '
'; + + var parentDiv = document.getElementById(Renderer.divIds.gameArea); + parentDiv.insertBefore(div, parentDiv.childNodes[0]); + + this._self = new createjs.DOMElement(div); + var wordsearch_model = instance._stage.getModelValue(data.item); + + var mappedArray = _.map(wordsearch_model.answer, function(val, key) { + return (val.value) + }); + var completeWordsArray = []; + for (i = 0; i < mappedArray.length; i++) { + var individualWordArray = []; + individualWordArray = mappedArray[i].split(","); + completeWordsArray.push(individualWordArray); + } + console.log("completeWordsArray: ", completeWordsArray); + var modDistractors = wordsearch_model.model.distractors || "क,व,खौ,ड़ाा,र,का,ना"; + var objDistractors = modDistractors.split(","); + console.log("objDistractors: ", objDistractors); + + var wordsearch_config = wordsearch_model.model.options || {}; + var wordsearchPlugin_words = []; + + + //splitted words goes here + wordsearchPlugin_splittedWords = completeWordsArray; + //distractors goes Here + wordsearchPlugin_distractors = objDistractors; + + for (i = 0; i < wordsearchPlugin_splittedWords.length; i++) { + wordsearchPlugin_words.push(wordsearchPlugin_splittedWords[i].join("")); + } + + // start a word find game + var gamePuzzle = wordfindgame.create(wordsearchPlugin_words, wordsearchPlugin_splittedWords, '#puzzle', '#words', wordsearch_config, wordsearchPlugin_distractors); + + $('#solve').click(function() { + wordfindgame.solve(gamePuzzle, wordsearchPlugin_words, wordsearchPlugin_splittedWords); + }); + + // Here width and height of individual cells is calculated + var wordsearch_height = Math.floor((dims.h / wordsearch_config.tableRow) - 3); // "-3" to cancel extra padding of the table + var wordsearch_width = Math.floor((dims.w - (dims.w / 12) - (dims.w / 12) - 250) / wordsearch_config.tableColumn); // 250px for words and (dims.w/12) for next and previous buttons + + if (!isNaN(wordsearch_height)) + $('#puzzle .puzzleSquare').css({ + "height": wordsearch_height + }); + + if (!isNaN(wordsearch_width)) + $('#puzzle .puzzleSquare').css({ + "width": wordsearch_width + }); + + // Hide or show solve button + var solve = data.solve; + if (solve === 'undefined' || solve === '') + solve = true; + + if (!solve) + $('#solve').css({ + "visibility": "hidden" + }); + + + //Here x and y position is being calculated + var wordsearch_xPos = dims.w / data.x; + var wordsearch_yPos = dims.h / data.y; + $('#puzzle-wrap').css({ + "margin-left": wordsearch_xPos + }); + $('#puzzle-wrap').css({ + "margin-top": wordsearch_yPos + }); + + // create just a puzzle, without filling in the blanks and print to console + var puzzle = wordfind.newPuzzle( + wordsearchPlugin_words, { + tableRow: 18, + tableColumn: 18, + fillBlanks: false + } + ); + wordfind.print(puzzle); + + + + }, + customEvent: function(data) { + + } +}); + +//# sourceURL=scribbleplugin.js diff --git a/test/editor/plugin.spec.js b/test/editor/plugin.spec.js new file mode 100644 index 0000000..fb48389 --- /dev/null +++ b/test/editor/plugin.spec.js @@ -0,0 +1,67 @@ +'use strict'; +/* +describe('org.ekstep.scribblepad', function() { + var $scope, + plugin, + pluginInstance, + pluginTitle = 'org.ekstep.scribblepad'; + + beforeEach(module('editorApp')); + + beforeEach(inject(function($rootScope, $controller) { + $scope = $rootScope.$new(); + $controller('MainCtrl', { $scope: $scope }); + })); + + beforeEach(function() { + EkstepEditor.pluginManager.loadPlugin(pluginTitle, "1.0"); + }); + + + + it('should be intialized', function() { + EkstepEditor.eventManager.dispatchEvent(pluginTitle + ':create', { + "type": "roundrect", + "y": 20, + "x": 25, + "fill": "#3399FF", + "w": 27, + "h": 60 + }); + pluginInstance = EkstepEditorAPI.getCurrentObject(); + expect(pluginInstance.type).toBe(pluginTitle); + expect(pluginInstance.editorObj).toBeDefined(); + }); + + it('getAttributes should return properties', function() { + var attr = pluginInstance.getAttributes(); + expect(attr.opacity).toBe(0.3); + expect(attr['stroke-width']).toBe(1); + expect(attr['opacity']).toBe(0.3); + expect(attr.stroke).toBe('#663300'); + expect(attr.thickness).toBe(2); + }); + + it('should fire event onConfigChange', function() { + spyOn(EkstepEditorAPI, 'render'); + spyOn(EkstepEditorAPI, 'dispatchEvent'); + pluginInstance.onConfigChange('color', '#663300'); + expect(EkstepEditorAPI.render).toHaveBeenCalled(); + expect(EkstepEditorAPI.dispatchEvent).toHaveBeenCalledWith('object:modified', { target: EkstepEditorAPI.getEditorObject() }); + }); + + it('should have config properties defined', function() { + var config = pluginInstance.getConfig(); + expect(config.color).toBe(pluginInstance.attributes.fill); + }); + + it('should update attributes on updateAttributes', function() { + pluginInstance.updateAttributes(); + var dataList = { "radius": "radius", "opacity": "opacity", "stroke": "stroke", "stroke-width": "stroke-width", "scaleX": "scaleX", "scaleY": "scaleY" }; + _.forEach(dataList, function(val, key) { + expect(pluginInstance.attributes[key]).toBe(pluginInstance.editorObj.get(val)); + }); + }); + +}); +*/ \ No newline at end of file