tag:blogger.com,1999:blog-48399312279262523962024-03-19T04:41:56.441+02:00Elad YarkoniWeb, Mobile and Creative IdeasAnonymoushttp://www.blogger.com/profile/13206865524231678679noreply@blogger.comBlogger5125tag:blogger.com,1999:blog-4839931227926252396.post-2788542752107973742012-09-20T15:56:00.000+03:002012-09-24T09:52:56.297+02:00Sublime Text auto-complete plugin development <span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"><b>Introduction</b></span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;"><a href="http://sublimetext.com/">Sublime Text</a> is my favorite code editor, It's very fast and lightweight and I find it very useful for web development.</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Sublime Text has a nice API to create sublime packages (plugins) and today I'm going to show you step by step how to do so.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><span style="font-family: Arial, Helvetica, sans-serif;">For more information, please visit the <a href="http://www.sublimetext.com/docs/2/api_reference.html">Sublime Text API documentation</a>.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"><b>MySignature Plugin</b></span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">The Sublime Text editor comes with default auto-complete feature which contains the words in your current file. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">you cannot auto-complete words from another file and if you have methods in your code (of course you have), it contains only the method names.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">MySignature plugin solves this problem and add to the auto-complete pop-up box methods from all your project files with their signature:</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNGGcilzootbK6mzH-r325lpSeIm9YwHxPj0uS3HHo9RTgr3iiTYqxZugqZe8PGjA_bYtdsIMYcOKKvtqkznusZ6J2O7QhQcoerCkYtElBRfA8T3X9v7eGLIa_w5EHjFlgyBPpLjNpc6s/s1600/Untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNGGcilzootbK6mzH-r325lpSeIm9YwHxPj0uS3HHo9RTgr3iiTYqxZugqZe8PGjA_bYtdsIMYcOKKvtqkznusZ6J2O7QhQcoerCkYtElBRfA8T3X9v7eGLIa_w5EHjFlgyBPpLjNpc6s/s400/Untitled.png" width="400" /></a></div>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">When you choose a method from the pop-up box, It pastes the method with its signature and all you have to do is to replace the method parameters.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"><b>Step By Step AutoComplete Plugin Tutorial</b></span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Plugins in Sublime Text are written in <a href="http://www.python.org/">Python</a>.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">You can view my full plugin code on <a href="https://github.com/eladyarkoni/MySignaturePlugin">MySignature gihub</a>.</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;"><b>Create the plugin folder</b></span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Create your plugin folder inside the sublime plugins folder:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">usually: </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">\Users\<username>\AppData\Roaming\Sublime Text 2\Packages - on windows</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">/Users/<username>/Library/Application Support/Sublime Text 2/Packages - on mac</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Create a new python file inside your plugin directory.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><u>Example</u>:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">mysign.py</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<b style="font-family: Arial, Helvetica, sans-serif;">Listen to Sublime Text events</b><br />
<b style="font-family: Arial, Helvetica, sans-serif;"><br /></b>
<span style="font-family: Arial, Helvetica, sans-serif;">This plugin needs to listen to two Sublime Text events:</span><br />
<ol>
<li><span style="font-family: Arial, Helvetica, sans-serif;">When file is saved - to load all the methods from all files into the memory.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">When auto-complete pop-up box appears - to display the relevant methods inside.</span></li>
</ol>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Create a new class which inherit from sublime_plugin.EventListener (<a href="http://www.sublimetext.com/docs/2/api_reference.html#sublime_plugin.EventListener">see API</a>):</span></div>
<div>
<br /></div>
<pre class="brush:python">class MyPlugin(MySign, sublime_plugin.EventListener):
def on_post_save(self, view):
def on_query_completions(self, view, prefix, locations):
</pre>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">When the plugin is loaded into the memory, <b>on_post_save </b>becomes a callback to file save event and the </span><span style="font-family: Arial, Helvetica, sans-serif;"><b>on_query_completions </b>becomes a callback to auto-complete events. (when you type ctrl+space or type an exists string)<b> </b></span><span style="font-family: Arial, Helvetica, sans-serif; font-weight: bold;"> </span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><b>ON_POST_SAVE(self, view) Method</b></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><b><br /></b></span>
<span style="font-family: Arial, Helvetica, sans-serif;">First, I get all the opened folders in the Sublime Text editor.</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">open_folder_array = view.window().folders()<i> // view represents the sublime current view object.</i> (see <a href="http://www.sublimetext.com/docs/2/api_reference.html#sublime.View">API</a>)</span>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">The next step is to scan all the files inside and load the methods into the memory.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Note that this is a heavy task and the editor may stuck so I uses python thread to do it:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">- Import python thread library: </span><b style="font-family: Arial, Helvetica, sans-serif;">import </b><span style="font-family: Arial, Helvetica, sans-serif;">threading</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
- <span style="font-family: Arial, Helvetica, sans-serif;">Create a new thread class: </span><b style="font-family: Arial, Helvetica, sans-serif;">class </b><span style="font-family: Arial, Helvetica, sans-serif;">MySignCollectorThread(threading.Thread):</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">- Create constructor, send the open_folder_array as a parameter and save it as a class data member.</span>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"></span>
<br />
<pre class="brush:python;">def __init__(self, collector, open_folder_arr, timeout_seconds):
self.collector = collector
self.timeout = timeout_seconds
self.open_folder_arr = open_folder_arr
threading.Thread.__init__(self)
</pre>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">- Implement the 'run' method which is called when the thread is started:</span><br />
<pre class="brush:python;">def run(self):
for folder in self.open_folder_arr:
jsfiles = self.get_javascript_files(folder)
for file_name in jsfiles:
self.save_method_signature(file_name)
</pre>
<span style="font-family: Arial, Helvetica, sans-serif;">- Implement the recursive method <b>get_javascript_files</b> to get all files inside the folder:</span>
<br />
<pre class="brush:py;">def get_javascript_files(self, dir_name, *args):
fileList = []
for file in os.listdir(dir_name):
dirfile = os.path.join(dir_name, file)
if os.path.isfile(dirfile):
fileName, fileExtension = os.path.splitext(dirfile)
if fileExtension == ".js" and ".min." not in fileName: // ignore minified files
fileList.append(dirfile)
elif os.path.isdir(dirfile):
fileList += self.get_javascript_files(dirfile, *args)
return fileList
</pre>
<span style="font-family: Arial, Helvetica, sans-serif;">- Implement the </span><span style="font-family: Arial, Helvetica, sans-serif;">method</span><span style="font-family: Arial, Helvetica, sans-serif;"> </span><b style="font-family: Arial, Helvetica, sans-serif;">save_method_signature</b><span style="font-family: Arial, Helvetica, sans-serif;"> which search the javascript methods inside a specific file and store it inside an array:</span>
<br />
<pre class="brush:py;">def save_method_signature(self, file_name):
file_lines = open(file_name, 'rU')
for line in file_lines:
if "function" in line:
matches = re.search('(\w+)\s*[:|=]\s*function\s*\((.*)\)', line)
if matches != None:
// store the method somewhere
...
...
</pre>
<span style="font-family: Arial, Helvetica, sans-serif;">- Create the thread and run it</span>
<br />
<pre class="brush:py;">if self._collector_thread != None:
self._collector_thread.stop()
self._collector_thread = MySignCollectorThread(self, open_folder_arr, 30)
self._collector_thread.start()
</pre>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><b>ON_QUERY_COMPLETIONS Method</b></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><b><br /></b></span>
<span style="font-family: Arial, Helvetica, sans-serif;">This method is called when auto-complete pop-up box is displayed and this method returns an array with tuples:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">[</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">('<label>', '<text-to-paste>'),</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">...</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">...</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">]</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">The '<label>' represents the label which will be displayed inside the pop-up box.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">This label will be separated with tab ('\t') when the first string is the method signature and the second string is the description (method file in my plugin).</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">The method description will be displayed in italic font. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">- Implements the on_query_completions:</span>
<br />
<pre class="brush:py">def on_query_completions(self, view, prefix, locations):
current_file = view.file_name()
completions = []
if self.get_lang(current_file) == 'javascript':
completions = // get the saved methods from the memory which contains the prefix string
// remove duplicate lines
completions = list(set(completions))
completions.sort()
// return the array
return (completions,sublime.INHIBIT_EXPLICIT_COMPLETIONS)
</pre>
<span style="font-family: Arial, Helvetica, sans-serif;">
- Implements the method <b>get_autocomplete_list</b></span>
<br />
<pre class="brush:py">def get_autocomplete_list(self, word):
autocomplete_list = []
for method_obj in self._functions:
if word in method_obj.name():
method_str_to_append = method_obj.name() + '(' + method_obj.signature()+ ')'
method_file_location = method_obj.filename();
autocomplete_list.append((method_str_to_append + '\t' + method_file_location,method_str_to_append))
return autocomplete_list
</pre>
<span style="font-family: Arial, Helvetica, sans-serif;"><b><br /></b>
<b><span style="font-size: large;">Publish Sublime Text Plugin</span></b><br />
<b><br /></b><a href="http://wbond.net/sublime_packages/package_control">Sublime Package Contro</a>l is a repository of Sublime Text plugins.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSIeuCg8K7M6CxOYmqKu-OPVfxt7PnUh6m9jlwKtP5a3MxNTuQ35TtysbgmAARy8k1cLBh6VWQe9HYJG8_HooZhgwamRJIk4zoBuCeYwRflywVW9bgllUNxficwmtlQCvDR3Bzd8vytoo/s1600/package_manager.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="303" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSIeuCg8K7M6CxOYmqKu-OPVfxt7PnUh6m9jlwKtP5a3MxNTuQ35TtysbgmAARy8k1cLBh6VWQe9HYJG8_HooZhgwamRJIk4zoBuCeYwRflywVW9bgllUNxficwmtlQCvDR3Bzd8vytoo/s400/package_manager.png" width="400" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br />
You can activate it with Ctrl+Shift+P shortcut in the Sublime Text editor, type 'package install' and you get a list of plugins to install with just one click.<br />
<br />
To publish your plugin to the Sublime Package Manager you must store it as a project inside <a href="https://github.com/">Gihub</a>.<br />
<br />
These are the steps to publish your plugin:</span><br />
<ol>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Push your plugin source code to Github as an open source project.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Fork the 'Sublime Package Manager' project from: <a href="https://github.com/wbond/package_control_channel">https://github.com/wbond/package_control_channel</a></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Add your plugin url from github to the repositories.json file:</span></li>
</ol>
<u style="font-family: Arial, Helvetica, sans-serif;">Example:</u></div>
<div>
<pre style="border: 0px; padding: 0px;">{
"schema_version": "1.2",
"repositories": [
... </pre>
<pre style="border: 0px; padding: 0px;"> "https://github.com/eibbors/Bubububububad",
<b> "https://github.com/eladyarkoni/MySignaturePlugin",</b>
"https://github.com/EleazarCrusader/nexus-theme",
...
"package_name_map": {
... </pre>
<pre style="border: 0px; padding: 0px;"> "modx-sublimetext-2": "MODx Revolution Snippets",
<b> "MySignaturePlugin": "Autocomplete Javascript with Method Signature",</b>
"Nette-package-for-Sublime-Text-2": "Nette",
...
}</pre>
<pre style="border: 0px; padding: 0px;"></pre>
<span style="font-family: Arial, Helvetica, sans-serif;">Then, make a pull request with your changes.<br />Wait for your pull request to be approved by <a href="https://github.com/wbond">wbond</a>.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br />That's It, You are now a Sublime Text Plugin Expert :)<br />Very simple, very useful and you can do whatever you want to make your perfect code editor!</span></div>
Anonymoushttp://www.blogger.com/profile/13206865524231678679noreply@blogger.com530tag:blogger.com,1999:blog-4839931227926252396.post-24717554398159343832012-09-05T18:08:00.001+03:002012-09-05T18:08:09.953+03:00Mobifying (Modifying for mobile) your website<br />
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">Hi,</span></div>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">I want to share with you one of my presentations about how to modify your website to work on mobile (tablets and smartphones).</span></div>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">This presentation contains best practices and HTML5 features that you must know in order to make your website perfectly working on mobile devices.</span></div>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">I presented this a year ago at one of my company technology meetings.</span></div>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">Enjoy. </span></div>
<div style="font-size: 13px; line-height: 18px;">
<a data-mce-href="https://docs.google.com/file/d/0B8oPzEnMgNLxTlBEX3dlTzczc2M/preview" href="https://docs.google.com/file/d/0B8oPzEnMgNLxTlBEX3dlTzczc2M/preview" style="color: #007bff;" title="Mobifying your website"><span style="font-family: Arial, Helvetica, sans-serif;">[Presentation link]</span></a></div>
Anonymoushttp://www.blogger.com/profile/13206865524231678679noreply@blogger.com169tag:blogger.com,1999:blog-4839931227926252396.post-48354326796893284552012-09-05T18:06:00.003+03:002012-09-05T18:06:54.490+03:00Draw Something JS - Part #2<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">In my previous post, I talked about how to draw lines with different widths and colors on HTML5 canvas elements, very easy!</span></div>
<div style="font-size: 13px; line-height: 18px;">
<a data-mce-href="http://www2.mta.ac.il/~eladyark/drawsomethingjs/" href="http://www2.mta.ac.il/~eladyark/drawsomethingjs/" style="color: #007bff;" target="_blank" title="View my full demo"><span style="font-family: Arial, Helvetica, sans-serif;">View my full demo</span></a></div>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">In this post, We will discuss about how to record the user movements and "play" it on the canvas.</span></div>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">The main idea is to save each mouse position to an array, loop over the array and paint on the canvas element.</span></div>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">The Array definition in Javascript: </span></div>
<blockquote style="border-left-color: rgb(228, 228, 228); border-left-style: solid; border-left-width: 4px; font-size: 13px; line-height: 18px; margin-left: 30px; padding-left: 15px;">
<span style="font-family: Arial, Helvetica, sans-serif;">var recordDataArray = []; // best practice to use [] instead of new Array();</span></blockquote>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">On each mousedown/mousemove event we need to push to the array the following data:</span></div>
<ul style="font-size: 13px; line-height: 18px;">
<li><span style="font-family: Arial, Helvetica, sans-serif;">mouse x position</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">mouse y position</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">event type (mousedown to begin a new line path or mousemove to continue the line path on the canvas)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">line color</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">line width</span></li>
</ul>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">Define the event type enum in Javascript:</span></div>
<blockquote style="border-left-color: rgb(228, 228, 228); border-left-style: solid; border-left-width: 4px; font-size: 13px; line-height: 18px; margin-left: 30px; padding-left: 15px;">
<span style="font-family: Arial, Helvetica, sans-serif;">var DrawEventType = {</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"> START: 0,</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"> MOVE: 1</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">}</span></blockquote>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">Now, We will modify our functions from the previous post to push the data to the array:</span></div>
<blockquote style="border-left-color: rgb(228, 228, 228); border-left-style: solid; border-left-width: 4px; font-size: 13px; line-height: 18px; margin-left: 30px; padding-left: 15px;">
<span style="font-family: Arial, Helvetica, sans-serif;"> var startPaintWithMouse = function(event) {</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"> mouseState = 1;</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx = board.getContext('2d');</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx.beginPath();</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx.lineWidth = lineWidth;</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx.strokeStyle = color;</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx.moveTo(event.offsetX,event.offsetY);</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> // push to array</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> recordDataArray.push({</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> type: DrawEventType.START,</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> x:event.offsetX,</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> y:event.offsetY,</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> color:color,</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> width:lineWidth</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"> });<span class="Apple-tab-span"></span></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span>};</span></blockquote>
<blockquote style="border-left-color: rgb(228, 228, 228); border-left-style: solid; border-left-width: 4px; font-size: 13px; line-height: 18px; margin-left: 30px; padding-left: 15px;">
<span style="font-family: Arial, Helvetica, sans-serif;">var movePaintWithMouse = function(event) {</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> if (mouseState == 1) {</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> event.preventDefault();</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx = board.getContext('2d');</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx.lineTo(event.offsetX,event.offsetY);</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx.stroke();</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"> recordDataArray.push({</span><span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> type:DrawEventType.MOVE,</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> x:event.offsetX,</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> y:event.offsetY,</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> color:color,</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> width:lineWidth</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> });<span class="Apple-tab-span"></span></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> }</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span>};</span></blockquote>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">We can create a button that clear the canvas.</span></div>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">Clearing the canvas in Javascript is easy too:</span></div>
<blockquote style="border-left-color: rgb(228, 228, 228); border-left-style: solid; border-left-width: 4px; font-size: 13px; line-height: 18px; margin-left: 30px; padding-left: 15px;">
<span style="font-family: Arial, Helvetica, sans-serif;">var brushCtx = board.getContext('2d');</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">brushCtx.clearRect(0, 0, board.width, board.height);</span></blockquote>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">And now, we can create a play button that loop over the array and paint the user movements on the canvas.</span></div>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">We need to use the setInterval javascript method to give the user the drawing experience.</span></div>
<blockquote style="border-left-color: rgb(228, 228, 228); border-left-style: solid; border-left-width: 4px; font-size: 13px; line-height: 18px; margin-left: 30px; padding-left: 15px;">
<span style="font-family: Arial, Helvetica, sans-serif;">var playDataArray = function(dataArray,speed) {</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> var dataIndex = 0;</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> var playInterval = setInterval(function(){</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> if (typeof(dataArray[dataIndex]) == 'object') {</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> drawDataObject(dataArray[dataIndex]);</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> dataIndex++;</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> } else {</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> clearInterval(playInterval);</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> }</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> },speed);</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span>};</span></blockquote>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">On each interval iteration we call the drawDataObject method which gets an object from our array and draw it.</span></div>
<blockquote style="border-left-color: rgb(228, 228, 228); border-left-style: solid; border-left-width: 4px; font-size: 13px; line-height: 18px; margin-left: 30px; padding-left: 15px;">
<span style="font-family: Arial, Helvetica, sans-serif;">var drawDataObject = function(data) {</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> if (data.type == DrawEventType.START) {</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx = board.getContext('2d');</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx.beginPath();</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx.lineWidth = data.width;</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx.strokeStyle = data.color;</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx.moveTo(data.x,data.y);</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> } else if (data.type == DrawEventType.MOVE) {</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx = board.getContext('2d');</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx.lineTo(data.x,data.y);</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> brushCtx.stroke();<span class="Apple-tab-span"></span></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span> }</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span class="Apple-tab-span"></span>};</span></blockquote>
<div style="font-size: 13px; line-height: 18px;">
<span style="font-family: Arial, Helvetica, sans-serif;">That's all!</span></div>
Anonymoushttp://www.blogger.com/profile/13206865524231678679noreply@blogger.com18tag:blogger.com,1999:blog-4839931227926252396.post-48116905774728340942012-09-05T17:58:00.002+03:002012-09-05T17:58:33.536+03:00Draw Something JS - Part #1This is my first post, so please be gentle with your comments :) <div>
Today, You are going to see the power of HTML5 and Javascript and I’m going to show you, step by step, how to create the Great DrawSomething application in Javascript.</div>
<div>
<br /><div>
<a href="http://www2.mta.ac.il/~eladyark/drawsomethingjs/">DrawSomething JS</a> <br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_MuH8vEDlPEN5RU9QEPk-Y35T0ktrNKJImGU-rtvyuIcJ4Er-HW47_cgqa4zzhpIUwn-loOBH8FOtDMaMIzcd5bPIGPNKdbYJfgnSoDBzLoeFtoBJ8tb6OMhmheCF4FLj9XmnDM1poqo/s1600/jsisthefuture.jpg"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_MuH8vEDlPEN5RU9QEPk-Y35T0ktrNKJImGU-rtvyuIcJ4Er-HW47_cgqa4zzhpIUwn-loOBH8FOtDMaMIzcd5bPIGPNKdbYJfgnSoDBzLoeFtoBJ8tb6OMhmheCF4FLj9XmnDM1poqo/s320/jsisthefuture.jpg" /></a><br /><br />Ready?!?! so lets go.<br /><br />The first thing we’re going to learn is how to draw inside your browser:<br /><br />HTML5 has a new element called Canvas, to add a canvas inside your html, you just need to copy this code inside the html page:<br /><br /><canvas id=”board” class=”board” ></canvas><br /><br />To draw inside this canvas with the mouse, we need to listen to three mouse events:<br /><ul>
<li>mousedown - to start drawing the line</li>
<li>mousemove - to continue drawing the line</li>
<li>mouseup - to stop drawing the line</li>
</ul>
<blockquote class="tr_bq">
var board = document.getElementById(“board”);<br />board.addEventListener(“mousedown”,startPaintWithMouse,false);<br />board.addEventListener(“mousemove”,movePaintWithMouse,false);<br />board.addEventListener(“mouseup”,stopPaintWithMouseUp,false);</blockquote>
</div>
<div>
Here are the methods implementation:<br /><blockquote class="tr_bq">
var startPaintWithMouse = function(event) {<br /> brushCtx = board.getContext(‘2d’); // get the context of the canvas<br /> brushCtx.beginPath();<br /> brushCtx.lineWidth = lineWidth; // set line width from variable<br /> brushCtx.strokeStyle = color; // set line color from variable<br /> brushCtx.moveTo(event.offsetX,event.offsetY); // start drawing from this point<br />};</blockquote>
<blockquote class="tr_bq">
var movePaintWithMouse = function(event) {<br /> if (mouseState == 1) {<br /> event.preventDefault();<br /> brushCtx = board.getContext(‘2d’);<br /> brushCtx.lineTo(event.offsetX,event.offsetY); // go to this point and draw<br /> brushCtx.stroke(); // stroke the line<br /> }<br />};</blockquote>
<blockquote class="tr_bq">
var stopPaintWithMouseUp = function(evet) {<br /> mouseState = 0; // set mouse state to 0 to stop the draw<br />};</blockquote>
<br />Now, just add the buttons that change the line width and color and start to draw inside the html5 canvas element.<br />In the next post, We will learn how to record the user movements and to play it, just like the DrawSomething app.</div>
</div>
Anonymoushttp://www.blogger.com/profile/13206865524231678679noreply@blogger.com34tag:blogger.com,1999:blog-4839931227926252396.post-53649210757006117842012-09-05T17:49:00.001+03:002012-09-05T17:49:28.144+03:00My First Post<span style="background-color: white; color: #0b161c; font-family: 'Lucida Grande', Lucida, Verdana, sans-serif; font-size: 12px; font-weight: bold; line-height: 19.200000762939453px;">"It’s really hard to design products by focus groups. A lot of times, people don’t know what they want until you show it to them" (Steve Jobs)</span>Anonymoushttp://www.blogger.com/profile/13206865524231678679noreply@blogger.com645