1import{S as Qe,i as ao,s as so,l,r as o,a as u,m as c,n as i,u as p,h as s,c as r,p as k,Z as He,b as e,F as n,B as Wt}from"./index-7fbbe144.js";function no(Le){let y,Zs,za,Y,$s,Ua,b,Qs,H,an,sn,Ya,V,nn,Va,X,da,Bt,Xa,j,tn,ja,K,en,Ka,L,Me=`<code class="language-sh">ionic start devdacticImageCanvas blank 2cd devdacticImageCanvas 3ionic cordova plugin add cordova-sqlite-storage 4ionic cordova plugin add cordova-plugin-file 5npm install --save @ionic-native/file</code>`,Ja,E,on,ma,pn,ln,Za,M,We=`<code class="language-ts"><span class="token keyword">import</span> <span class="token punctuation">{</span> BrowserModule <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@angular/platform-browser'</span><span class="token punctuation">;</span> 6<span class="token keyword">import</span> <span class="token punctuation">{</span> ErrorHandler<span class="token punctuation">,</span> NgModule <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@angular/core'</span><span class="token punctuation">;</span> 7<span class="token keyword">import</span> <span class="token punctuation">{</span> IonicApp<span class="token punctuation">,</span> IonicErrorHandler<span class="token punctuation">,</span> IonicModule <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'ionic-angular'</span><span class="token punctuation">;</span> 8<span class="token keyword">import</span> <span class="token punctuation">{</span> SplashScreen <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@ionic-native/splash-screen'</span><span class="token punctuation">;</span> 9<span class="token keyword">import</span> <span class="token punctuation">{</span> StatusBar <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@ionic-native/status-bar'</span><span class="token punctuation">;</span> 10 11<span class="token keyword">import</span> <span class="token punctuation">{</span> MyApp <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'./app.component'</span><span class="token punctuation">;</span> 12<span class="token keyword">import</span> <span class="token punctuation">{</span> HomePage <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'../pages/home/home'</span><span class="token punctuation">;</span> 13 14<span class="token keyword">import</span> <span class="token punctuation">{</span> File <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@ionic-native/file'</span><span class="token punctuation">;</span> 15<span class="token keyword">import</span> <span class="token punctuation">{</span> IonicStorageModule <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@ionic/storage'</span><span class="token punctuation">;</span> 16 17<span class="token decorator"><span class="token at operator">@</span><span class="token function">NgModule</span></span><span class="token punctuation">(</span><span class="token punctuation">{</span> 18 declarations<span class="token operator">:</span> <span class="token punctuation">[</span> 19 MyApp<span class="token punctuation">,</span> 20 HomePage 21 <span class="token punctuation">]</span><span class="token punctuation">,</span> 22 imports<span class="token operator">:</span> <span class="token punctuation">[</span> 23 BrowserModule<span class="token punctuation">,</span> 24 IonicModule<span class="token punctuation">.</span><span class="token function">forRoot</span><span class="token punctuation">(</span>MyApp<span class="token punctuation">)</span><span class="token punctuation">,</span> 25 IonicStorageModule<span class="token punctuation">.</span><span class="token function">forRoot</span><span class="token punctuation">(</span><span class="token punctuation">)</span> 26 <span class="token punctuation">]</span><span class="token punctuation">,</span> 27 bootstrap<span class="token operator">:</span> <span class="token punctuation">[</span>IonicApp<span class="token punctuation">]</span><span class="token punctuation">,</span> 28 entryComponents<span class="token operator">:</span> <span class="token punctuation">[</span> 29 MyApp<span class="token punctuation">,</span> 30 HomePage 31 <span class="token punctuation">]</span><span class="token punctuation">,</span> 32 providers<span class="token operator">:</span> <span class="token punctuation">[</span> 33 StatusBar<span class="token punctuation">,</span> 34 SplashScreen<span class="token punctuation">,</span> 35 <span class="token punctuation">{</span>provide<span class="token operator">:</span> ErrorHandler<span class="token punctuation">,</span> useClass<span class="token operator">:</span> IonicErrorHandler<span class="token punctuation">}</span><span class="token punctuation">,</span> 36 File 37 <span class="token punctuation">]</span> 38<span class="token punctuation">}</span><span class="token punctuation">)</span> 39<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">AppModule</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></code>`,$a,J,cn,Qa,Z,un,as,_,rn,ga,kn,fn,ss,I,hn,wa,dn,mn,ns,$,gn,ts,C,wn,va,vn,yn,es,W,Be=`<code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-header</span><span class="token punctuation">></span></span> 40 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-navbar</span> <span class="token attr-name">color</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>primary<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> 41 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-title</span><span class="token punctuation">></span></span> 42 Ionic Canvas 43 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-title</span><span class="token punctuation">></span></span> 44 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-navbar</span><span class="token punctuation">></span></span> 45<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-header</span><span class="token punctuation">></span></span> 46 47<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-content</span> <span class="token attr-name">padding</span> <span class="token attr-name">no-bounce</span><span class="token punctuation">></span></span> 48 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">#fixedContainer</span> <span class="token attr-name">ion-fixed</span><span class="token punctuation">></span></span> 49 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-row</span><span class="token punctuation">></span></span>
50 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-col</span> <span class="token attr-name">*ngFor</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>let color of colors<span class="token punctuation">"</span></span> <span class="token attr-name">[style.background]</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>color<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>color-block<span class="token punctuation">"</span></span> <span class="token attr-name">tappable</span> <span class="token attr-name">(click)</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>selectColor(color)<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-col</span><span class="token punctuation">></span></span> 51 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-row</span><span class="token punctuation">></span></span> 52 53 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-row</span> <span class="token attr-name">radio-group</span> <span class="token attr-name">[(ngModel)]</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>selectedColor<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> 54 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-col</span> <span class="token attr-name">*ngFor</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>let color of colors<span class="token punctuation">"</span></span> <span class="token attr-name">text-center</span><span class="token punctuation">></span></span> 55 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-radio</span> <span class="token attr-name">[value]</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>color<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-radio</span><span class="token punctuation">></span></span> 56 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-col</span><span class="token punctuation">></span></span> 57 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-row</span><span class="token punctuation">></span></span> 58 59 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>canvas</span> <span class="token attr-name">#imageCanvas</span> <span class="token attr-name">(touchstart)</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>startDrawing($event)<span class="token punctuation">"</span></span> <span class="token attr-name">(touchmove)</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>moved($event)<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>canvas</span><span class="token punctuation">></span></span> 60 61 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span> <span class="token attr-name">ion-button</span> <span class="token attr-name">full</span> <span class="token attr-name">(click)</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>saveCanvasImage()<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Save Image<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span> 62 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span> 63 64 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-list</span> <span class="token attr-name">*ngIf</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>storedImages.length > 0<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> 65 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-list-header</span><span class="token punctuation">></span></span>Previous Drawings<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-list-header</span><span class="token punctuation">></span></span> 66 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-card</span> <span class="token attr-name">*ngFor</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>let obj of storedImages; let i = index<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
67 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-card-content</span><span class="token punctuation">></span></span> 68 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>img</span> <span class="token attr-name">[src]</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>getImagePath(obj.img)<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> 69 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-card-content</span><span class="token punctuation">></span></span> 70 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-row</span><span class="token punctuation">></span></span> 71 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span> <span class="token attr-name">ion-button</span> <span class="token attr-name">full</span> <span class="token attr-name">icon-only</span> <span class="token attr-name">color</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>danger<span class="token punctuation">"</span></span> <span class="token attr-name">(click)</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>removeImageAtIndex(i)<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> 72 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ion-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>trash<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-icon</span><span class="token punctuation">></span></span> 73 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span> 74 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-row</span><span class="token punctuation">></span></span> 75 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-card</span><span class="token punctuation">></span></span> 76 <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-list</span><span class="token punctuation">></span></span> 77 78<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ion-content</span><span class="token punctuation">></span></span></code>`,os,P,bn,ya,En,_n,ps,B,qe=`<code class="language-undefined">page-home { 79 canvas { 80 display: block; 81 border: 1px solid rgb(187, 178, 178); 82 } 83 .color-block { 84 height: 40px; 85 } 86}</code>`,ls,Q,In,cs,aa,Cn,is,sa,Pn,us,T,Tn,ba,Sn,xn,rs,S,On,Ea,Rn,An,ks,x,Nn,_a,Dn,Fn,fs,O,Gn,Ia,Hn,Ln,hs,q,ze=`<code class="language-ts"><span class="token keyword">import</span> <span class="token punctuation">{</span> Component<span class="token punctuation">,</span> ViewChild<span class="token punctuation">,</span> Renderer <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@angular/core'</span><span class="token punctuation">;</span> 87<span class="token keyword">import</span> <span class="token punctuation">{</span> NavController<span class="token punctuation">,</span> Platform<span class="token punctuation">,</span> normalizeURL<span class="token punctuation">,</span> Content <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'ionic-angular'</span><span class="token punctuation">;</span> 88<span class="token keyword">
88import</span> <span class="token punctuation">{</span> File<span class="token punctuation">,</span> IWriteOptions <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@ionic-native/file'</span><span class="token punctuation">;</span> 89<span class="token keyword">import</span> <span class="token punctuation">{</span> Storage <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@ionic/storage'</span><span class="token punctuation">;</span> 90 91<span class="token keyword">const</span> <span class="token constant">STORAGE_KEY</span> <span class="token operator">=</span> <span class="token string">'IMAGE_LIST'</span><span class="token punctuation">;</span> 92 93<span class="token decorator"><span class="token at operator">@</span><span class="token function">Component</span></span><span class="token punctuation">(</span><span class="token punctuation">{</span> 94 selector<span class="token operator">:</span> <span class="token string">'page-home'</span><span class="token punctuation">,</span> 95 templateUrl<span class="token operator">:</span> <span class="token string">'home.html'</span> 96<span class="token punctuation">}</span><span class="token punctuation">)</span> 97<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">HomePage</span> <span class="token punctuation">{</span> 98 <span class="token comment">// Canvas stuff</span> 99 <span class="token decorator"><span class="token at operator">@</span><span class="token function">ViewChild</span></span><span class="token punctuation">(</span><span class="token string">'imageCanvas'</span><span class="token punctuation">)</span> canvas<span class="token operator">:</span> <span class="token builtin">any</span><span class="token punctuation">;</span> 100 canvasElement<span class="token operator">:</span> <span class="token builtin">any</span><span class="token punctuation">;</span> 101 102 saveX<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> 103 saveY<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span> 104 105 storedImages <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> 106 107 <span class="token comment">// Make Canvas sticky at the top stuff</span> 108 <span class="token decorator"><span class="token at operator">@</span><span class="token function">ViewChild</span></span><span class="token punctuation">(</span>Content<span class="token punctuation">)</span> content<span class="token operator">:</span> Content<span class="token punctuation">;</span> 109 <span class="token decorator"><span class="token at operator">@</span><span class="token function">ViewChild</span></span><span class="token punctuation">(</span><span class="token string">'fixedContainer'</span><span class="token punctuation">)</span> fixedContainer<span class="token operator">:</span> <span class="token builtin">any</span><span class="token punctuation">;</span> 110 111 <span class="token comment">// Color Stuff</span> 112 selectedColor <span class="token operator">=</span> <span class="token string">'#9e2956'</span><span class="token punctuation">;</span> 113 114 colors <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">'#9e2956'</span><span class="token punctuation">,</span> <span class="token string">'#c2281d'</span><span class="token punctuation">,</span> <span class="token string">'#de722f'</span><span class="token punctuation">,</span> <span class="token string">'#edbf4c'</span><span class="token punctuation">,</span> <span class="token string">'#5db37e'</span><span class="token punctuation">,</span> <span class="token string">'#459cde'</span><span class="token punctuation">,</span> <span class="token string">'#4250ad'</span><span class="token punctuation">,</span> <span class="token string">'#802fa3'</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> 115 116 <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token keyword">public</span> navCtrl<span class="token operator">:</span> NavController<span class="token punctuation">,</span> <span class="token keyword">private</span> file<span class="token operator">:</span> File<span class="token punctuation">,</span> <span class="token keyword">private</span> storage<span class="token operator">:</span> Storage<span class="token punctuation">,</span> <span class="token keyword">public</span> renderer<span class="token operator">:</span> Renderer<span class="token punctuation">,</span> <span class="token keyword">private</span> plt<span class="token operator">:</span>
116 Platform<span class="token punctuation">)</span> <span class="token punctuation">{</span> 117 <span class="token comment">// Load all stored images when the app is ready</span> 118 <span class="token keyword">this</span><span class="token punctuation">.</span>storage<span class="token punctuation">.</span><span class="token function">ready</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> 119 <span class="token keyword">this</span><span class="token punctuation">.</span>storage<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token constant">STORAGE_KEY</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>data <span class="token operator">=></span> <span class="token punctuation">{</span> 120 <span class="token keyword">if</span> <span class="token punctuation">(</span>data <span class="token operator">!=</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> 121 <span class="token keyword">this</span><span class="token punctuation">.</span>storedImages <span class="token operator">=</span> data<span class="token punctuation">;</span> 122 <span class="token punctuation">}</span> 123 <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 124 <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 125 <span class="token punctuation">}</span> 126 127 <span class="token function">ionViewDidEnter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> 128 <span class="token comment">// https://github.com/ionic-team/ionic/issues/9071#issuecomment-362920591</span> 129 <span class="token comment">// Get the height of the fixed item</span> 130 <span class="token keyword">let</span> itemHeight <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>fixedContainer<span class="token punctuation">.</span>nativeElement<span class="token punctuation">.</span>offsetHeight<span class="token punctuation">;</span> 131 <span class="token keyword">let</span> scroll <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>content<span class="token punctuation">.</span><span class="token function">getScrollElement</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 132 133 <span class="token comment">// Add preexisting scroll margin to fixed container size</span> 134 itemHeight <span class="token operator">=</span> Number<span class="token punctuation">.</span><span class="token function">parseFloat</span><span class="token punctuation">(</span>scroll<span class="token punctuation">.</span>style<span class="token punctuation">.</span>marginTop<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">"px"</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">+</span> itemHeight<span class="token punctuation">;</span> 135 scroll<span class="token punctuation">.</span>style<span class="token punctuation">.</span>marginTop <span class="token operator">=</span> itemHeight <span class="token operator">+</span> <span class="token string">'px'</span><span class="token punctuation">;</span> 136 <span class="token punctuation">}</span> 137 138 <span class="token function">ionViewDidLoad</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> 139 <span class="token comment">// Set the Canvas Element and its size</span> 140 <span class="token keyword">this</span><span class="token punctuation">.</span>canvasElement <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>canvas<span class="token punctuation">.</span>nativeElement<span class="token punctuation">;</span> 141 <span class="token keyword">this</span><span class="token punctuation">.</span>canvasElement<span class="token punctuation">.</span>width <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>plt<span class="token punctuation">.</span><span class="token function">width</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">''</span><span class="token punctuation">;</span> 142 <span class="token keyword">this</span><span class="token punctuation">.</span>canvasElement<span class="token punctuation">.</span>height <span class="token operator">=</span> <span class="token number">200</span><span class="token punctuation">;</span> 143 <span class="token punctuation">}</span> 144 145<span class="token punctuation">}</span></code>`,ds,m,Mn,Ca,Wn,Bn,Pa,qn,zn,ms,R,Un,Ta,Yn,Vn,gs,g,Xn,Sa,jn,Kn,xa,Jn,Zn,ws,A,$n,Oa,Qn,at,vs,w,st,Ra,nt,tt,Aa,et,ot,ys,h,pt,Na,lt,ct,Da,it,ut,Fa,rt,kt,bs,N,ft,Ga,ht,dt,Es,z,Ue=`<code class="language-undefined">selectColor(color) { 146 this.selectedColor = color; 147} 148 149startDrawing(ev) { 150 var canvasPosition = this.canvasElement.getBoundingClientRect(); 151 152 this.saveX = ev.touches[0].pageX - canvasPosition.x; 153 this.saveY = ev.touches[0].pageY - canvasPosition.y; 154} 155 156moved(ev) { 157 var canvasPosition = this.canvasElement.getBoundingClientRect(); 158 159 let ctx = this.canvasElement.getContext('2d'); 160 let currentX = ev.touches[0].pageX - canvasPosition.x; 161 let currentY = ev.touches[0].pageY - canvasPosition.y; 162 163 ctx.lineJoin = 'round'; 164 ctx.strokeStyle = this.selectedColor; 165 ctx.lineWidth = 5; 166 167 ctx.beginPath(); 168 ctx.moveTo(this.saveX, this.saveY); 169 ctx.lineTo(currentX, currentY); 170 ctx.closePath(); 171 172 ctx.stroke(); 173 174 this.saveX = currentX; 175 this.saveY = currentY; 176} 177 178 179saveCanvasImage() { 180 var dataUrl = this.canvasElement.toDataURL(); 181 182 let ctx = this.canvasElement.getContext('2d'); 183 ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // Clears the canvas 184 185 let name = new Date().getTime() + '.webp'; 186 let path = this.file.dataDirectory; 187 let options: IWriteOptions = { replace: true }; 188 189 var data = dataUrl.split(',')[1]; 190 let blob = this.b64toBlob(data, 'image.webp'); 191 192 this.file.writeFile(path, name, blob, options).then(res => { 193 this.storeImage(name); 194 }, err => { 195 console.log('error: ', err); 196 }); 197} 198 199// https://forum.ionicframework.com/t/save-base64-encoded-image-to-specific-filepath/96180/3
200b64toBlob(b64Data, contentType) { 201 contentType = contentType || ''; 202 var sliceSize = 512; 203 var byteCharacters = atob(b64Data); 204 var byteArrays = []; 205 206 for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { 207 var slice = byteCharacters.slice(offset, offset + sliceSize); 208 209 var byteNumbers = new Array(slice.length); 210 for (var i = 0; i < slice.length; i++) { 211 byteNumbers[i] = slice.charCodeAt(i); 212 } 213 214 var byteArray = new Uint8Array(byteNumbers); 215 216 byteArrays.push(byteArray); 217 } 218 219 var blob = new Blob(byteArrays, { type: contentType }); 220 return blob; 221}</code>`,_s,na,mt,Is,ta,gt,Cs,d,wt,Ha,vt,yt,La,bt,Et,Ma,_t,It,Ps,ea,Ct,Ts,oa,Pt,Ss,pa,Tt,xs,v,St,Wa,xt,Ot,Ba,Rt,At,Os,D,Nt,qa,Dt,Ft,Rs,U,Ye=`<code class="language-undefined">storeImage(imageName) { 222 let saveObj = { img: imageName }; 223 this.storedImages.push(saveObj); 224 this.storage.set(STORAGE_KEY, this.storedImages).then(() => { 225 setTimeout(() => { 226 this.content.scrollToBottom(); 227 }, 500); 228 }); 229} 230 231removeImageAtIndex(index) { 232 let removed = this.storedImages.splice(index, 1); 233 this.file.removeFile(this.file.dataDirectory, removed[0].img).then(res => { 234 }, err => { 235 console.log('remove err; ' ,err); 236 }); 237 this.storage.set(STORAGE_KEY, this.storedImages); 238} 239 240getImagePath(imageName) { 241 let path = this.file.dataDirectory + imageName; 242 // https://ionicframework.com/docs/wkwebview/#my-local-resources-do-not-load 243 path = normalizeURL(path); 244 return path; 245}</code>`,As,la,Gt,Ns,ca,Ht,Ds,ia,Lt,Fs,ua,Mt,Gs,f,qt;return{c(){y=l("p"),Zs=o("Working with the canvas can be challenging, but there are amazing things you can\u2019t build using it like this little drawing application which can also save your amazing paintings inside the apps folder and load all of them again!"),za=u(),Y=l("p"),$s=o("Along this tutorial we will implement a canvas inside our Ionic app on which we can draw in different colours. We\u2019ll then store the canvas data as a new image inside our app and keep the information inside Ionic storage so we can access all of our paintings later."),Ua=u(),b=l("p"),Qs=o("If you don\u2019t really need the drawing part you can also check out "),H=l("a"),an=o("this signature pad tutorial"),sn=o(" which describes how to build a simple input for a signature below any document."),Ya=u(),V=l("p"),nn=o("The final result will look like the image below, so let\u2019s get started with our drawing app!"),Va=u(),X=l("p"),da=l("img"),Xa=u(),j=l("h2"),tn=o("Starting Our Drawing App"),ja=u(),K=l("p"),en=o("We start with a blank Ionic app and add the Cordova plugins for the Ionic storage and also the File so we can write a new file to the filesystem of our device later. Go ahead and run:"),Ka=u(),L=l("pre"),Ja=u(),E=l("p"),on=o("Now make sure to import everything correctly into your "),ma=l("strong"),pn=o("app/app.module.ts"),ln=o(" like this:"),Za=u(),M=l("pre"),$a=u(),J=l("p"),cn=o("There are no further dependencies as the canvas is always available so that\u2019s all from the configuration side!"),Qa=u(),Z=l("h2"),un=o("Building the Canvas Drawing View"),as=u(),_=l("p"),rn=o("Before we get into the class logic let\u2019s craft a simple view. Our app needs the actual canvas element along with the functions to recognise the touches and movement on the canvas. Also, we have a list of all stored images below the canvas and to make the app more user friendly we need to "),ga=l("strong"),kn=o("fix the canvas"),fn=o(" (or the surrounding div) at the top of the app."),ss=u(),I=l("p"),hn=o("For this, we can use the "),wa=l("code"),dn=o("ion-fixed"),mn=o(" attribute but still need some manual coding as this would otherwise result in a very strange looking UI where our elements overlap!"),ns=u(),$=l("p"),gn=o("Above our canvas we also add a simple selection of colours using a radio-group plus some additional logic to make it look and feel better."),ts=u(),C=l("p"),wn=o("For now, open your "),va=l("strong"),vn=o("pages/home/home.html"),yn=o(" and change it to:"),es=u(),W=l("pre"),os=u(),P=l("p"),bn=o("Additional we add some CSS rules to make the view even better, but those are more or less o
245ptional so open your "),ya=l("strong"),En=o("pages/home/home.scss"),_n=o(" and change it to:"),ps=u(),B=l("pre"),ls=u(),Q=l("p"),In=o("This won\u2019t work by now as we haven added all the variables and functions so let\u2019s do this now."),cs=u(),aa=l("h2"),Cn=o("Painting On Our Canvas Like Picasso"),is=u(),sa=l("p"),Pn=o("There\u2019s quite a bit of code needed for the logic and therefore I\u2019ll split up the different parts in this section."),us=u(),T=l("p"),Tn=o("We start with the basic variables we gonna need plus the initial logic to make our "),ba=l("strong"),Sn=o("div sticky at the top"),xn=o(". I also added the link to an open Github issue on this topic where I got the code from to fix this current problem."),rs=u(),S=l("p"),On=o("Once the app is loaded we try to load all of our stored images. This will be an empty array when we first start the app, but of course later we will "),Ea=l("strong"),Rn=o("get the actual stored images"),An=o(" (more precisely: the names!)."),ks=u(),x=l("p"),Nn=o("Inside the "),_a=l("code"),Dn=o("ionViewDidLoad"),Fn=o(" we also update our canvas element and set the appropriate size, and that\u2019s all for the starting phase."),fs=u(),O=l("p"),Gn=o("Open your "),Ia=l("strong"),Hn=o("pages/home/home.ts"),Ln=o(" and change it to:"),hs=u(),q=l("pre"),ds=u(),m=l("p"),Mn=o("Now we got the basics and can start the actual drawing part of the app. We already added the functions to the view so we now need to handle both the "),Ca=l("code"),Wn=o("touchstart"),Bn=o(" and "),Pa=l("code"),qn=o("touchmove"),zn=o(" events."),ms=u(),R=l("p"),Un=o("For the first, we simply store the current position of the touch. Also, as our canvas lives somewhere on the screen we need to calculate the offset from the actual screen using "),Ta=l("code"),Yn=o("getBoundingClientRect"),Vn=o(". The result is the real position for both the x and y value!"),gs=u(),g=l("p"),Xn=o("To "),Sa=l("strong"),jn=o("draw a line"),Kn=o(" we can use both the starting value of our touch and the new value (calculated to with the offset). We then get our "),xa=l("strong"),Jn=o("drawing context"),Zn=o(" from the canvas and define how lines should look, which color they have and which width they have."),ws=u(),A=l("p"),$n=o("We then execute the "),Oa=l("strong"),Qn=o("stroke"),at=o(" onto our canvas creating a line between two points! Actually it\u2019s as simple as that."),vs=u(),w=l("p"),st=o("These 2 functions now allow us to draw with different selected colours onto our canvas image, but we want to go one step further. Inside our "),Ra=l("code"),nt=o("saveCanvasImage"),tt=o(" function we need to transform the canvas element first of all to a base64 string using "),Aa=l("code"),et=o("toDataURL"),ot=o("."),ys=u(),h=l("p"),pt=o("I had problems storing this string directly, therefore we "),Na=l("strong"),lt=o("transform the data into a Blob"),ct=o(" using the function "),Da=l("code"),it=o("b64toBlob"),ut=o(". This Blob object is now perfect to be stored, so we use the File plugin to "),Fa=l("strong"),rt=o("write the file into our apps data directory"),kt=o("."),bs=u(),N=l("p"),ft=o("Now add these functions below the previous code inside "),Ga=l("strong"),ht=o("pages/home/home.ts"),dt=o(" and of course inside the class:"),Es=u(),z=l("pre"),_s=u(),na=l("p"),mt=o("So this will create the actual file but we still need to keep track of the files we created."),Is=u(),ta=l("h2"),gt=o("Saving Our Canvas Images"),Cs=u(),d=l("p"),wt=o("That\u2019s why we use the Ionic storage to store the information of an image which is in this case "),Ha=l("strong"),vt=o("only the name"),yt=o(". It\u2019s important to "),La=l("strong"),bt=o("not store the full path to the file"),Et=o(" because segments of that URL might change and you won\u2019t be able to find your file later on. Simple store the name and you will always find the files using "),Ma=l("code"),_t=o("file.dataDirectory"),It=o(" later on!"),Ps=u(),ea=l("p"),Ct=o("When we add a new image we also scroll our list to the bottom, a nice little effect to make the app more visual appealing."),Ts=u(),oa=l("p"),Pt=o("To remove an image we now only need the actual image information to remove it from the storage and also to delete the file at the given path."),Ss=u(),pa=l("p"),Tt=o("Finally, the last function takes care of resolving all file URLs when you restart the app. As we only store the names of the images we need to create the correct path to the image using the file plugin."),xs=u(),v=l("p"),St=o("Additional we use the "),Wa=l("co
245de"),xt=o("normalizeURL"),Ot=o(" function of Ionic to "),Ba=l("strong"),Rt=o("prevent any issues with the WKWebView"),At=o(" on iOS!"),Os=u(),D=l("p"),Nt=o("Finish your code by adding the last missing functions below the previous ones inside "),qa=l("strong"),Dt=o("pages/home/home.ts"),Ft=o(":"),Rs=u(),U=l("pre"),As=u(),la=l("h2"),Gt=o("Conclusion"),Ns=u(),ca=l("p"),Ht=o("It\u2019s actually not super hard to build your own drawing app, and working with the file system has gotten so much easier since earlier versions."),Ds=u(),ia=l("p"),Lt=o("Although there\u2019s some code involved in here, nothing of this is really fancy stuff but of course if you have any problems or issues feel free to leave a comment!"),Fs=u(),ua=l("p"),Mt=o("You can also find a video version of this article below."),Gs=u(),f=l("iframe"),this.h()},l(a){y=c(a,"P",{});var t=i(y);Zs=p(t,"Working with the canvas can be challenging, but there are amazing things you can\u2019t build using it like this little drawing application which can also save your amazing paintings inside the apps folder and load all of them again!"),t.forEach(s),za=r(a),Y=c(a,"P",{});var zt=i(Y);$s=p(zt,"Along this tutorial we will implement a canvas inside our Ionic app on which we can draw in different colours. We\u2019ll then store the canvas data as a new image inside our app and keep the information inside Ionic storage so we can access all of our paintings later."),zt.forEach(s),Ua=r(a),b=c(a,"P",{});var Hs=i(b);Qs=p(Hs,"If you don\u2019t really need the drawing part you can also check out "),H=c(Hs,"A",{href:!0,rel:!0});var Ut=i(H);an=p(Ut,"this signature pad tutorial"),Ut.forEach(s),sn=p(Hs," which describes how to build a simple input for a signature below any document."),Hs.forEach(s),Ya=r(a),V=c(a,"P",{});var Yt=i(V);nn=p(Yt,"The final result will look like the image below, so let\u2019s get started with our drawing app!"),Yt.forEach(s),Va=r(a),X=c(a,"P",{});var Vt=i(X);da=c(Vt,"IMG",{src:!0}),Vt.forEach(s),Xa=r(a),j=c(a,"H2",{});var Xt=i(j);tn=p(Xt,"Starting Our Drawing App"),Xt.forEach(s),ja=r(a),K=c(a,"P",{});var jt=i(K);en=p(jt,"We start with a blank Ionic app and add the Cordova plugins for the Ionic storage and also the File so we can write a new file to the filesystem of our device later. Go ahead and run:"),jt.forEach(s),Ka=r(a),L=c(a,"PRE",{class:!0});var Ve=i(L);Ve.forEach(s),Ja=r(a),E=c(a,"P",{});var Ls=i(E);on=p(Ls,"Now make sure to import everything correctly into your "),ma=c(Ls,"STRONG",{});var Kt=i(ma);pn=p(Kt,"app/app.module.ts"),Kt.forEach(s),ln=p(Ls," like this:"),Ls.forEach(s),Za=r(a),M=c(a,"PRE",{class:!0});var Xe=i(M);Xe.forEach(s),$a=r(a),J=c(a,"P",{});var Jt=i(J);cn=p(Jt,"There are no further dependencies as the canvas is always available so that\u2019s all from the configuration side!"),Jt.forEach(s),Qa=r(a),Z=c(a,"H2",{});var Zt=i(Z);un=p(Zt,"Building the Canvas Drawing View"),Zt.forEach(s),as=r(a),_=c(a,"P",{});var Ms=i(_);rn=p(Ms,"Before we get into the class logic let\u2019s craft a simple view. Our app needs the actual canvas element along with the functions to recognise the touches and movement on the canvas. Also, we have a list of all stored images below the canvas and to make the app more user friendly we need to "),ga=c(Ms,"STRONG",{});var $t=i(ga);kn=p($t,"fix the canvas"),$t.forEach(s),fn=p(Ms," (or the surrounding div) at the top of the app."),Ms.forEach(s),ss=r(a),I=c(a,"P",{});var Ws=i(I);hn=p(Ws,"For this, we can use the "),wa=c(Ws,"CODE",{});var Qt=i(wa);dn=p(Qt,"ion-fixed"),Qt.forEach(s),mn=p(Ws," attribute but still need some manual coding as this would otherwise result in a very strange looking UI where our elements overlap!"),Ws.forEach(s),ns=r(a),$=c(a,"P",{});var ae=i($);gn=p(ae,"Above our canvas we also add a simple selection of colours using a radio-group plus some additional logic to make it look and feel better."),ae.forEach(s),ts=r(a),C=c(a,"P",{});var Bs=i(C);wn=p(Bs,"For now, open your "),va=c(Bs,"STRONG",{});var se=i(va);vn=p(se,"pages/home/home.html"),se.forEach(s),yn=p(Bs," and change it to:"),Bs.forEach(s),es=r(a),W=c(a,"PRE",{class:!0});var je=i(W);je.forEach(s),os=r(a),P=c(a,"P",{});var qs=i(P);bn=p(qs,"Additional we add some CSS rules to make the view even better, but those are more or less o
245ptional so open your "),ya=c(qs,"STRONG",{});var ne=i(ya);En=p(ne,"pages/home/home.scss"),ne.forEach(s),_n=p(qs," and change it to:"),qs.forEach(s),ps=r(a),B=c(a,"PRE",{class:!0});var Ke=i(B);Ke.forEach(s),ls=r(a),Q=c(a,"P",{});var te=i(Q);In=p(te,"This won\u2019t work by now as we haven added all the variables and functions so let\u2019s do this now."),te.forEach(s),cs=r(a),aa=c(a,"H2",{});var ee=i(aa);Cn=p(ee,"Painting On Our Canvas Like Picasso"),ee.forEach(s),is=r(a),sa=c(a,"P",{});var oe=i(sa);Pn=p(oe,"There\u2019s quite a bit of code needed for the logic and therefore I\u2019ll split up the different parts in this section."),oe.forEach(s),us=r(a),T=c(a,"P",{});var zs=i(T);Tn=p(zs,"We start with the basic variables we gonna need plus the initial logic to make our "),ba=c(zs,"STRONG",{});var pe=i(ba);Sn=p(pe,"div sticky at the top"),pe.forEach(s),xn=p(zs,". I also added the link to an open Github issue on this topic where I got the code from to fix this current problem."),zs.forEach(s),rs=r(a),S=c(a,"P",{});var Us=i(S);On=p(Us,"Once the app is loaded we try to load all of our stored images. This will be an empty array when we first start the app, but of course later we will "),Ea=c(Us,"STRONG",{});var le=i(Ea);Rn=p(le,"get the actual stored images"),le.forEach(s),An=p(Us," (more precisely: the names!)."),Us.forEach(s),ks=r(a),x=c(a,"P",{});var Ys=i(x);Nn=p(Ys,"Inside the "),_a=c(Ys,"CODE",{});var ce=i(_a);Dn=p(ce,"ionViewDidLoad"),ce.forEach(s),Fn=p(Ys," we also update our canvas element and set the appropriate size, and that\u2019s all for the starting phase."),Ys.forEach(s),fs=r(a),O=c(a,"P",{});var Vs=i(O);Gn=p(Vs,"Open your "),Ia=c(Vs,"STRONG",{});var ie=i(Ia);Hn=p(ie,"pages/home/home.ts"),ie.forEach(s),Ln=p(Vs," and change it to:"),Vs.forEach(s),hs=r(a),q=c(a,"PRE",{class:!0});var Je=i(q);Je.forEach(s),ds=r(a),m=c(a,"P",{});var ra=i(m);Mn=p(ra,"Now we got the basics and can start the actual drawing part of the app. We already added the functions to the view so we now need to handle both the "),Ca=c(ra,"CODE",{});var ue=i(Ca);Wn=p(ue,"touchstart"),ue.forEach(s),Bn=p(ra," and "),Pa=c(ra,"CODE",{});var re=i(Pa);qn=p(re,"touchmove"),re.forEach(s),zn=p(ra," events."),ra.forEach(s),ms=r(a),R=c(a,"P",{});var Xs=i(R);Un=p(Xs,"For the first, we simply store the current position of the touch. Also, as our canvas lives somewhere on the screen we need to calculate the offset from the actual screen using "),Ta=c(Xs,"CODE",{});var ke=i(Ta);Yn=p(ke,"getBoundingClientRect"),ke.forEach(s),Vn=p(Xs,". The result is the real position for both the x and y value!"),Xs.forEach(s),gs=r(a),g=c(a,"P",{});var ka=i(g);Xn=p(ka,"To "),Sa=c(ka,"STRONG",{});var fe=i(Sa);jn=p(fe,"draw a line"),fe.forEach(s),Kn=p(ka," we can use both the starting value of our touch and the new value (calculated to with the offset). We then get our "),xa=c(ka,"STRONG",{});var he=i(xa);Jn=p(he,"drawing context"),he.forEach(s),Zn=p(ka," from the canvas and define how lines should look, which color they have and which width they have."),ka.forEach(s),ws=r(a),A=c(a,"P",{});var js=i(A);$n=p(js,"We then execute the "),Oa=c(js,"STRONG",{});var de=i(Oa);Qn=p(de,"stroke"),de.forEach(s),at=p(js," onto our canvas creating a line between two points! Actually it\u2019s as simple as that."),js.forEach(s),vs=r(a),w=c(a,"P",{});var fa=i(w);st=p(fa,"These 2 functions now allow us to draw with different selected colours onto our canvas image, but we want to go one step further. Inside our "),Ra=c(fa,"CODE",{});var me=i(Ra);nt=p(me,"saveCanvasImage"),me.forEach(s),tt=p(fa," function we need to transform the canvas element first of all to a base64 string using "),Aa=c(fa,"CODE",{});var ge=i(Aa);et=p(ge,"toDataURL"),ge.forEach(s),ot=p(fa,"."),fa.forEach(s),ys=r(a),h=c(a,"P",{});var F=i(h);pt=p(F,"I had problems storing this string directly, therefore we "),Na=c(F,"STRONG",{});var we=i(Na);lt=p(we,"transform the data into a Blob"),we.forEach(s),ct=p(F," using the function "),Da=c(F,"CODE",{});var ve=i(Da);it=p(ve,"b64toBlob"),ve.forEach(s),ut=p(F,". This Blob object is now perfect to be stored, so we use the File plugin to "),Fa=c(F,"STRONG",{});var ye=i(Fa);rt=p(ye,"write the file into our apps data directory"),ye.forEach(s),kt=p(F,"."),F.forEach(s),bs=r(a),N=c(a,"P",{});var Ks=i(N);ft=p(Ks,"Now add these functions below the previous code inside "),Ga=c(Ks,"STRONG",{});var be=i(Ga);ht=p(be,"pages/home/home.ts"),be.forEach(s),dt=p(Ks," and of course inside the class:"),Ks.forEach(s),Es=r(a),z=c(a,"PRE",{class:!0});var Ze=i(z);Ze.forEach(s),_s=r(a),na=c(a,"P",{});var Ee=i(na);mt=p(Ee,"So this will create the actual file but we still need to keep track of the files we created."),Ee.forEach(s),Is=r(a),ta=c(a,"H2",{});var _e=i(ta);gt=p(_e,"Saving Our Canvas Images"),_e.forEach(s),Cs=r(a),d=c(a,"P",{});var G=i(d);wt=p(G,"That\u2019s why we use the Ionic storage to store the information of an image which is in this case "),Ha=c(G,"STRONG",{});var Ie=i(Ha);vt=p(Ie,"only the name"),Ie.forEach(s),yt=p(G,". It\u2019s important to "),La=c(G,"STRONG",{});
245var Ce=i(La);bt=p(Ce,"not store the full path to the file"),Ce.forEach(s),Et=p(G," because segments of that URL might change and you won\u2019t be able to find your file later on. Simple store the name and you will always find the files using "),Ma=c(G,"CODE",{});var Pe=i(Ma);_t=p(Pe,"file.dataDirectory"),Pe.forEach(s),It=p(G," later on!"),G.forEach(s),Ps=r(a),ea=c(a,"P",{});var Te=i(ea);Ct=p(Te,"When we add a new image we also scroll our list to the bottom, a nice little effect to make the app more visual appealing."),Te.forEach(s),Ts=r(a),oa=c(a,"P",{});var Se=i(oa);Pt=p(Se,"To remove an image we now only need the actual image information to remove it from the storage and also to delete the file at the given path."),Se.forEach(s),Ss=r(a),pa=c(a,"P",{});var xe=i(pa);Tt=p(xe,"Finally, the last function takes care of resolving all file URLs when you restart the app. As we only store the names of the images we need to create the correct path to the image using the file plugin."),xe.forEach(s),xs=r(a),v=c(a,"P",{});var ha=i(v);St=p(ha,"Additional we use the "),Wa=c(ha,"CODE",{});var Oe=i(Wa);xt=p(Oe,"normalizeURL"),Oe.forEach(s),Ot=p(ha," function of Ionic to "),Ba=c(ha,"STRONG",{});var Re=i(Ba);Rt=p(Re,"prevent any issues with the WKWebView"),Re.forEach(s),At=p(ha," on iOS!"),ha.forEac
245h(s),Os=r(a),D=c(a,"P",{});var Js=i(D);Nt=p(Js,"Finish your code by adding the last missing functions below the previous ones inside "),qa=c(Js,"STRONG",{});var Ae=i(qa);Dt=p(Ae,"pages/home/home.ts"),Ae.forEach(s),Ft=p(Js,":"),Js.forEach(s),Rs=r(a),U=c(a,"PRE",{class:!0});var $e=i(U);$e.forEach(s),As=r(a),la=c(a,"H2",{});var Ne=i(la);Gt=p(Ne,"Conclusion"),Ne.forEach(s),Ns=r(a),ca=c(a,"P",{});var De=i(ca);Ht=p(De,"It\u2019s actually not super hard to build your own drawing app, and working with the file system has gotten so much easier since earlier versions."),De.forEach(s),Ds=r(a),ia=c(a,"P",{});var Fe=i(ia);Lt=p(Fe,"Although there\u2019s some code involved in here, nothing of this is really fancy stuff but of course if you have any problems or issues feel free to leave a comment!"),Fe.forEach(s),Fs=r(a),ua=c(a,"P",{});var Ge=i(ua);Mt=p(Ge,"You can also find a video version of this article below."),Ge.forEach(s),Gs=r(a),f=c(a,"IFRAME",{width:!0,height:!0,src:!0,frameborder:!0,allow:!0,title:!0}),i(f).forEach(s),this.h()},h(){k(H,"href","https://devdactic.com/signature-drawpad-ionic-2/"),k(H,"rel","nofollow"),He(da.src,Bt="/img/blog/wp-img/wp-content-uploads-2018-02-ionic-canvas-drawing.gif")||k(da,"src",Bt),k(L,"class","language-sh"),k(M,"class","language-ts"),k(W,"class","language-html"),k(B,"class","language-undefined"),k(q,"class","language-ts"),k(z,"class","language-undefined"),k(U,"class","language-undefined"),k(f,"width","1024"),k(f,"height","576"),He(f.src,qt="https://www.youtube.com/embed/igJFPu6RrJ0?feature=oembed")||k(f,"src",qt),k(f,"frameborder","0"),k(f,"allow","accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"),f.allowFullscreen=!0,k(f,"title","Canvas Drawing + Saving Images as Files with Ionic")},m(a,t){e(a,y,t),n(y,Zs),e(a,za,t),e(a,Y,t),n(Y,$s),e(a,Ua,t),e(a,b,t),n(b,Qs),n(b,H),n(H,an),n(b,sn),e(a,Ya,t),e(a,V,t),n(V,nn),e(a,Va,t),e(a,X,t),n(X,da),e(a,Xa,t),e(a,j,t),n(j,tn),e(a,ja,t),e(a,K,t),n(K,en),e(a,Ka,t),e(a,L,t),L.innerHTML=Me,e(a,Ja,t),e(a,E,t),n(E,on),n(E,ma),n(ma,pn),n(E,ln),e(a,Za,t),e(a,M,t),M.innerHTML=We,e(a,$a,t),e(a,J,t),n(J,cn),e(a,Qa,t),e(a,Z,t),n(Z,un),e(a,as,t),e(a,_,t),n(_,rn),n(_,ga),n(ga,kn),n(_,fn),e(a,ss,t),e(a,I,t),n(I,hn),n(I,wa),n(wa,dn),n(I,mn),e(a,ns,t),e(a,$,t),n($,gn),e(a,ts,t),e(a,C,t),n(C,wn),n(C,va),n(va,vn),n(C,yn),e(a,es,t),e(a,W,t),W.innerHTML=Be,e(a,os,t),e(a,P,t),n(P,bn),n(P,ya),n(ya,En),n(P,_n),e(a,ps,t),e(a,B,t),B.innerHTML=qe,e(a,ls,t),e(a,Q,t),n(Q,In),e(a,cs,t),e(a,aa,t),n(aa,Cn),e(a,is,t),e(a,sa,t),n(sa,Pn),e(a,us,t),e(a,T,t),n(T,Tn),n(T,ba),n(ba,Sn),n(T,xn),e(a,rs,t),e(a,S,t),n(S,On),n(S,Ea),n(Ea,Rn),n(S,An),e(a,ks,t),e(a,x,t),n(x,Nn),n(x,_a),n(_a,Dn),n(x,Fn),e(a,fs,t),e(a,O,t),n(O,Gn),n(O,Ia),n(Ia,Hn),n(O,Ln),e(a,hs,t),e(a,q,t),q.innerHTML=ze,e(a,ds,t),e(a,m,t),n(m,Mn),n(m,Ca),n(Ca,Wn),n(m,Bn),n(m,Pa),n(Pa,qn),n(m,zn),e(a,ms,t),e(a,R,t),n(R,Un),n(R,Ta),n(Ta,Yn),n(R,Vn),e(a,gs,t),e(a,g,t),n(g,Xn),n(g,Sa),n(Sa,jn),n(g,Kn),n(g,xa),n(xa,Jn),n(g,Zn),e(a,ws,t),e(a,A,t),n(A,$n),n(A,Oa),n(Oa,Qn),n(A,at),e(a,vs,t),e(a,w,t),n(w,st),n(w,Ra),n(Ra,nt),n(w,tt),n(w,Aa),n(Aa,et),n(w,ot),e(a,ys,t),e(a,h,t),n(h,pt),n(h,Na),n(Na,lt),n(h,ct),n(h,Da),n(Da,it),n(h,ut),n(h,Fa),n(Fa,rt),n(h,kt),e(a,bs,t),e(a,N,t),n(N,ft),n(N,Ga),n(Ga,ht),n(N,dt),e(a,Es,t),e(a,z,t),z.innerHTML=Ue,e(a,_s,t),e(a,na,t),n(na,mt),e(a,Is,t),e(a,ta,t),n(ta,gt),e(a,Cs,t),e(a,d,t),n(d,wt),n(d,Ha),n(Ha,vt),n(d,yt),n(d,La),n(La,bt),n(d,Et),n(d,Ma),n(Ma,_t),n(d,It),e(a,Ps,t),e(a,ea,t),n(ea,Ct),e(a,Ts,t),e(a,oa,t),n(oa,Pt),e(a,Ss,t),e(a,pa,t),n(pa,Tt),e(a,xs,t),e(a,v,t),n(v,St),n(v,Wa),n(Wa,xt),n(v,Ot),n(v,Ba),n(Ba,Rt),n(v,At),e(a,Os,t),e(a,D,t),n(D,Nt),n(D,qa),n(qa,Dt),n(D,Ft),e(a,Rs,t),e(a,U,t),U.innerHTML=Ye,e(a,As,t),e(a,la,t),n(la,Gt),e(a,Ns,t),e(a,ca,t),n(ca,Ht),e(a,Ds,t),e(a,ia,t),n(ia,Lt),e(a,Fs,t),e(a,ua,t),n(ua,Mt),e(a,Gs,t),e(a,f,t)},p:Wt,i:Wt,o:Wt,d(a){a&&s(y),a&&s(za),a&&s(Y),a&&s(Ua),a&&s(b),a&&s(Ya),a&&s(V),a&&s(Va),a&&s(X),a&&s(Xa),a&&s(j),a&&s(ja),a&&s(K),a&&s(Ka),a&&s(L),a&&s(Ja),a&&s(E),a&&s(Za),a&&s(M),a&&s($a),a&&s(J),a&&s(Qa),a&&s(Z),a&&s(as),a&&s(_),a&&s(ss),a&&s(I),a&&s(ns),a&&s($),a&&s(ts),a&&s(C),a&&s(es),a&&s(W),a&&s(os),a&&s(P),a&&s(ps),a&&s(B),a&&s(ls),a&&s(Q),a&&s(cs),a&&s(aa),a&&s(is),a&&s(sa),a&&s(us),a&&s(T),a&&s(rs),a&&s(S),a&&s(ks),a&&s(x),a&&s(fs),a&&s(O),a&&s(hs),a&&s(q),a&&s(ds),a&&s(m),a&&s(ms),a&&s(R),a&&s(gs),a&&s(g),a&&s(ws),a&&s(A),a&&s(vs),a&&s(w),a&&s(ys),a&&s(h),a&&s(bs),a&&s(N),a&&s(Es),a&&s(z),a&&s(_s),a&&s(na),a&&s(Is),a&&s(ta),a&&s(Cs),a&&s(d),a&&s(Ps),a&&s(ea),a&&s(Ts),a&&s(oa),a&&s(Ss),a&&s(pa),a&&s(xs),a&&s(v),a&&s(Os),a&&s(D),a&&s(Rs),a&&s(U),a&&s(As),a&&s(la),a&&s(Ns),a&&s(ca),a&&s(Ds),a&&s(ia),a&&s(Fs),a&&s(ua),a&&s(Gs),a&&s(f)}}}const eo={title:"Ionic Canvas Drawing and Saving Images as Files",author:"Simon Grimm",author_id:1,twitter:"schlimmson",description:"Working with the canvas can be challenging, but there are amazing things you can’t build using it like this little drawing application which can also save your amazing paintings inside the apps folder and load all of them again!",published:"2018-04-17T00:00:00.000Z",slug:"ionic-canvas-drawing-files",updated:"2018-04-17T00:00:00.000Z",t
245imeToRead:9,wpId:4210,tags:["advanced","Ionic"],hero:"/img/blog/wp-img/devdactic.com-wp-content-uploads-2018-04-ionic-canvas-drawing-files.webp"};class oo extends Qe{constructor(y){super(),ao(this,y,null,no,so,{})}}export{oo as default,eo as metadata};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.