From 1164a8db1246394a91cbba7921070f56d863e614 Mon Sep 17 00:00:00 2001 From: KyMAN <0kyman0@gmail.com> Date: Wed, 31 Jan 2024 14:15:20 +0100 Subject: [PATCH] fix: Migrating project to the new Gitea Host. --- .gitignore | 7 + Artbook/Kanvas.svg | 72 ++ Artbook/Kanvas.xcf | Bin 0 -> 66288 bytes HTML/base.kanvas.html | 175 ++++ JSON/html.files.json | 1 + Public/.htaccess | 1 + Public/ecma/version/20230707/Kanvas.ecma.js | 747 +++++++++++++++ Public/ecma/version/221106/Kanvas.ecma.js | 936 +++++++++++++++++++ Public/ecma/version/30311230/Kanvas.ecma.js | 782 ++++++++++++++++ Public/git_update.php | 4 + Public/images/kanvas-180.png | Bin 0 -> 27799 bytes Public/images/kanvas-192.png | Bin 0 -> 25602 bytes Public/images/kanvas-270.png | Bin 0 -> 28787 bytes Public/images/kanvas-32.png | Bin 0 -> 7913 bytes Public/images/kanvas-512.png | Bin 0 -> 6447 bytes Public/images/kanvas.png | Bin 0 -> 6447 bytes Public/test/index.html | 85 ++ Public/wmd.php | 6 + Public/wmd_scripts.php | 21 + WMD/JSON/html.files.json | 1 + WMD/dev/ECMAScript/index.w.md | 24 + WMD/dev/PHP/index.w.md | 27 + WMD/dev/Public/Kanvas.ecma.js.w.md | 958 ++++++++++++++++++++ WMD/dev/Public/wmd.php.w.md | 23 + WMD/dev/Public/wmd_scripts.php.w.md | 23 + WMD/dev/index.w.md | 89 ++ WMD/es/20230707/index.w.md | 32 + WMD/es/doc/kanvas.idea.w.md | 76 ++ WMD/es/doc/kanvas.quality.w.md | 108 +++ WMD/es/doc/kanvas.settings.w.md | 275 ++++++ WMD/es/doc/kanvas.starting.w.md | 69 ++ WMD/es/doc/kanvas.targets.w.md | 29 + WMD/es/index.w.md | 55 ++ WMD/index.w.md | 25 + push.bat | 12 + push.sh | 13 + 36 files changed, 4676 insertions(+) create mode 100755 .gitignore create mode 100755 Artbook/Kanvas.svg create mode 100755 Artbook/Kanvas.xcf create mode 100755 HTML/base.kanvas.html create mode 100755 JSON/html.files.json create mode 100755 Public/.htaccess create mode 100644 Public/ecma/version/20230707/Kanvas.ecma.js create mode 100755 Public/ecma/version/221106/Kanvas.ecma.js create mode 100755 Public/ecma/version/30311230/Kanvas.ecma.js create mode 100755 Public/git_update.php create mode 100755 Public/images/kanvas-180.png create mode 100755 Public/images/kanvas-192.png create mode 100755 Public/images/kanvas-270.png create mode 100755 Public/images/kanvas-32.png create mode 100755 Public/images/kanvas-512.png create mode 100755 Public/images/kanvas.png create mode 100755 Public/test/index.html create mode 100755 Public/wmd.php create mode 100755 Public/wmd_scripts.php create mode 100755 WMD/JSON/html.files.json create mode 100755 WMD/dev/ECMAScript/index.w.md create mode 100755 WMD/dev/PHP/index.w.md create mode 100755 WMD/dev/Public/Kanvas.ecma.js.w.md create mode 100755 WMD/dev/Public/wmd.php.w.md create mode 100755 WMD/dev/Public/wmd_scripts.php.w.md create mode 100755 WMD/dev/index.w.md create mode 100755 WMD/es/20230707/index.w.md create mode 100755 WMD/es/doc/kanvas.idea.w.md create mode 100755 WMD/es/doc/kanvas.quality.w.md create mode 100755 WMD/es/doc/kanvas.settings.w.md create mode 100755 WMD/es/doc/kanvas.starting.w.md create mode 100755 WMD/es/doc/kanvas.targets.w.md create mode 100755 WMD/es/index.w.md create mode 100755 WMD/index.w.md create mode 100755 push.bat create mode 100755 push.sh diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..132a69b --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +Kanvas.apache2.conf +PHP/Kanvas.Secrets.php +Public/es +Public/dev +Public/index.html +Public/data +Data \ No newline at end of file diff --git a/Artbook/Kanvas.svg b/Artbook/Kanvas.svg new file mode 100755 index 0000000..1141f2a --- /dev/null +++ b/Artbook/Kanvas.svg @@ -0,0 +1,72 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/Artbook/Kanvas.xcf b/Artbook/Kanvas.xcf new file mode 100755 index 0000000000000000000000000000000000000000..85d5f58090484064f4ee8511fbd87d05b2d0c9c6 GIT binary patch literal 66288 zcmeI52b^40`S)jLXLh#tmMz)cY~N(ldm)iv0SWCdD2PEIp-2h6D6oqnMG=Xjz6iEh zs3KiON+=?|DjlRrO9&x7*`0gd@9&&@v$G`?u)xgcbI)_mbI-kZ?kP_{=N@|aQODGs za_}K_CygF6CKL)q`~wgQ{g|VWBOE3v=E#^0N(a9ZjwnYuN12~jy;ACb7MOb|x9&K2 z!BI!eKl%j9A)PFmecb#5PnbWi?&QNyIIQloJI~oeX9{f9!;d=f(D@yQ9(VXW;iw%B zwH|-MsYlMQJAT2DhtF%vYCYu8gBKjR;JCV03p$QF^q>RlMvokAe}iPk_@~;q^q@g5 z4bInXI-^TZIsTXf4?g_pL+i!_&jNYsU`QX=apKX3pHO%B(FY$k|9D-$;E+R(pMS!} zKd7q*q8z60rD}(yU-%JMxUBr`FE-!u(TCIPth+53FlY-`dUrN zzUTr6e{_a}7oX+eCD%Ims~a7>tjNJD?(*Ri4qmD8&F>l?UiXG8U+>qy$$$Spz3lL} zF81M42XFJ+B^2rm-4mK-BBAMeEuvGoSzX2n~&p>dcXheezpDQkJB_WEfh6VKZIjSC}ug_q)^=Gm>9}16GEA0 zd??Ev<3ibHY$(T!3FX>jbSTe^;=JM6BZ1*0*g-i$c?2*GI2;&Fg6))Jl-q#mz*b;9 z3ARwqpxg}11U3P)l3*j{Y|0J59N;iuZW64goJYA1m=CN479_!;lnW`>0E>Xtz+zw( z@9JQtDWO~mz7#kFSZ3))s=ZU~9W|-(y=9uSee@(BT2f$-j!+@=qX^njY>)O(3G|{A zT2W??mQXqLp#s`4#2$^IO6Wlqw4mA^^`RQ(|4`X`5K%=KZ+^9FlVh8mgM zb#VNLLt~*R`u1 zQ4SpuGu_G+#_SL>rZaA!E2*b%s^urs`jg=mQ{W#{;U&}TAuTN&ngQ?Gful2f=0=%q zTjaZ~t*d7aF7XDVAb`Q>a6GejbO_(S&cD07E&r+A^19S}_qPTFeHOq^N`Jd{aC0w> zc^G9r#+a9yo9R%QNS4yI(|MM3>~thf>DX}}2D)}S zy1sPmbe=68JMP1DBvnxt|Yv`P?J%;JYb!*qTGG%elQ9=BePa@u#GflIQJ_MNPOOZ)ECz&j(dUZz^J zw}q3rO{z8j8^)%zpk`)!i`9%ut(Me=w$yGlry{FGjX;~~VD^q==1R*Ng|;=?YF;^3 z3)`G+%V}?e)2d#}OJIGGL@3LPv%YkuV|mHEof#|1Ml(%b16dm6DUgRi);wA8+U!xp zEO&=13*Q%4!mKZ*ZV9urkaM!W=UbT0`>31&l_>^hp>e8SE>uGJ{M0`gtWB~#`bzvs zn!2=fY3S0-HBO|3OZ(P%YUOC59s3>*N84tcL+?(a^~d==JDL_BWe;bs9f`fRgE|rF zbTArX$dVn5j5uZIQxaWPzAqfbHDPcgI1EQSekQ>ddNzPM-^^%ISuo7Kn|Zd%O+b~K z{QC&k$modzT|V{S|3mGbbuXh~DkDKOW`b`Sauy=l+I0lAZZ45oCQ6TH? z4&(=ihVk2(W}q0-C>&pRI+pyQABKMQQP^zy_%v zyn}$ykLR=GNi4En#SxZUiE{;9EDw1_kqtRkb{Px(8Ru&s8Zq12f+@Rlss&Ol@JX>B zZ|Xfevu18aIte6{!1~)8akX{SSJq!eqQsDXK9*0)?L_`_x~8+Y1-7=p-sZfIE%CVIN;k8yP=e zhKE#bP)cM?416&jRF#YHrV19IbBFO3D4$P0jeLxJ9(+|^1>tkZD|%1)Z1P$B2jw%V zpJO#cMfVkRjkEYke=p=et4@r3G2>eKDEU(Ix_^ZFWj@~6d<1;8wSq?R_LlQM()f?E zfTr=^%i!M;JicY{^e|CF1a(Q+Cln`adIm{?Os`hT-7E7utND(CYJp7M~Y1`+T6m z=K;ff`d{zU{yJ!~_`y)%2c`MV+#@(Di5c|ZIvoVS4R_ijj zZL-z66fIL+uMAtJxLg@l@`#1{cSW>dA@>q@&9min>Iv%Vd#O^tZfWiaC~EM|^Qwr!R{Z z@-H>Zi@-VMHCK9iX$n9WQT%!LwYX67?fRZsG+@X0eZc~&OlgBd*B zM#jrdB^#Ai<;asFOP(xv=ztlwv#eS&bLxKv?dRIAZ#!>GdzRChy&kcF9df+3<1W9L{8NG7t7D60X>7^$`<8Vd`N5L!)4#0e zC7&O>-1oj6R#WVK?)E=tYwp|ooFe#6g?*hOf_-rVF%9-$E_nxku)3H#ieiZ)fe5VDp zOKR-&9ZRmQQe!7Ib_SzweaFh+^ei=Ywmf!ZIg=+|p3!8uX%Btix&L6-Z2A7da{{>O zsDV=cdkgfm1lYHcI!t^XWz9IpV-wlDz}7EBcOMre$*o{H3B~B7XEL)|9|HQkj=E$!`bU$6izEs+~Ml{ z_mqQu5rY4>{blw|z_%b@LM~nk`4aN*^cCYvh@xS}frV(7%4cw{fI5oxQ9h6B+zN;+ zG}kgDPFXUup!5~w#St?(Dt$|$^0HE9_;6rZt1FVvs~orY2(Ig27JlG;w&yv$&(;6y z|D68i!Jj+W|L=d_{^jj?zwLR>_B=OEKc~h<@|aAG4L7$knU|@t(RUuE#zz0KA+L7_ zyhLk6-P+J>yDm^`v)tZinRcz#6q}Y(->mKmK?3pL_~#mA6~%9jq`5_S(|wULC2 zEeB95wRL_ZhoC&E$xvQ+m9+zrpsaOT9}qz8L=>g0-F{<0S?ja|Q2?7MYbT;6prSLJ zwaHmWlk>7xY0ZnCp`CwY{{J4v^JD&hueW&VL+M0ksE&IV?F6i~#=n>`X%JGf>ilZ^4k4Hb(Ggm zFVa8DHs&2(7Lqvk*R`sff!?b7>mJf!^<3q%$?Lx<8YdSWC_6QBX^GUxO^w_X%}vqV ze;>^aWWg=LKz>YKvFTQ?1bfEDtp9TYG)$a+JW!l{98l88SfIFg0LM@kCm#(I7at8* z5Z4|>S#Ts!Qb`9;(nyEp8WCc1#8o21?#R|1A(khGEF>6(qbT+#W??HZmvRd*&%!9N zKoMfbV-_|6wN|4MsF2G;A7C&$TJL#hS5rBt zC(pae+EvuS7S3fd-db!qW}}|dAtu~E?(j7LQ&3QE_= zU_1s;QSDBr|FCuU&D&i1+goIJ3AEphHkVKrpVia`yVi*%cmWe+sDN z*4Uo{+tY_lJsedM=hQ6Mo~90lE!1A8DvRTaiaMx0@X~DA!3?OQ%7Re~wTG(8;+29e z8=bx z(NLnmirx#ix_nwmyN>!m6w-6>yaw0 z{X#a6T=24K$U?3<&JrklMkTyn_;g#xc{gNPAA-Cfe5TDi&xow-mB=B&=UBY+u;kjj z^TOnjujahovl3Wn&&m6c!@I~kp&gXuz0fLnc{FmYMZX*<4}t!_EctprS@ElY@;cN2 z)ow$9YO`9PJQ;P|Pi-}fvf8NuC{IZvc(qS6WwlKUQ0>wR)cqD_Lx63OR56iIUA zNT9)g_^^|>CPg?Y_C)%=ETyuVs?8-)D-J?25IMv?1V`=%$mjIAS2@oWPb=lwf+gtd zg2ns?^-wR*i(9mH=4+r1?whm!|J*knYO?ifPlgBo(!)FP&(Q9qrwu zJ)E@fj=meIFQw>vk(EG6^6n5WC~qo1@S5c72j-bGd0iW+O%T~8Y9oDmyU%HJ7v`z< zcL_WMf_=-$wmi2YqSv;!DGx$$zh2wl!2ABEp0l~v~T-w z?mn)a`_>QoOP;Vex{F&GqsX-^%8FFW2B#=BL4qj<^mzX#26uEmB&~r-jex;gzJI%I zuACYHgSBAak@eAywEjJl{M>;(vuWDc|32GN9{8O991T!3q^#51V(AX*25{>v-+iC6 z`D+KS8(b5>zR%tKHL5EgqKi#;-;Gw>dcgq8duKn(y!Kq%nt1W;vvhBd6@FVR>B;x+ zUC|+HLH|`9{UZ#5=z`Syf3o{u`gov|2YR`5bA44^NAR5?>FL1{tQy(c6(a-Jg9Q|6 z;EItz-%nmO66pB@JoZsM_BosO*l%jJNTAXGFJ3FVbYKnqBtmBa{UpA5@Xo0gPzwY! z;gboAtpzR(t3?jpFYVSYD~rLu=&X`kXQAwCecbdls+VO~fGK7{<51FtR*wbobaqW> zyepLYUqSnCU3=A8+fvm=8C3@!EuW-zFRDPb^=m$5K7U z_z31|YL0#QbF4Eg8~F~0~we2@S3mQ3`-yk`!IstxQe(-C8>s_=_1JBV{+*_eVPFpMDKZ!3m@9B7G&P3>q z)^0eDX_zmre2*)%&Q-h6%Zn!}r6{8e{*8m8h((mOzPK2u`lV1c2lefVO!9HwI+HpX z)RpJaL3sqVK3Kcs%Ok0s?zR3`yW9)b0=3pxmIkf!9mah`85?}q2o=@Z-X@^d^(qQk z>xtY7o-7|~T~U-?(z>E3J*IU;?wfQYeK-oLEs8oCsOTs6?bU2JpZo5r+oxFCQ}X&D z>4@_5x_ycz$DG0adUqHIb{g0om}+&|RswxB)#}zV8B`_#@(B(JKZSLanN zwUkmZATBPll9i5C#D~=QF_pD8&awvD;NmeGi8*Ovbz%#WQL8;lng4FLX}8OC0bjCk zJ52xQ=Xqz;MUA+;HkfBn4I%XL%WmMz`g4 z4qERJd`%%(>#(JD4&sqpyUt;-wGLZa=P=k>hmWrxVsMMH=x}Ffv0bAPSmHlkF!kO6 z&kbw>uD=Iwm*l!1r+hHZJ9E2O)w|e^`Az2Y@xL-BT5NQA7%HUi9)(%&sqYK5duE5h3#QSN5Ot4BO@O}jzuwd1Uiy?HYX9BNS;28^6)3_BiZhgF4EAQ6L zSNrSe-J1G({6<=1Ux(kwt-E(?@Q30#57y<&PVCm}yS4jO*wx*7{w8ZT-uyV z@%lV|Tk6XH_3yUb_I=*AjM?D7Zuy!`Yd6w}?+K;eJ7~-PaLa8wkS}b@HQQ1*_-|Xj zW=s9Or5!GU_@!XA@76>Yi^6PebaAjsSn>UVeLL8b-r2tgMi&S1QJae{-jts2MtLX{ z4!HvmVk z96^3qQocGVpOuuaOUh>_<#Uqqxk>qa@_L^Bi;g&lo~Qda`FTL7QF+4;*pQSjQQkiQ z!SAk`AeYnx{(IcDr#shuun!mb@Ee0%1L~dw9sZtUeR!sW_v$_P{q1lcKIFp}e7MxX z`+w-eU;FR|2Oqr2!H2GN@Zo11d}O(UkDcnnYkYXSgOA_h;NO4j;8U}G=s)+_OI`W7 z{e1W}AKu~M3*8R>bE*$_@u6S;Wxw7l>JNUelsWj?K|b{V|G$oN65(DC` z8y^FhBhm>5F;~P{Zsa|m7bhabTRSELVCH2KL}z}NMQEG%Ol}r2BHpU@Y=D`YLnxj3 zX)fU+-V<55XbRrS);xguaz5LPm>(9PD0mOX3(yt3_l6Y`M&fyU76Ht6i_sUn`_hY1 z6})%rN{B4+yxmFx=BzT*1#fY*3~j-CyRsam*h_r60$|P7URyfcbg`5*(*8*r?rmt0I%V8N9^oEP(k&Hi7Qm?P=MJG*0C()Hsz3 zFsJ2dz}=pfr=j-NkbDib#7_Ak6B$7VYSc35Zcob>ooIJ8m`~(X$xFMHv8b_rHnr|h zt(_A=t?DJJ^=WX?d#Ke#t?vc3cJ(;-b|vSAz8lnvKj_!Gh+2!em)VDmt{f2XQMtR(k zs#L|P@#}(01us(REKuQVIC+<9olx3mVwXd5{?bG|r}ji5y#~XUD}R-4$T=3Fh3Y!3PRp)-Uz}yAv*d3oR{(NNPxL`6k%ZI zi=zpF_nO}yjfC!HJ~jqmeleEdPjm1%lNs_xtR6?irMAOLc2O^*2zsS@B~T~oO)7^XQE%uFs8Qn0uEHt^P~!1JGHReb zs#go4No=@s;xLFyV#UItjnEU-Ylf6iFWwyTrr%I#t2TuakvaDksQQHFP$E9}Y4R%; z){xI%@GtUjbQO@VTeyn+V{>EVM=k0m&tu3>zro8liS>&{kdMrH0Q~z4tI6jqc$xgm zC+phMuBFhdD7j$^*Ob8C5@Q$jU;|8Ut@v5SB&M65x4W8FPB9yvUw~%v{VB$z(G%6{ z6<%z9rPOOn=sUXRdYewt+HG@>B9P4-rC#{S3F_kmlzOpO6rXI4RqACg8K)8PO{HG( zDt$lDT%^>i?;gYWF~1w5j;@}B)PZ}&2Q zIj39<_ug1JgV}q#szSUr@tGk2(^V;sdwW_XycSAZC1%?*yBc6ltr5$;IZ`8*`&!9R zG28BGwE%NmomlP-;X1M0SBmPzY}bt+1~5l7FcZubjpDe^=QWDgt{u|^F!P$>xaM~) zVz|%bwusfPYHtOYxoyl6^V9Z?f`|l?2!DT%k&5&_Zxmig?{BeDp@ez27I84~xiJi@ zu_2Sznfa-zo8Py+`9Qku z&G+iX*34eEGcQzUB8J4p&fXiQPBnYk&RnR@h+45oPRI{(`%pa&Ty~i?g#mrVT zt5eN>wljYS$!>(FJ)SAT`Y2txvIW$|^e`37mw*>Rd7D>o#@5MvEU5Df&LJ6@gMmMy z&WP2Vc|!Nec`DZD-DzgaI3}%Utax*%Tl7yD$G6FZuj8V>#kkEk$h=z%YG$`;?MANb zU(`CAOyriJ)|o-A9mQ^Kt%^6Pbq=+ncX9GQ-RoR3%XF_@#7Mo}$<-{O)_G)Ne^sq? zYF(&Wb)e>KtktlbTHgT`e~6R!tJY8aT9)0~TQ$8;rSDS7wwJB+^PtjxWV}5%H=Ncm z=aUh)b$43SYPz3aV3yT$*TY)OhI{sgz^U%YHI}qbL6ZI+#oT8aOk&l=EzmvvfvceR zZ+8{LLKoDV1k@3ceZu-$sPNv1j>!BqmVY4QhyPG*S&d}>D$7LB2_|oVAHYY@5{h1~ zu(Z357X4G1SWrUuB?7{2*!)kA6AEePeT<%ra*0H2=OZoL6&9_j0p- zQ3uzTcfE^9oM+|M%if1aFgnfoJi zqn5dQf0<*M`}#%0EpuPKu*x#`mlkAO=Kk>9sL$MYvdn$mqIS#NmoKce%>Bg$*_OFK zG&gFQd*X(jEOTGCsLe9>CFfRJ=KkUWBzrHs6W#UD+%#S~eeU0FhfSl+au>Wxe%+#0 z^5tF2$iH*$5b})+*OGr>K^FPxS0>22Ya?_1Nx`b!r?cq&@J=@jL2p*uRG~8S$k%F6ll912G~)!EzaFJnw`f38<&pO`Bb}-Z zS`kR~{_V)3iMn%_k3jyEKr~W+jryaJJM`w`5K?&a=O!Rf>dhxH=Jn=NOiu{uXPPlL zbY}O}hZ*0`M34opf|$<%jtAa_tZ^Fw77%=(E!Mqj&b3T|agQ;2%=J7C?pM&`mw?$H%o$*!FN0Z{4d!Sthl9yN-tw#f)dgm6Fhwi5|AXA` z2TZedXt=XL)@-OoX{B%zCw>hBze0R@6lXd-5v@EGf62Lmp_1iS@cPnA-0lWEoR+=>IQ@B<5AH`zt`ev2)mgKF2;P7A3C#%fCoQ}Q1 z5dKNJv~$}7$D>t0o|!HIVmD6bF3Xcb99Q{np7m`MY=l7+`>C8QTa$x^oT=h9ocu|) zG-VY%k52N2b)#o5tItA2F+b(}<#e;RN46vub(uE`I%v+zksR}FPTzv={kNEk-m+Z& z=+h?I`Lq<1G@yW%19X|ygf$&%=x2bp13c4 zG=>RGCSzoo@OB#uFlUXEePVHR9F_?b-0?C^BtAU>V9uB*1I2A=6ERJo-%pZlqI^TQHgiZsM&K)~`QiCIYkpWe#+n}vwQ|}OlG6}5)BD^Mxp!qN z?EKfh*z`5vkKy*C)*v5Pu}RvrH92|V-*a+*Djy5{36&;7_UasUB5ApohhiTct{AxB8XN23|s?ofAPNiA}Cj z^d3&m3H9?}Kb<>og)XxjGq-aP9!kT?+g; zaNnR#i=<3@pX`75b$$i>9d+hY=h<;v?I?0NPjl|8ocoPm=cu60_;o>@f)_b= zAeF<{khzS?Cj^xysY&gPieBd2L8^3}U+EiEdQMN9*{w>W$(8+!bMweVZXt6ycREv* z^1$ra14eZ!-n90K=v~%6ah~iGNT8!+pr~154HU7zS_8#}GEg9Pj+JuS0C|QO#2>O2 zil0~u#TO^`;ak|@#$XdU=tYd0zr`wY9{;MR0mDcoFJUeMBLQ@EDVSEe&U_Qh4Pf5Q z!GN;^|LzzN7*xF1(n0J6VlGu9Pl0(V0_IRKbHKzUO5aD_(?CoEQMeMs^&liGdn3Tq zFv!d=!Tc7?hM{0aG7iiIVEzndRSCD-iK|Zs@i2&`*&yg)a|Bh>UI6n_6wJ|J_63ur z@%4BZ%s0V&4on&I!Q8>sKL#-c#4tvz`8|lMsG4Y_>IBYQ0%9?Ubx=9;c@XDOHT)!) z_Y1&$70fAMVy}RCD-#SIZw>*I`yQAV)4-ey<_loT*Ybb|x!=z~>uUJ#gE;sY>CcT5xIRDdlCf0@Lhn z)B6;;W2O}5r`C0vuPB9!=_=?3k*XD(98$j_7-+@;ie7fA$r?~zIwZ2D-Y`Jz(qv2eQd=pAkPN3CWv zqxHQ(vq-78p*AW*$^}ZjRmIlT_jRS-+ZhoN{`pFKo{faW685m^{UO%RdDE3#r^IWA zZCuK+t}`;LZ=>gSg-j*O-Okw|#B1ZVGRMz=FTI|w1>xoZrQVZatq?c6*z^wVqh}^h z-7K%-9oLPu_MOA5Dc}m30$@JYzP)a&weK8mO#xTR6oALTnzz@Dwf3E_SyRB3G6ir3 zqv`^BYuz|#*@X4<-VtO9Um|lAneZPtXDgi)RGPejb4PNn^mS0zhoN^7MlfuaTb)5> z!(>j*5`8?1O!*rdYyE}XE2?#tYE9wfY}GoNO!X2_H|So`yMtQa4QlO*CD<&W*3hLv zt=PS)Rm{CG7TbH7y%}uBP^l3a-Q6nVVREmk(oa=sDw!`)=~yZ?uK;tSo|pMpQ0bRJ zrGu%&;KaBQRLXfOs01g+48@(kMy2DaG-?f)n{+4f9fS~aV&$&Zanw4IS`%qmSF7-! zdxHGJ~!l_ zSr#N|;3(dyUc$$#G04%CU@#<_@x1pFBL8=Q*af%?@Jj64&j zW6h_*AZwUgfpI!)k|kVMTEf-SWC<6d7KCfv5KFkuwuI~bd`q}aw1n%;3`?>ORtjOX zG;2?rKA=UhW|k#ff7GTQW{jm2LFw{~kjE?l$s$x;A)08aDhFl%N@lt1K zai8w%jImbu4bFUh2ZI(#-OvRy=<(|H)8!CZq!d+c8sozJ(WX0UBM@`nRHa{3ih?=? zHP{@X)XRFuTJyWCHNSY3wd3PeX57_xTSNX8HXX0fDs#KF=I^XUGzSleYAIrLZe)O<=yE zlmR~m<;onQ)O$8ETKd+WHobqeJj64!oq@StspkzJDcAAOlzJPgwc&v|S1CMdgfzJm zlp?CcBMMXb~2 z4(9)C`hbFZ%??AA-k_9s)gBP$=QW$T}5umXK`|c7i_?)>YbYgcEUfw-d;|wS5wgnz-wD11@-g@hVw=kx6^d6|SFSg_}dNH0C zu{!*1~yWtYe#`{CQ73iKFX+^oU^At|a%_XsUk2F{@?R}(SoRHkyQnkA( zEj@eZGooaPp00?MwQef1)aupAmQHn_tjz$tYw|5QdZxq5PHPU*%D$dO`0*e$k2HwN zy#IgD5w8=QcAxnJo$$I6A}Tw+X~{{|-6AB3Xjj5gj9uTgw4&x-Q3-KE>)hLYnWY4^ znA*^z;tLg~>Fu>#Q{8KM+|KWepDM=Fo4aa+yvc2UA1>c=&hNC5kvDgZ_B8UwJl`Uh zblw%(D})Yhltpsbl{GVba!<7aab~?yrLdf` zTPkJqOzTQiD1K-5TjiKSz3O}D%!M&Jn|EO%+=-FaoAWNYcRo#S=-(J1v?&+F7gF=a zB9ME$$LUumlWTg6+&T@z44wTg6UW~yfxq+9!9SH zALN$rMK1R;jlzXEZh2>rcMc&p_62fp??f)|%HTinqU*ulfS1@z;Eu0MvQu>30y_kM zliiR^@j{&tPV*8xq4=g5*feP*^_jQBzoz!-T+iH24~&q+HW|`+Gw^EQry#0Ujk^y7 zDuJ~TtW)$s+Vf!0;|#VD)HpC%?|?ZOOedJPGQbqkp=LgqAA)&7ArLdPa^QnJ zag?5j9%pU?{u%f===xZo3=fw9_vg}{MlOxL4CY5*u(Lp^z+_AOLXR`w2D2;|Oc_F* zISz~j$JcSlc+CkgUj>6r0a{37OymKmaRzzS+z;H1@(gN*WyZJ>#KF|`MuUmVjIapI z$zV3rg0alzLNJnXSC@dP60>2J7)hb;=74F_8zDfMo4~v(57#W7@MREx1MvhL%8I-@ zQ#I{5sxIct;nbK4BI8XENKjTD_u9b}tptMv<>ciWFm-Ce?}E9E+pSQ;+crdkG7{9^ z&g21~;eOLWD8l4t2xwo1d_0-O+={-8YPhnkIAo4NQ{12VmAw>Q@<(L|_eiUcXEMji z)?iJ1ub~3ZA~K=(e@wK79t@BdRE5m%arEAwPG&-0pW&kx=tC>|mAPy~jWuJQXU&-J z7g#gqiIxPuo^H*U2U%5<`~8+BmdkRi z_PfB6%vWPp``yoKzmJEl_WNm@-l8QcW~^0ye`g75k0q#Pp(U%*&1t;Ttq`fUMEgC= z3Xv}oSA_Qa1)DygMKNZkl_YPpl-C8%RcPmHsa{W6>OSo;105&6|6ok>A_HoqBR3BLaHaLd(Jen|^%V5gR; zJydU*+R|MdQ(G9dJ-T>^?aQ}ks}~d9T@l+|*B9E3dU>MlqIC-_SNk=7HMrW-!)^1g z_@Y)9adXSm9;~-byVTkh#G!2y-a$MVri0g~so4_nW!pa2721}0d4g?|wF?|q%d&6% zRJ&ey#Xg-#r^%xfk+<|uVqM}ARIS7>{hWZF$2rAK5qqAuLgr)j%93?Ywfno z%A>XSNgjnUXjgP^&*klkk7|CrP0TA}p%y!!&uMQyl({A`ugsrmr3502xEAtCy&^wz zFW2HG7@L?DVoD8uFBqFxml&Iv7QzW4*t6(@RyJ8R+{z~1h;j$CN-`-j-Is(y7pKE4 zN^dDJ>!0A|&4YD#`rvjL^H;WNUADL6bA+<)_+}0?NqeTMS-GO>Zp71zqLO%TFXs|o zT~cjkRATRII3>MZ-zE3nFnt$Ojm|YS_aZENL^@#lzm@=^4X}KaJMGoyJvXW))U*40 z_or)*Q^X@~&`6L?j>H&Ax89?TR-|3A_ejaF7ZbCHT#D2;MYmYV*p{pYJQ$!k-w8iDFEa`1w4DqFE z3CaK!Ad`1j5}*{lD{jls&v!mU4Aa?Y1e|6HAUqKCG&|uCkgi+HVzNP_AW#8|!K(xm zcxkuM36!DH-6x}`eH$%-V!P?NCV$5sSI}H}ht30!0!f-YplQiv^+Xih#T$9M4-J_) zh}-8dpu#v%3FRRM`5+qOohk&P*sF;0iO)6=f55QnqQ&!;)2g>42Al8D)^ADvs9KLh zE-|~6I6ahzueZr&O+Vd?QUR}|4@!oI%uKYA?rDTm-;1Vl{K$~`Kl=BE@JI|y&!OSG zQaqX%3P!<(DPx!?dgmjE*gl=MxN^KW976o_`4d8BAp>mfn2BO>^uxT#gnH3GmrW6e zqvLX?;&zJ=H*P+y4b&13!{b7U{cM`{BAZ5d3zTFn!EX00j`8-CJi$X~UhQtVZ$BA;kg-Cz~v9c;iGq1Xhx?PW$bYu!PTJquJUqG&1*7x(lzF)`IF@$iclC+UroFR?d^(&M`4`jZ1+%x32gk^o zIcv1io9yMOZPCD^EHhr*8D)FakmEK${jd=7>rN2_j ztJX**{+?1^wOT6isY-d(DyhWtl=7;TQi*rB>3x;bh^GxvdaY9I$raLzFHy>?mP;i* zTPf;!nN;HA__T8}&&^qEX8vXK7&pgL={B^$U(6h+Vsbn8%QKDkwd!Zu3)aYVv}Na6 zORSOUo0h4Ut+7U?A6wQw3~M(+^i?*UAT}>=7U}1$q8ffoEZ-bp8Gq~*F@AG`W&gSF zNq05pS`D^*tu$EkGpon8BqR}->uowiI<5Jugafmu6%is&NxwCRSS>gHhO}Js4Xf)G zu8`DVzHeoR>J5?|%&)Bk(cww^HGi_{Y)KR5At}PvI%j@PDO<_-xTW*04_HjfTbI#;O|yS8ErgSXQS@T?2jZ{8hn zq1Vz&WfA&{Qf7Jy+}G@E)7wjA5Smo1^a`aYenoI!bCFVJx{ZtIQi|iKKtT~lDrKhU zD=6ZNO0iDmDJWt`oBlCRF%e^OmHt{OdR&fliVKutiOZHN?dwW$9A(LuHeadtY$Q{@ zv^{Kkf2Le%(=(J_rv0nOib2F8FQswFVoW)LZ?WuijH(`g$&YXDtR{tKiW|oFOB;PE8#ZyhZe=1?jOqU z;2!{dUiPqyO*6kR|CAF>JnmS#dQwa3wER-bH|v$3*+tsB)HF;ULy)Z_{71ReRQK0! zdzYFLSDpOpIk&g8u>th1{CaM+ARKW^L&K40{POD-+GOK3lstb4spl`{^!z2HUXQDf z7GQr&J_kqmaJmn7_2K?LJkp1!`S5%nUh2cEeR!)6AM)V~K3wX<9t-*Wfe)*FIKqe1 zeYmR+_xItEK0M8b=lk$dA71UlTYdPD4`1-%QXlp>h__e2FiV~s9O1+1KHSxZ`}^=n zAD-sJ^L==!53ly&tv-CnhcEbWsSkS`jO6&R+J_^2INgW4`fz_A9_ho=e0aVOFZJQo lKD^aJl4PMel~1)tY7Bg`#sI_(Dxkyux=3~CH_Jal{~yfa%=Q2P literal 0 HcmV?d00001 diff --git a/HTML/base.kanvas.html b/HTML/base.kanvas.html new file mode 100755 index 0000000..8f5161c --- /dev/null +++ b/HTML/base.kanvas.html @@ -0,0 +1,175 @@ + + + + {title} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ + + + Kanvas + + Kanvas + +

+ +
+
+
+ Menu + + +
+
+ Content +
{content}
+
+
+ Files + + +
+
+ + + diff --git a/JSON/html.files.json b/JSON/html.files.json new file mode 100755 index 0000000..ba6b588 --- /dev/null +++ b/JSON/html.files.json @@ -0,0 +1 @@ +{"files":["\/mnt\/d\/git\/Kanvas\/Public\/dev\/ECMAScript\/index.html","\/mnt\/d\/git\/Kanvas\/Public\/dev\/PHP\/index.html","\/mnt\/d\/git\/Kanvas\/Public\/dev\/Public\/Kanvas.ecma.js.html","\/mnt\/d\/git\/Kanvas\/Public\/dev\/Public\/wmd.php.html","\/mnt\/d\/git\/Kanvas\/Public\/dev\/Public\/wmd_scripts.php.html","\/mnt\/d\/git\/Kanvas\/Public\/dev\/index.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.idea.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.quality.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.settings.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.starting.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.targets.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/index.html","\/mnt\/d\/git\/Kanvas\/Public\/index.html"],"directories":["\/JSON","\/dev","\/dev\/ECMAScript","\/dev\/PHP","\/dev\/Public","\/es","\/es\/doc"]} \ No newline at end of file diff --git a/Public/.htaccess b/Public/.htaccess new file mode 100755 index 0000000..81d9bac --- /dev/null +++ b/Public/.htaccess @@ -0,0 +1 @@ +Header set Access-Control-Allow-Origin "*" diff --git a/Public/ecma/version/20230707/Kanvas.ecma.js b/Public/ecma/version/20230707/Kanvas.ecma.js new file mode 100644 index 0000000..144f9e9 --- /dev/null +++ b/Public/ecma/version/20230707/Kanvas.ecma.js @@ -0,0 +1,747 @@ +Kanvas = function(settings){ + + const self = this, + default_settings = { + nulls : false, + default_value : null, + position : ".kanvas", + preload_timeout : 2000, + frames_per_second : 60, + quality : 1, + quality_x : 1, + quality_y : 1, + cells : 40, + swap_and_drop_timer : 5000, + font_size : 1, + font_family : "Arial", + settings_overwrite : false, + autostart : true, + autobuild : true, + font_minimum_size : 12, + events_cache_timer : 100 + }, + custom = {}, + cache = {}, + frames_times = [], + id_length = 11, + id_alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + ids = [], + threads = [], + number_of_cells = {x : 0, y : 0}, + events_cache = []; + let thread = null, + frames_per_second = null, + canvas, context, + last_frame_time = 0, frames_times_summatory = 0, + swap_and_drop_timer, + cache_box, + default_font_size, default_font_family, + settings_overwrite, + built = false, + started = false, + font_minimum_size, + events_cache_timer; + + this.map = []; + let cells = this.cells; + let cell_size = this.cell_size; + let quality = this.quality; + let quality_x = this.quality_x; + let quality_y = this.quality_y; + this.cells_x = 0; + this.cells_y = 0; + this.delta_time = 0; + + let item_self = this.item_self; + let hash_self = this.hash_self; + let object_name = this.object_name; + + this.Event = function(){ + + const self = this, + events = [], + properties = []; + + const construct = () => { + + events_cache.push(autoclean); + + }; + + this.execute = (callback, ...arguments) => events.forEach((event, i) => ( + event && + (typeof callback == "function" ? callback(properties[i]) : true) && + event(...arguments) + )); + + this.add = (callback, own_properties) => { + + let i = 0; + const l = events.length; + + for(; i < l; i ++) + if(!events[i]) + break; + + events[i] = callback; + properties[i] = own_properties; + + return i; + }; + + this.remove = i => events[i] = null; + + const autoclean = () => { + + const date = Date.now(); + + properties.forEach((own_properties, i) => { + if(own_properties && own_properties.last_used && date - own_properties.last_used > events_cache_timer){ + events[i] = null; + properties[i] = null; + }; + }); + + }; + + this.update = (i, date) => events[i] && (properties[i].last_used = date); + + construct(); + + }; + + this.on_screen_change = new this.Event(); + this.on_ready = new this.Event(); + this.on_click = new this.Event(); + this.on_click_down = new this.Event(); + this.on_click_up = new this.Event(); + this.on_key_down = new this.Event(); + this.on_key_up = new this.Event(); + + const construct = () => { + + settings = ( + settings instanceof Array ? settings : + typeof settings == "object" ? [settings] : + []).filter(inputs => typeof inputs == "object" && !(inputs instanceof Array)); + + self.settings("autostart") && self.start(); + + }; + + this.start = callback => { + + const end = status => typeof callback == "function" && callback(status); + + if(started){ + end(false); + return false; + }; + started = true; + + settings_overwrite = self.settings(["settings_overwrite", "overwrite"]); + frames_per_second = self.settings(["frames_per_second", "fps"]); + events_cache_timer = self.settings("events_cache_timer"); + object_name = self.object_name = self.settings("object_name"); + + thread = setInterval(execute, 1000 / frames_per_second); + + if(self.settings("autobuild")) + self.build(callback); + else + end(true); + + return true; + }; + + this.build = callback => { + + const position = self.settings("position"), + end = status => typeof callback == "function" && callback(status); + + if(built){ + end(false); + return false; + }; + built = true; + + if(position){ + + if(position.tagName || position.nodeName){ + end_build(position); + end(true); + return; + }; + + if(typeof position != "string"){ + console.error("position_not_string"); + end(false); + return; + }; + + if(!position.trim()){ + console.error("position_selector_empty"); + end(false); + return; + }; + + let html_object; + + try{ + if(html_object = document.querySelector(position)){ + end_build(html_object); + end(true); + return; + }; + }catch(exception){ + console.error(exception); + console.error("position_bad_selector"); + end(false); + return; + }; + + const date = Date.now(), + timeout = self.settings("preload_timeout"); + let interval = setInterval(() => { + if(html_object = document.querySelector(position)){ + clearInterval(interval); + end_build(html_object); + end(true); + }else if(Date.now() - date > timeout){ + clearInterval(interval); + console.error("position_timeout"); + end(false); + }; + }, frames_per_second); + + }else{ + console.error("no_position"); + end(false); + }; + + return true; + }; + + const end_build = position => { + + quality = self.quality = self.settings("quality"); + quality_x = self.quality_x = self.settings("quality_x"); + quality_y = self.quality_y = self.settings("quality_y"); + cells = self.cells = self.settings("cells"); + default_font_size = self.settings("font_size"); + default_font_family = self.settings("font_family"); + + cache.quality = 0; + cache.quality_x = 0; + cache.quality_y = 0; + + cache.screen = {x : 0, y : 0}; + cache.origin = {x : 0, y : 0}; + + item_self = self.item_self = (position || document.querySelector("body")).appendChild(document.createElement("div")); + cache_box = item_self.appendChild(document.createElement("div")); + canvas = item_self.appendChild(document.createElement("canvas")); + hash_self = self.hash_self = self.settings(["id", "hash"]) || self.create_id(); + + item_self.setAttribute("id", hash_self); + item_self.setAttribute("class", ["kanvas", hash_self].concat((self.settings("class") || "").split(/\s+/)).filter((key, i, array) => array.indexOf(key) == i).join(" ")); + item_self.setAttribute("data-hash", hash_self); + item_self.setAttribute("data-cells", cells); + item_self.setAttribute("data-minimum-font-size", font_minimum_size = self.settings("font_minimum_size")); + + cache_box.setAttribute("class", "kanvas-cache-box"); + cache_box.setAttribute("style", ` + position : absolute; + top : 0%; + left : 0%; + width : 100%; + height : 100%; + visibility : hidden; + z-index : 10; + opacity : 0; + `.replace(/[\r\n\s]+/g, "")); + + canvas.setAttribute("class", "kanvas-ui"); + canvas.setAttribute("style", ` + position : absolute; + top : 0%; + left : 0%; + width : 100%; + height : 100%; + z-index : 20; + `.replace(/[\r\n\s]+/g, "")); + canvas.onclick = event => on_click(canvas, event, "click"); + canvas.onmousedown = event => on_click(canvas, event, "down"); + canvas.onmouseup = event => on_click(canvas, event, "up"); + canvas.onkeydown = event => on_key(canvas, event, "down"); + canvas.onkeyup = event => on_key(canvas, event, "up"); + + context = canvas.getContext("2d"); + + context.id = self.create_id(); + + swap_and_drop_timer = self.settings("swap_and_drop_timer"); + + self.on_ready.execute(); + + }; + + this.nulls = nulls => typeof nulls == "boolean" ? nulls : self.settings("nulls", null, false, false); + + this.default_value = (_default, nulls) => _default !== undefined && (self.nulls(nulls) || _default !== null) ? _default : self.settings("default_value", null, null, true); + + this.settings = (names, inputs, _default, nulls) => { + + const l = (names = ( + names instanceof Array ? names : + typeof names == "string" ? [names] : + [] + ).filter((name, i, array) => name && typeof name == "string" && array.indexOf(name) == i)).length; + + if(l){ + + const m = (inputs = ( + inputs instanceof Array ? inputs : + typeof inputs == "object" ? [inputs] : + []).concat(settings, custom, [default_settings])).length; + + nulls = self.nulls(nulls); + + for(let j = 0; j < m; j ++) + if(inputs[j] && typeof inputs[j] == "object" && !(inputs[j] instanceof Array)) + for(let i = 0; i < l; i ++) + if(inputs[j][names[i]] !== undefined && (nulls || inputs[j][names[i]] !== null)) + return inputs[j][names[i]]; + }; + return self.default_value(_default, nulls); + }; + + this.settings_add = (inputs, overwrite) => { + if(!inputs) + return; + + if(typeof inputs == "string"){ + try{ + inputs = JSON.parse(inputs); + }catch(exception){}; + }; + + if(typeof inputs == "object"){ + if(inputs instanceof Array) + inputs.forEach(inputs, overwrite); + else{ + typeof overwrite != "boolean" && (overwrite = settings_overwrite); + for(const key in inputs) + if(overwrite || custom[key] === undefined) + custom[key] = inputs[key]; + }; + }; + + }; + + this.create_id = () => { + + let id; + const l = id_alphabet.length; + + do{ + id = ""; + while((id += id_alphabet[l * Math.random() >> 0]).length < id_length); + }while( + ids.includes(id) || + !/^[a-z]/i.test(id) || + document.querySelector("." + id + ",#" + id + ",[name=" + id + "]") + ); + ids.push(id); + + return id; + }; + + const execute = () => { + + const date = Date.now(); + let screen_changed = false; + + if(item_self && (cache.screen.x != item_self.offsetWidth || cache.screen.y != item_self.offsetHeight)){ + screen_changed = true; + + cache.screen.x = item_self.offsetWidth; + cache.screen.y = item_self.offsetHeight; + + const font_size = cache.screen[cache.screen.x < cache.screen.y ? "x" : "y"] / cells; + + item_self.style.fontSize = (font_size < font_minimum_size ? font_minimum_size : font_size) + "px"; + + }; + + if(canvas){ + + if(last_frame_time){ + + const frame_time = date - last_frame_time; + + frames_times.push(frame_time); + frames_times_summatory += frame_time; + + self.delta_time = frame_time / 1000; + + while(frames_times.length > frames_per_second) + frames_times_summatory -= frames_times.shift(); + + }; + + last_frame_time = date; + + if(screen_changed || cache.quality != quality){ + + const width = cache.screen.x * quality, + height = cache.screen.y * quality; + + cache.quality = quality; + canvas.setAttribute("width", width); + canvas.setAttribute("height", height); + cache.origin.x = width / 2; + cache.origin.y = height / 2; + + cell_size = self.cell_size = (width > height ? height : width) / cells; + + number_of_cells.x = width / cell_size; + number_of_cells.y = height / cell_size; + + this.cells_x = number_of_cells.x / 2; + this.cells_y = number_of_cells.y / 2; + + for(const key in cache) + if(cache[key] && cache[key].data) + cache[key].data = null; + + self.on_screen_change.execute(); + + }; + + }; + + threads.forEach(thread => thread && thread()); + + if(canvas){ + + context.beginPath(); + context.clearRect(0, 0, cache.screen.x * quality, cache.screen.y * quality); + context.translate(cache.origin.x, cache.origin.y); + + draw(context, self.map, 0, 0); + + context.translate(-cache.origin.x, -cache.origin.y); + + for(const key in cache) + if(cache[key] && cache[key].last_used && date - cache[key].last_used > swap_and_drop_timer) + delete cache[key]; + + }; + + events_cache.forEach(autoclean => autoclean()); + + }; + + this.set_quality = new_quality => quality = self.quality = new_quality; + this.set_quality_x = new_quality => quality_x = self.quality_x = new_quality; + this.set_quality_y = new_quality => quality_y = self.quality_y = new_quality; + + const _x = x => x * cell_size; + const _y = y => y * cell_size; + const size = size => size * cell_size; + + const set_cache = (context, status) => { + + !status && cache[context.id] && cache[context.id].ok && (cache[context.id].ok = false); + + return status; + }; + + const set_border = (context, inputs) => { + + const has_border = !!(inputs.border_color || !isNaN(inputs.border_width)); + + inputs.border_color && (context.strokeStyle = inputs.border_color); + !isNaN(inputs.border_width) && (context.lineWidth = size(inputs.border_width)); + + return has_border; + }; + + const set_background = (context, inputs) => { + + const has_background = !!(inputs.background || (!inputs.border_color && isNaN(inputs.border_width))); + + if(inputs.background){ + if(inputs.background instanceof Array){ + + const v = inputs.background, + is_linear = v.length == 5, + gradient = ( + is_linear ? context.createLinearGradient(_x(v[0]), _y(v[1]), _x(v[2]), _y(v[3])) : + context.createRadialGradient(_x(v[0]), _y(v[1]), _x(v[2]), _y(v[3]), size(v[4]), size(v[5])) + ); + + inputs.background[is_linear ? 4 : 6].forEach(color => gradient.addColorStop(color[0], color[1])); + + context.fillStyle = gradient; + + }else + context.fillStyle = inputs.background; + }; + + return has_background; + }; + + const set_shadow = (context, inputs, shape_callback) => { + + const shadows = inputs.shadow || inputs.shadows; + + (shadows && shadows.length ? shadows[0] instanceof Array ? shadows : [shadows] : []).forEach(shadow => { + [context.shadowOffsetX, context.shadowOffsetY, context.shadowBlur, context.shadowColor] = shadow; + context.shadowOffsetX = size(shadow[0]); + context.shadowOffsetY = size(shadow[1]); + context.shadowBlur = size(shadow[2]); + context.shadowColor = size(shadow[3]); + shape_callback(); + }); + + }; + + const shapes = { + rectangle : (context, inputs) => { + + const x = _x(inputs.x), + y = _y(inputs.y), + width = size(inputs.width), + height = size(inputs.height), + has_border = set_border(context, inputs), + has_background = set_background(context, inputs); + + set_shadow(context, inputs, () => context.rect(x, y, width, height)); + has_background && context.fillRect(x, y, width, height); + has_border && context.strokeRect(x, y, width, height); + + return set_cache(context, true); + }, + image : (context, inputs) => { + + const url = inputs.url; + + if(url){ + + const cached = cache[url]; + + if(!cached){ + (cache[url] = { + image : new Image(), + loaded : false, + last_used : Date.now() + }).image.src = url; + cache[url].image.crossOrigin = "anonymous"; + cache[url].image.onload = () => cache[url].loaded = true; + return set_cache(context, false); + }; + + if(cached.loaded){ + + let width = inputs.width, + height = inputs.height; + const cut_x = inputs.cut_x || 0, + cut_y = inputs.cut_y || 0, + cut_width = inputs.cut_width || 0, + cut_height = inputs.cut_height || 0, + position_x = inputs.x || 0, + position_y = inputs.y || 0, + x = _x(position_x), + y = _y(position_y), + end_width = size(width), + end_height = size(height); + + !width && (width = cache.quality * (cut_width || cache[url].image.width - cut_x) / cell_size); + !height && (height = cache.quality * (cut_height || cache[url].image.height - cut_y) / cell_size); + + set_shadow(context, inputs, () => context.rect(x, y, end_width, end_height)); + set_border(context, inputs); + context.drawImage( + cache[url].image, + cut_x, cut_y, cut_width || cache[url].image.width - cut_x, cut_height || cache[url].image.height - cut_y, + x, y, end_width, end_height + ); + cache[url].last_used = Date.now(); + + return set_cache(context, true); + }; + + }; + + return set_cache(context, false); + }, + cache : (context, inputs) => { + + const width = inputs.width ? inputs.width * cell_size : canvas.getAttribute("width"), + height = inputs.height ? inputs.height * cell_size : canvas.getAttribute("height"); + let status = false; + + if(!cache[inputs.name]){ + + const subcanvas = cache_box.appendChild(document.createElement("canvas")); + + cache[inputs.name] = { + canvas : subcanvas, + data : null + }; + cache[inputs.name].context = subcanvas.getContext("2d"); + + cache[inputs.name].context.id = inputs.name; + + subcanvas.setAttribute("data-id", cache[inputs.name].context.id); + + cache[inputs.name].context.translate(inputs.x || 0, inputs.y || 0); + + }; + + if(cache[inputs.name].data){ + if(cache[inputs.name].image_loaded){ + context.drawImage(cache[inputs.name].image, _x(inputs.x || 0), _y(inputs.y || 0), cache[inputs.name].image.width, cache[inputs.name].image.height); + status = true; + }else if(!cache[inputs.name].image){ + + cache[inputs.name].image = new Image(); + + cache[inputs.name].image.src = cache[inputs.name].data; + cache[inputs.name].image.onload = () => { + // cache[inputs.name].canvas.remove(); + cache[inputs.name].image_loaded = true; + }; + // cache[inputs.name].image.onerror = () => cache[inputs.name].canvas.remove(); + + }; + }else{ + + cache[inputs.name].canvas.setAttribute("width", width); + cache[inputs.name].canvas.setAttribute("height", height); + + cache[inputs.name].context.beginPath(); + cache[inputs.name].context.clearRect(0, 0, width, height); + cache[inputs.name].context.translate(width / 2, height / 2); + + cache[inputs.name].image = null; + cache[inputs.name].image_loaded = false; + cache[inputs.name].ok = true; + + draw(cache[inputs.name].context, inputs.childs, 0, 0); + + cache[inputs.name].context.closePath(); + + cache[inputs.name].ok && + (cache[inputs.name].data = cache[inputs.name].canvas.toDataURL("image/png", 1.0)); + + }; + + cache[inputs.name].last_used = Date.now(); + + return set_cache(context, status); + }, + text : (context, inputs) => { + + const x = _x(inputs.x), + y = _y(inputs.y), + has_border = set_border(context, inputs), + has_background = set_background(context, inputs); + + inputs.align && (context.textAlign = inputs.align); + inputs.baseline && (context.textBaseline = inputs.baseline); + !isNaN(inputs.border_width) && (context.lineWidth = size(inputs.border_width)); + context.font = (inputs.style ? inputs.style + " " : "") + size(inputs.size || default_font_size) + "px " + (inputs.family || default_font_family); + + set_shadow(context, inputs, () => context.fillText(inputs.text, x, y)); + has_background && context.fillText(inputs.text, x, y); + has_border && context.strokeText(inputs.text, x, y); + + return true; + } + }; + + this.string_variables = (string, variables) => string.replace(/\{([^\{\}]+)\}/g, (...arguments) => variables[arguments[1]] !== undefined ? variables[arguments[1]] : arguments[0]); + + const draw = (context, level, x, y) => level.forEach(values => { + if(values && (shapes[values.type] || ["block"].includes(values.type))){ + + const sub_x = _x(x + (values.margin_x || 0)), + sub_y = _y(y + (values.margin_y || 0)), + date = Date.now(); + + context.save(); + context.translate(sub_x, sub_y); + + const transform = context.getTransform(); + + values.rotate && context.rotate(2 * Math.PI * values.rotate / 360); + !isNaN(values.alpha) && (context.globalAlpha = values.alpha); + + if(values.on_click){ + values.context_x = transform.e / quality; + values.context_y = transform.f / quality; + if(!values.last_used || date - values.last_used > events_cache_timer) + values.i = self.on_click.add(eval(self.string_variables(values.on_click, {object_name : object_name})), values); + else + self.on_click.update(values.i, date); + values.last_used = date; + }; + + values.type != "block" && shapes[values.type](context, values); + + values.type != "cache" && values.childs && draw(context, values.childs, values.x, values.y); + + context.translate(-sub_x, -sub_y); + context.restore(); + + }; + }); + + this.get_real_fps = this.get_real_frames_per_second = () => frames_times_summatory ? 1000 / (frames_times_summatory / frames_times.length) : 0; + + this.threads_add = callback => { + + let i = 0; + const l = threads.length; + + for(; i < l; i ++) + if(!threads[i]) + break; + + threads[i] = callback; + + return i; + }; + + this.threads_remove = i => threads[i] = null; + + this.get_cells_x = () => number_of_cells.x; + this.get_cells_y = () => number_of_cells.y; + + this.extends = object => { + for(const key in self) + if(object[key] === undefined) + object[key] = self[key]; + }; + + const on_click = (canvas, event, action) => { + + switch(action){ + case "click": + self.on_click.execute(properties => ( + event.clientX >= properties.context_x + (properties.x * cell_size) && + event.clientY >= properties.context_y + (properties.y * cell_size) && + event.clientX <= properties.context_x + ((properties.x + properties.width) * cell_size) && + event.clientY <= properties.context_y + ((properties.y + properties.height) * cell_size) + ), canvas, event); + break; + }; + + }; + + construct(); + +}; \ No newline at end of file diff --git a/Public/ecma/version/221106/Kanvas.ecma.js b/Public/ecma/version/221106/Kanvas.ecma.js new file mode 100755 index 0000000..38dcfa5 --- /dev/null +++ b/Public/ecma/version/221106/Kanvas.ecma.js @@ -0,0 +1,936 @@ +Kanvas = function(input){ + + const self = this, + default_settings = { + quality : 1, + quality_x : 1, + quality_y : 1, + cells : 100, + origin : 5, // Posición origen. Mirar teclado numérico para ver los diferentes valores para cada posición. + frames_per_second : 60, + ratio : null, // Expone la proporción de tamaño del Canvas (16/9 para pantallas WideScreen por ejemplo). Si es equivalente a falso cubrirá todo el área de la capa donde se encuentre. + overwrite : false, + position : "body", + autostart : true, + object_name : "kanvas", + class : "kanvas", + application : "Kanvas", + x : 0, + y : 0, + width : 0, + height : 0, + color : "#000", + blur : 0, + italic : false, + bold : false, + size : 1, + font : "Arial", + align : "left", + alpha : 1, + degrees : 0, + baseline : "Alphabetic", + shadow_x : 0, + shadow_y : 0, + shadow_color : "#000", + shadow_blur : 0, + border_color : "#000", + border_width : 0, + text_italic : false, + text_bold : false, + text_size : 1, + font_family : "Arial", + text_color : "#000", + text_align : "left", + text_alpha : 1, + rotate_x : 0, + rotate_y : 0, + rotate_degrees : 0, + image_x : 0, + image_y : 0, + image_alpha : 1, + rectangle_color : "#000", + rectangle_alpha : 1, + rectangle_x : 0, + rectangle_y : 0, + text_baseline : "Alphabetic", + default_value : null, + hash_alphabet : "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + hash_length : 7, + frames_per_second_samples : 20, + settings_overwrite : false, + ajax_timeout : 2000 + }, + custom = {}, + // cache = [], + _screen = {x : 0, y : 0}, + position = {x : 0, y : 0}, + events = {}, + threads = [], + hashes = [], + attributes = { + natives : ["id", "class", "onmousemove", "tabindex", "onkeydown", "onkeyup"] + }, + cache = {}, + frames_per_second_samples = [], + delta_time = 0; + let q, qx, qy, // Calidad porcentual. + c, // Número de celdas en el lado más corto de la pantalla o área de trabajo rectangular. + fx, fy, // Posición contra el foco. + dx, dy, // Distancia desde los laterales hasta el cuadrado de trabajo. + s, // Tamaño de la celda. Solo se mide un lado pues será cuadrada. + mx, my, // Posición origen del lienzo. + thread = null, + timeout = 0, + last_time = 0, + started = false, + cache_container, context, canvas, + // cache_l = 0, + thread_object = null, + frames_per_second_samples_number, + last_frame_per_second_sample = Date.now(), + real_frames_per_seconds = 0, + ajax_timeout; + + let item_self = this.item_self; + let hash_self = this.hash_self; + let object_name = this.object_name; + let mouse = this.mouse = {x : 0, y : 0}; + + this.LOADING = 1 << 0; + this.LOADED = 1 << 1; + this.ERROR = 1 << 2; + + this.map = []; + + const null_or_undefined = this.null_or_undefined = value => value === undefined || value === null; + + this.get = (url, callback) => { + + let ended = false; + const ajax = new XMLHttpRequest(), + end = status => { + if(ended) + return; + ended = true; + typeof callback == "function" && callback(ajax.response, ajax.status, ajax.readyState, status, status == "OK"); + }, + date = Date.now(); + + ajax.open("get", url, true); + ajax.timeout = ajax_timeout; + ajax.onreadystatechange = () => { + if(ended) + return; + if(ajax.readyState == 4) + end((ajax.status >= 200 && ajax.status < 300) || [301, 302, 304].includes(ajax.status) ? "OK" : "HTTP_ERROR"); + else if(Date.now() - date > ajax_timeout) + end("FORCED_TIMEOUT"); + }; + ajax.send(null); + + ajax.ontimeout = () => end("TIMEOUT"); + ajax.onabort = () => end("ABORTED"); + ajax.onerror = () => end("ERROR"); + + return ajax; + }; + + const allow_nulls = this.allow_nulls = nulls => typeof nulls == "boolean" ? nulls : settings(["nulls", "allow_nulls"], null, false, false); + + const default_value = this.default_value = (_default, nulls) => _default !== undefined && (nulls || _default !== null) ? _default : settings(["default_value", "default", "by_default"], null, null, true); + + this.settings_add = (inputs, overwrite, callback) => { + + if(inputs instanceof Array){ + + let loaded = 0; + const end = () => ++ loaded == inputs.length && typeof callback == "function" && callback(); + + inputs.forEach(input => self.settings_add(input, overwrite, end)); + + return; + }; + + if(typeof inputs == "object"){ + typeof overwrite != "boolean" && (overwrite = settings(["settings_overwrite", "overwrite"])); + for(const key in inputs) + (overwrite || custom[key] === undefined) && (custom[key] = inputs[key]); + inputs.autostart !== undefined && (input.autostart = inputs.autostart); + typeof callback == "function" && callback(); + return; + }; + + if(typeof inputs == "string"){ + + let json; + + try{ + if(json = JSON.parse(inputs)){ + self.settings_add(json, overwrite, callback); + return; + }; + }catch(exception){}; + + self.get(inputs, response => { + try{ + if(json = JSON.parse(response)){ + self.settings_add(json, overwrite, callback); + return; + }; + }catch(exception){}; + typeof callback == "function" && callback(); + }); + + return; + }; + + typeof callback == "function" && callback(); + + }; + + const settings = this.settings = (names, inputs, _default, nulls) => { + if(!names) + return default_value(_default, nulls); + + nulls = allow_nulls(nulls); + + const l = (names.push ? names : names = [names]).length, + m = (inputs = (inputs ? inputs.push ? inputs : [inputs] : []).concat([input, custom, default_settings])).length; + + for(let j = 0; j < m; j ++) + if(typeof inputs[j] == "object") + for(let i = 0; i < l; i ++) + if(names[i] && inputs[j][names[i]] !== undefined && (nulls || inputs[j][names[i]] !== null)) + return inputs[j][names[i]]; + return default_value(_default, nulls); + }; + + const threads_function = () => threads.forEach(thread => thread && thread()); + + const threads_start = this.threads_start = frames_per_second => thread_object === null && (thread_object = setInterval(threads_function, 1000 / (isNaN(frames_per_second) || frames_per_second < 1 ? settings(["frames_per_second", "fps"]) : frames_per_second))); + + const threads_stop = this.threads_stop = () => { + + if(thread_object === null) + return; + + clearInterval(thread_object); + thread_object = null; + + }; + + const threads_add = this.threads_add = callback => { + if(typeof callback != "function") + return null; + + let i = 0; + const l = threads.length; + + for(; i < l; i ++) + if(!threads[i]) + break; + + threads[i] = callback; + + return i; + }; + + const threads_remove = this.threads_remove = i => !isNaN(i) && threads[i] && (threads[i] = null); + + const is_html_object = this.is_html_object = variable => typeof variable == "object" && (variable.tagName || variable.nodeName); + + const preload = this.preload = (selector, callback) => { + if(typeof callback != "function") + return; + + if(!selector){ + callback(null, false, "NO_SELECTOR"); + return; + }; + if(is_html_object(selector)){ + callback(selector, false, "OK"); + return; + }; + if(!selector.substr){ + callback(null, false, "BAD_TYPE"); + return; + }; + + let item; + + try{ + if(item = document.querySelector(selector)){ + callback(item, false, "OK"); + return; + }; + }catch(exception){ + callback(null, false, "BAD_SELECTOR"); + return; + }; + + const timeout = settings(["preload_timeout", "timeout"]), + date = Date.now(); + let preload = threads_add(() => { + if(item = document.querySelector(selector)){ + threads_remove(preload); + callback(item, true, "OK"); + }else if(Date.now() - date > timeout){ + threads_remove(preload); + callback(null, true, "TIMEOUT"); + }; + }); + + }; + + const hash = this.hash = () => { + + let hash, alphabet = settings(["hash_alphabet", "alphabet"]); + const length = settings(["hash_length", "length"]), + l = (alphabet.push ? alphabet : alphabet = alphabet.split("")).length; + + do{ + hash = ""; + while((hash += alphabet[Math.random() * l >> 0]).length < length); + }while( + hashes.includes(hash) || + /^\d/.test(hash) || + document.querySelector("." + hash + ",#" + hash + ",[name=" + hash + "]") + ); + hashes.push(hash); + + return hash; + }; + + const set_attribute = this.set_attribute = (item, custom_attributes) => { + if(!is_html_object(item) || typeof custom_attributes != "object") + return; + + for(const name in custom_attributes) + item.setAttribute((attributes.natives.includes(name) ? "" : "data-") + name.replace(/[^a-z\d-]+/g, "-"), custom_attributes[name]); + + }; + + const construct = () => { + + const custom_attributes = { + natives : settings("attributes_natives") + }; + + for(const key in custom_attributes){ + !attributes[key] && (attributes[key] = []); + (custom_attributes ? custom_attributes.push ? custom_attributes : [custom_attributes] : []).forEach(new_attribute => attributes[key].push(new_attribute)); + }; + + object_name = self.object_name = settings("object_name"); + + settings("autostart") && self.start(); + + }; + + const Events = this.Events = function(){ + + const events = []; + + this.add = callback => { + if(typeof callback != "function") + return null; + + let i = 0; + const l = events.length; + + while(i < l){ + if(events[i] === null) + break; + i ++; + }; + + events[i] = callback; + + return i; + }; + + this.remove = i => !isNaN(i) && i >= 0 && events[i] && (events[i] = null); + + this.execute = (...inputs) => events.forEach(event => event && event(...inputs)); + + }; + + const range_analyze = range => !range || ( + mouse.x >= range.x && mouse.x <= range.x + range.width && + mouse.y >= range.y && mouse.y <= range.y + range.height + ); + + const on_resize_method = screen => { + + if(_screen.x == item_self.offsetWidth && _screen.y == item_self.offsetHeight) + return; + + const width = canvas.width = (_screen.x = item_self.offsetWidth) * q * qx, + height = canvas.height = (_screen.y = item_self.offsetHeight) * q * qy; + + if(width < height){ + s = width / c; + dx = 0; + dy = -(c - (c * height / width)) / 2; + mx = position.x; + my = position.y + dy; + }else{ + s = height / c; + dx = -(c - (c * width / height)) / 2; + dy = 0; + mx = position.x + dx; + my = position.y; + }; + + //resize_methods.forEach((method) => {if(method)method();}); + execute_event("resize"); + + }; + + const position_set = () => { + + const origin = settings("origin"); + + position.x = c * (.5 * ((origin - 1) % 3)); + position.y = c * (1 - (.5 * ((origin - 1) / 3 >> 0))); + + }; + + const calculate_real_frames_per_seconds = () => { + + const now = Date.now(), + time = now - last_frame_per_second_sample; + + frames_per_second_samples.push(time); + last_frame_per_second_sample = now; + + while(frames_per_second_samples.length > frames_per_second_samples_number) + frames_per_second_samples.shift(); + + real_frames_per_seconds = 1000 / (frames_per_second_samples.reduce((a, b) => a + b) / frames_per_second_samples.length); + delta_time = time / 1000; + + }; + + this.start = callback => { + + const end = status => typeof callback == "function" && callback(status); + + if(started){ + end(false); + return false; + }; + started = true; + + q = settings(["quality", "q"]); + qx = settings(["quality_x", "qx"]); + qy = settings(["quality_y", "qy"]); + timeout = 1000 / settings("frames_per_second"); + c = settings("cells"); + position_set(); + threads_start(); + ajax_timeout = settings("ajax_timeout"); + + preload(settings("position"), (position, asynchronous, error) => { + + if(!position){ + console.error("ERROR. Position HTML for install GUI CANVAS is bad. [" + error + "]"); + return; + }; + + const _class = (hash_self = self.hash_self = hash()) + " " + settings("class"); + + !new RegExp("\\b" + default_settings.class + "\\b").test(_class) && (_class += " " + default_settings.class); + + set_attribute(item_self = self.item_self = position.appendChild(document.createElement("div")), { + id : hash_self, + hash : hash_self, + class : _class, + application : default_settings.application, + onmousemove : object_name + ".check_mouse(this, event);", + tabindex : 0, + onkeydown : object_name + ".key_down(this, event);", + onkeyup : object_name + ".key_up(this, event);", + cells : c, + mouse_x : 0, + mouse_y : 0 + }); + set_attribute(cache_container = item_self.appendChild(document.createElement("div")), { + class : "cache" + }); + set_attribute(canvas = item_self.appendChild(document.createElement("canvas")), { + class : "canvas" + }); + context = canvas.getContext("2d"); + + thread = threads_add(thread_method); + on_resize_thread = threads_add(on_resize_method); + item_self.onclick = () => execute_event("click"); + + frames_per_second_samples_number = self.settings("frames_per_second_samples"); + threads_add(calculate_real_frames_per_seconds); + + end(true); + + }); + + return true; + }; + + // o = Origin {mx, my} + const draw = this.draw = (map, context, o) => map && map.forEach((level, i) => level && (level.push && draw(level, context, o || {mx : mx, my : my}) || (level.type && components[level.type] && components[level.type](level, context, self, o || {mx : mx, my : my})))); + + const refresh_draw = () => { + + if(!context) + return; + + context.clearRect(0, 0, canvas.width, canvas.height); + draw(self.map, context); + + }; + + const thread_method = () => { + + const date = Date.now(); + + if(date - last_time < timeout) + return; + last_time = date; + + refresh_draw(); + + }; + + // Establecer posición sobre el foco de origen. + // Establecer posición sobre los laterales del recuadro o área de trabajo. + const value = this.value = (value, quality) => q * value * (quality || 1); + // const _x = this._x = value => q * qx * value * s; + // const _y = this._y = value => q * qy * value * s; + const _x = this._x = value => value * s; + const _y = this._y = value => value * s; + + this.preload_cache_items = (items, callback_per_item, callback) => { + + const end = status => typeof callback == "function" && callback(status); + + typeof items == "string" && (items = [items]); + + if(!(items instanceof Array)){ + end(false); + return; + }; + + let fully = true, + loaded = 0; + const has_callback_per_item = typeof callback_per_item == "function", + on_item_loaded = (url, ok) => { + ok !== undefined && (cache[url].status = ok ? self.LOADED : self.ERROR); + cache[url].on_load.execute(url, ok); + has_callback_per_item && callback_per_item(url, ok); + ok === false && fully && (fully = false); + ++ loaded == items.length && end(fully); + }; + + items.forEach(url => { + + if(cache[url]){ + if(cache[url].status == self.LOADING) + cache[url].on_load.add(has_callback_per_item); + else + on_item_loaded(url); + return; + }; + + const extension = ((url.match(/\.([^\.]+)/) || [])[1] || "").toLowerCase(); + + cache[url] = { + status : self.LOADING, + on_load : new Events() + }; + + switch(extension){ + case "jpg": + case "jpeg": + case "jpge": + case "png": + case "webp": + case "gif": + case "tif": + case "tiff": + case "pcx": + case "bmp": + + const image = new Image(); + + cache[url].type = "image"; + cache[url].image = image; + + image.src = url; + image.onload = () => on_item_loaded(url, true); + image.onerror = () => on_item_loaded(url, false); + + break; + default: + + cache[url].type = "unknown"; + cache[url].status = self.ERROR; + on_item_loaded(url, false); + + break; + }; + + }); + + }; + + const angle = this.angle = (x, y, randians) => { + + if(typeof x == "object"){ + + const line = x.push ? { + x : x[0] - y[0], + y : x[1] - y[1] + } : { + x : x.x - y.x, + y : x.y - y.y + }; + + x = line.x; + y = line.y; + + }; + + let angle = Math.asin(y / ((x ** 2) + (y ** 2)) ** .5); + + // if(x >= 0) + // angle += Math.PI / 2; + // else + // angle = (1.5 * Math.PI) - angle; + + return (x >= 0 ? angle + (Math.PI / 2) : ((1.5 * Math.PI) - angle)) * (randians ? 1 : 180 / Math.PI); + }; + + const shadow = (data, context) => { + + const z = dx < dy ? _x : _y; + + if(!data.ok){ + isNaN(data.x) && (data.x = settings(["shadow_x", "x"])); + isNaN(data.y) && (data.y = settings(["shadow_y", "y"])); + !data.color && (data.color = settings(["shadow_color", "color"])); + isNaN(data.blur) && (data.blur = settings(["shadow_blur", "blur"])); + data.ok = true; + }; + + context.shadowOffsetX = z(data.x); + context.shadowOffsetY = z(data.y); + context.shadowColor = data.color; + context.shadowBlur = z(data.blur); + + }; + + const border = (data, context) => { + + if(!data.ok){ + !data.color && (data.color = settings(["border_color", "color"])); + isNaN(data.width) && (data.width = settings(["border_width", "width"])); + data.ok = true; + }; + + context.strokeStyle = data.color; + context.lineWidth = (dx < dy ? _x : _y)(data.width); + + }; + + const components = { + rotate : (data, context, kanvas, o) => { + if(data.ignore) + return; + + if(!data.ok){ + isNaN(data.x) && (data.x = settings(["rotate_x", "x"])); + isNaN(data.y) && (data.y = settings(["rotate_y", "y"])); + isNaN(data.degrees) && (data.degrees = settings(["rotate_degrees", "degrees"])); + data.ok = true; + }; + + // console.log(JSON.stringify(data)); + // console.log(JSON.stringify([_x(data.x + mx), _y(data.y + my)])); + + context.save(); + context.translate(_x(data.x + o.mx), _y(data.y + o.my)); + context.rotate(data.degrees * Math.PI / 180); + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + }, + image : (data, context, kanvas, o) => { + if(data.ignore) + return; + + !data.ok && !data.source && (data.source = data.src || data.url); + + if(cache[data.source]){ + + if(!data.ok){ + if(cache[data.source] && cache[data.source].status == self.LOADED){ + isNaN(data.swidth) && (data.swidth = cache[data.source].image.width); + isNaN(data.sheight) && (data.sheight = cache[data.source].image.height); + isNaN(data.width) && (data.width = data.swidth); + isNaN(data.height) && (data.height = data.sheight); + }; + isNaN(data.x) && (data.x = settings(["image_x", "x"])); + isNaN(data.y) && (data.y = settings(["image_y", "y"])); + isNaN(data.alpha) && (data.alpha = settings(["image_alpha", "alpha"])); + isNaN(data.sx) && (data.sx = 0); + isNaN(data.sy) && (data.sy = 0); + isNaN(data.mx) && (data.mx = 0); + isNaN(data.my) && (data.my = 0); + data.ok = true; + }; + + if(cache[data.source].status != self.LOADED) + return; + + const half_width = data.width / 2, + half_height = data.height / 2; + + context.save(); + context.globalAlpha = data.alpha; + context.translate(_x(o.mx + data.x + data.mx + half_width), _y(o.my + data.y + data.my + half_height)); + context.rotate(data.rotate * Math.PI / 180); + context.drawImage( + cache[data.source].image, + data.sx, data.sy, data.swidth, data.sheight, + _x(-half_width), _y(-half_height), _x(data.width), _y(data.height) + ); + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + }else + self.preload_cache_items([data.source]); + + }, + // cache : (data, context, kanvas, o) => { + // if(data.ignore) + // return; + + // context.save(); + + // if(isNaN(data.cache_i)){ + + // const cache_canvas = cache_container.appendChild(document.createElement("canvas")), + // cache_context = cache_canvas.getContext("2d"), + // width = data.width || canvas.width, + // height = data.height || canvas.height; + // image = new Image(); + + // cache_canvas.width = width; + // cache_canvas.height = height; + + // get_new_cache_i(data); + // cache_context.save(); + // // cache_context.translate(_x(-o.mx), _y(-o.my)); + // draw(data.childs, cache_context, {mx : 0, my : 0}); + // image.src = cache_canvas.toDataURL("image/png"); + // cache[data.cache_i] = image; + // cache_context.restore(); + + // cache_canvas.remove(); + + // }; + + // context.drawImage(cache[data.cache_i], 0, 0); + // context.restore(); + + // }, + rectangle : (data, context, kanvas, o) => { + if(data.ignore)return; + + const proportion = canvas.width > canvas.height ? canvas.width / canvas.height : canvas.height / canvas.width; + + if(!data.ok){ + isNaN(data.alpha) && (data.alpha = settings(["rectangle_alpha", "alpha"])); + !data.color && (data.color = settings(["rectangle_color", "color"])); + isNaN(data.x) && (data.x = settings(["rectangle_x", "x"])); + isNaN(data.y) && (data.y = settings(["rectangle_y", "y"])); + isNaN(data.width) && (data.width = proportion * c); + isNaN(data.height) && (data.height = proportion * c); + isNaN(data.mx) && (data.mx = 0); + isNaN(data.my) && (data.my = 0); + data.ok = true; + }; + + context.save(); + data.shadow && (shadow(data.shadow, context)); + context.globalAlpha = data.alpha; + context.fillStyle = data.color; + context.translate(_x(o.mx + data.x + data.mx), _y(o.my + data.y + data.my)); + context.rotate(data.rotate * Math.PI / 180); + context.translate(_x(-data.mx), _y(-data.my)); + context.fillRect(_x(data.x), _y(data.y), _x(data.width), _y(data.height)); + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + }, + text : (data, context, kanvas, o) => { + if(data.ignore) + return; + + if(!data.ok){ + typeof data.italic != "boolean" && (data.italic = settings(["text_italic", "italic"])); + isNaN(data.bold) && typeof data.bold != "boolean" && (data.bold = settings(["text_bold", "bold"])); + isNaN(data.size) && (data.size = settings(["text_size", "size"])); + data.font && (data.font_family = data.font); + !data.font_family && (data.font_family = settings(["text_font_family", "text_font", "font"])); + !data.align && (data.align = settings(["text_align", "align"])); + isNaN(data.x) && (data.x = settings(["text_x", "x"])); + isNaN(data.y) && (data.y = settings(["text_y", "y"])); + !data.text && (data.text = ""); + isNaN(data.alpha) && (data.alpha = settings(["text_alpha", "alpha"])); + !data.baseline && (data.baseline = settings(["text_baseline", "baseline"])); + data.ok = true; + }; + + context.save(); + data.shadow && (shadow(data.shadow, context)); + context.globalAlpha = data.alpha; + context.textAlign = data.align; + context.textBaseline = data.baseline; + context.font = ( + (data.italic ? "italic " : "") + + (data.bold ? isNaN(data.bold) ? "bold " : data.bold + " " : "") + + (dx < dy ? _x : _y)(data.size) + "px " + + data.font_family + ); + if(data.color){ + context.fillStyle = data.color; + context.fillText(data.text, _x(data.x + mx), _y(data.y + my)); + }; + if(data.border){ + border(data.border, context); + context.strokeText(data.text, _x(data.x + mx), _y(data.y + my)); + }; + context.restore(); + + }, + block : (data, context, kanvas, o) => { + if(data.ignore) + return; + + if(!data.ok){ + isNaN(data.alpha) && (data.alpha = settings(["block_alpha", "alpha"])); + data.ok = true; + }; + + context.save(); + context.globalAlpha = data.alpha; + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + } + }; + + this.add_components = (json, overwrite) => { + if(!json) + return; + + !json.push && (json = [json]); + typeof overwrite != "bool" && (overwrite = settings("overwrite")); + + json.forEach((items) => { + if(!items) + return; + if(items.push) + self.add_components(items, overwrite); + else if(typeof items == "object") + for(let key in items) + (overwrite || !components[key]) && (components[key] = items[key]); + }); + + }; + + this.extends = (object, overwrite) => { + for(const key in self) + (overwrite || object[key] === undefined) && (object[key] = self[key]); + }; + + this.check_mouse = (item, event) => { + + item_self.setAttribute("data-mouse-x", mouse.x = (event.clientX * q * qx / s) - mx); + item_self.setAttribute("data-mouse-y", mouse.y = (event.clientY * q * qy / s) - my); + + execute_event("mouse_move"); + + }; + + const on_event = this.on_event = (name, method, range) => { + + if(typeof method != "function") + return null; + + !events[name] && (events[name] = { + methods : [], + l : 0, + ranges : [] + }); + + let i = 0; + + for(; i < events[name].l; i ++) + if(!events[name].methods[i]) + break; + + events[name].methods[i] = method; + events[name].ranges[i] = range; + events[name].l = events[name].methods.length; + + return i; + }; + + const remove_event = this.remove_event = (name, i) => events[name] && !isNaN(i) && i >= 0 && i < events[name].l && events[name].methods[i] && (events[name].methods[i] = null); + + const execute_event = this.execute_event = (name, input) => { + + if(events[name] && events[name].l) + for(let i = 0; i < events[name].l; i ++) + events[name].methods[i] && events[name].methods[i](range_analyze(events[name].ranges[i]), input); + + }; + + const event_range = this.event_range = (name, i) => events[name] && !isNaN(i) && i >= 0 && i < events[name].l ? events[name].ranges[i] : null; + + this.on_mouse_move = (method, range) => on_event("mouse_move", method, range); + this.on_resize = (method, range) => on_event("resize", method, range); + this.on_click = (method, range) => on_event("click", method, range); + this.on_key_down = (method, range) => on_event("key_down", method, range); + this.on_key_up = (method, range) => on_event("key_up", method, range); + + this.remove_mouse_move = i => {remove_event("mouse_move", i);}; + this.remove_resize = i => {remove_event("resize", i);}; + this.remove_click = i => {remove_event("click", i);}; + this.remove_key_down = i => {remove_event("key_down", i);}; + this.remove_key_up = i => {remove_event("key_up", i);}; + + this.range_mouse_move = i => event_range("mouse_move", i); + this.range_resize = i => event_range("resize", i); + this.range_click = i => event_range("click", i); + this.range_key_down = i => event_range("key_down", i); + this.range_key_up = i => event_range("key_up", i); + + this.key_down = (item, event) => execute_event("key_down", {code : event.keyCode}); + this.key_up = (item, event) => execute_event("key_up", {code : event.keyCode}); + + this.get_margins = () => ({x : mx, y : my}); + this.get_position = () => ({x : position.x, y : position.y}); + this.get_cells = () => c; + this.get_canvas_distance = () => ({x : dx, y : dy}); + this.get_cell_size = () => s; + + this.get_real_frames_per_second = () => real_frames_per_seconds; + this.delta_time = () => delta_time; + + construct(); + +}; diff --git a/Public/ecma/version/30311230/Kanvas.ecma.js b/Public/ecma/version/30311230/Kanvas.ecma.js new file mode 100755 index 0000000..7c89766 --- /dev/null +++ b/Public/ecma/version/30311230/Kanvas.ecma.js @@ -0,0 +1,782 @@ +Kanvas = function(input){ + + const self = this, + default_settings = { + quality : 1, + quality_x : 1, + quality_y : 1, + cells : 100, + origin : 5, // Posición origen. Mirar teclado numérico para ver los diferentes valores para cada posición. + frames_per_second : 60, + ratio : null, // Expone la proporción de tamaño del Canvas (16/9 para pantallas WideScreen por ejemplo). Si es equivalente a falso cubrirá todo el área de la capa donde se encuentre. + overwrite : false, + position : "body", + autostart : true, + object_name : "kanvas", + class : "kanvas", + application : "Kanvas", + x : 0, + y : 0, + width : 0, + height : 0, + color : "#000", + blur : 0, + italic : false, + bold : false, + size : 1, + font : "Arial", + align : "left", + alpha : 1, + degrees : 0, + baseline : "Alphabetic", + shadow_x : 0, + shadow_y : 0, + shadow_color : "#000", + shadow_blur : 0, + border_color : "#000", + border_width : 0, + text_italic : false, + text_bold : false, + text_size : 1, + font_family : "Arial", + text_color : "#000", + text_align : "left", + text_alpha : 1, + rotate_x : 0, + rotate_y : 0, + rotate_degrees : 0, + image_x : 0, + image_y : 0, + image_alpha : 1, + rectangle_color : "#000", + rectangle_alpha : 1, + rectangle_x : 0, + rectangle_y : 0, + text_baseline : "Alphabetic", + default_value : null, + hash_alphabet : "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + hash_length : 7 + }, + cache = [], + _screen = {x : 0, y : 0}, + position = {x : 0, y : 0}, + events = {}, + threads = [], + hashes = [], + attributes = { + natives : ["id", "class", "onmousemove", "tabindex", "onkeydown", "onkeyup"] + }; + let q, qx, qy, // Calidad porcentual. + c, // Número de celdas en el lado más corto de la pantalla o área de trabajo rectangular. + fx, fy, // Posición contra el foco. + dx, dy, // Distancia desde los laterales hasta el cuadrado de trabajo. + s, // Tamaño de la celda. Solo se mide un lado pues será cuadrada. + mx, my, // Posición origen del lienzo. + thread = null, + timeout = 0, + last_time = 0, + started = false, + cache_container, context, canvas, + cache_l = 0, + thread_object = null; + + let item_self = this.item_self; + let hash_self = this.hash_self; + let object_name = this.object_name; + let mouse = this.mouse = {x : 0, y : 0}; + + this.map = []; + + const null_or_undefined = this.null_or_undefined = value => value === undefined || value === null; + + const allow_nulls = this.allow_nulls = nulls => typeof nulls == "boolean" ? nulls : settings(["nulls", "allow_nulls"], null, false, false); + + const default_value = this.default_value = (_default, nulls) => _default !== undefined && (nulls || _default !== null) ? _default : settings(["default_value", "default", "by_default"], null, null, true); + + const settings = this.settings = (names, inputs, _default, nulls) => { + if(!names) + return default_value(_default, nulls); + + nulls = allow_nulls(nulls); + + const l = (names.push ? names : names = [names]).length, + m = (inputs = (inputs ? inputs.push ? inputs : [inputs] : []).concat([input, default_settings])).length; + + for(let j = 0; j < m; j ++) + if(typeof inputs[j] == "object") + for(let i = 0; i < l; i ++) + if(names[i] && inputs[j][names[i]] !== undefined && (nulls || inputs[j][names[i]] !== null)) + return inputs[j][names[i]]; + return default_value(_default, nulls); + }; + + const threads_function = () => threads.forEach(thread => thread && thread()); + + const threads_start = this.threads_start = frames_per_second => thread_object === null && (thread_object = setInterval(threads_function, 1000 / (isNaN(frames_per_second) || frames_per_second < 1 ? settings(["frames_per_second", "fps"]) : frames_per_second))); + + const threads_stop = this.threads_stop = () => { + + if(thread_object === null) + return; + + clearInterval(thread_object); + thread_object = null; + + }; + + const threads_add = this.threads_add = callback => { + if(typeof callback != "function") + return null; + + let i = 0; + const l = threads.length; + + for(; i < l; i ++) + if(!threads[i]) + break; + + threads[i] = callback; + + return i; + }; + + const threads_remove = this.threads_remove = i => !isNaN(i) && threads[i] && (threads[i] = null); + + const is_html_object = this.is_html_object = variable => typeof variable == "object" && (variable.tagName || variable.nodeName); + + const preload = this.preload = (selector, callback) => { + if(typeof callback != "function") + return; + + if(!selector){ + callback(null, false, "NO_SELECTOR"); + return; + }; + if(is_html_object(selector)){ + callback(selector, false, "OK"); + return; + }; + if(!selector.substr){ + callback(null, false, "BAD_TYPE"); + return; + }; + + let item; + + try{ + if(item = document.querySelector(selector)){ + callback(item, false, "OK"); + return; + }; + }catch(exception){ + callback(null, false, "BAD_SELECTOR"); + return; + }; + + const timeout = settings(["preload_timeout", "timeout"]), + date = Date.now(); + let preload = threads_add(() => { + if(item = document.querySelector(selector)){ + threads_remove(preload); + callback(item, true, "OK"); + }else if(Date.now() - date > timeout){ + threads_remove(preload); + callback(null, true, "TIMEOUT"); + }; + }); + + }; + + const hash = this.hash = () => { + + let hash, alphabet = settings(["hash_alphabet", "alphabet"]); + const length = settings(["hash_length", "length"]), + l = (alphabet.push ? alphabet : alphabet = alphabet.split("")).length; + + do{ + hash = ""; + while((hash += alphabet[Math.random() * l >> 0]).length < length); + }while( + hashes.includes(hash) || + /^\d/.test(hash) || + document.querySelector("." + hash + ",#" + hash + ",[name=" + hash + "]") + ); + hashes.push(hash); + + return hash; + }; + + const set_attribute = this.set_attribute = (item, custom_attributes) => { + if(!is_html_object(item) || typeof custom_attributes != "object") + return; + + for(const name in custom_attributes) + item.setAttribute((attributes.natives.includes(name) ? "" : "data-") + name.replace(/[^a-z\d-]+/g, "-"), custom_attributes[name]); + + }; + + const construct = () => { + + const custom_attributes = { + natives : settings("attributes_natives") + }; + + for(const key in custom_attributes){ + !attributes[key] && (attributes[key] = []); + (custom_attributes ? custom_attributes.push ? custom_attributes : [custom_attributes] : []).forEach(new_attribute => attributes[key].push(new_attribute)); + }; + + object_name = self.object_name = settings("object_name"); + + settings("autostart") && self.start(); + + }; + + const range_analyze = range => !range || ( + mouse.x >= range.x && mouse.x <= range.x + range.width && + mouse.y >= range.y && mouse.y <= range.y + range.height + ); + + const on_resize_method = screen => { + + if(_screen.x == item_self.offsetWidth && _screen.y == item_self.offsetHeight) + return; + + const width = canvas.width = (_screen.x = item_self.offsetWidth) * q * qx, + height = canvas.height = (_screen.y = item_self.offsetHeight) * q * qy; + + if(width < height){ + s = width / c; + dx = 0; + dy = -(c - (c * height / width)) / 2; + mx = position.x; + my = position.y + dy; + }else{ + s = height / c; + dx = -(c - (c * width / height)) / 2; + dy = 0; + mx = position.x + dx; + my = position.y; + }; + + //resize_methods.forEach((method) => {if(method)method();}); + execute_event("resize"); + + }; + + const position_set = () => { + + const origin = settings("origin"); + + position.x = c * (.5 * ((origin - 1) % 3)); + position.y = c * (1 - (.5 * ((origin - 1) / 3 >> 0))); + + }; + + this.start = () => { + + if(started) + return; + started = true; + + q = settings(["quality", "q"]); + qx = settings(["quality_x", "qx"]); + qy = settings(["quality_y", "qy"]); + timeout = 1000 / settings("frames_per_second"); + c = settings("cells"); + position_set(); + threads_start(); + + preload(settings("position"), (position, asynchronous, error) => { + + if(!position){ + console.error("ERROR. Position HTML for install GUI CANVAS is bad. [" + error + "]"); + return; + }; + + const _class = (hash_self = self.hash_self = hash()) + " " + settings("class"); + + !new RegExp("\\b" + default_settings.class + "\\b").test(_class) && (_class += " " + default_settings.class); + + set_attribute(item_self = self.item_self = position.appendChild(document.createElement("div")), { + id : hash_self, + hash : hash_self, + class : _class, + application : default_settings.application, + onmousemove : object_name + ".check_mouse(this, event);", + tabindex : 0, + onkeydown : object_name + ".key_down(this, event);", + onkeyup : object_name + ".key_up(this, event);" + }); + set_attribute(cache_container = item_self.appendChild(document.createElement("div")), { + class : "cache" + }); + set_attribute(canvas = item_self.appendChild(document.createElement("canvas")), { + class : "canvas" + }); + context = canvas.getContext("2d"); + + thread = threads_add(thread_method); + on_resize_thread = threads_add(on_resize_method); + item_self.onclick = () => execute_event("click"); + + }); + + }; + + // o = Origin {mx, my} + const draw = this.draw = (map, context, o) => map && map.forEach((level, i) => level && (level.push && draw(level, context, o || {mx : mx, my : my}) || (level.type && components[level.type] && components[level.type](level, context, self, o || {mx : mx, my : my})))); + + const refresh_draw = () => { + + if(!context) + return; + + context.clearRect(0, 0, canvas.width, canvas.height); + draw(self.map, context); + + }; + + const thread_method = () => { + + const date = Date.now(); + + if(date - last_time < timeout) + return; + last_time = date; + + refresh_draw(); + + }; + + // Establecer posición sobre el foco de origen. + // Establecer posición sobre los laterales del recuadro o área de trabajo. + const value = this.value = (value, quality) => q * value * (quality || 1); + // const _x = this._x = value => q * qx * value * s; + // const _y = this._y = value => q * qy * value * s; + const _x = this._x = value => value * s; + const _y = this._y = value => value * s; + + this.cache_set = item => { + + let i = 0; + + for(; i < cache_l; i ++) + if(cache[i] === null) + break; + + cache[i] = item; + cache_l = cache.length; + + return i; + }; + + const get_new_cache_i = item => item.cache_i = self.cache_set(true); + + this.cache_clean = i => !isNaN(i) && i >= 0 && i < cache.length && cache[i] !== null && (cache[i] = null); + + const preload_cache_items = (items, callback_per_item, callback, i) => { + + if(i >= items.length){ + typeof callback == "function" && callback(); + return; + }; + + const end = () => { + typeof callback_per_item == "function" && callback_per_item(i, items[i]); + preload_cache_items(items, callback_per_item, callback, i + 1); + }; + + if(!items[i]){ + end(); + return; + }; + + switch(items[i].type){ + case "image": + + const source = items[i].source || items[i].value; + + if(!source){ + end(); + return; + }; + + const image = new Image(); + + image.src = source; + image.crossOrigin = "anonymous"; + image.onload = () => { + items[i].cache_i = self.cache_set(image); + // console.log([items[i], items[i].source || items[i].value, cache[items[i].cache_i]]); + end(); + }; + image.onerror = end; + + break; + default: + items[i].cache_i = self.cache_set(image); + end(); + break; + }; + + }; + + this.preload_cache_items = (items, callback_per_item, callback) => { + + if(!items){ + typeof callback == "function" && callback(); + return; + }; + !items.pus && (items = [items]); + + preload_cache_items(items, callback_per_item, callback, 0); + + }; + + const angle = this.angle = (x, y, randians) => { + + if(typeof x == "object"){ + + const line = x.push ? { + x : x[0] - y[0], + y : x[1] - y[1] + } : { + x : x.x - y.x, + y : x.y - y.y + }; + + x = line.x; + y = line.y; + + }; + + let angle = Math.asin(y / ((x ** 2) + (y ** 2)) ** .5); + + // if(x >= 0) + // angle += Math.PI / 2; + // else + // angle = (1.5 * Math.PI) - angle; + + return (x >= 0 ? angle + (Math.PI / 2) : ((1.5 * Math.PI) - angle)) * (randians ? 1 : 180 / Math.PI); + }; + + const shadow = (data, context) => { + + const z = dx < dy ? _x : _y; + + if(!data.ok){ + isNaN(data.x) && (data.x = settings(["shadow_x", "x"])); + isNaN(data.y) && (data.y = settings(["shadow_y", "y"])); + !data.color && (data.color = settings(["shadow_color", "color"])); + isNaN(data.blur) && (data.blur = settings(["shadow_blur", "blur"])); + data.ok = true; + }; + + context.shadowOffsetX = z(data.x); + context.shadowOffsetY = z(data.y); + context.shadowColor = data.color; + context.shadowBlur = z(data.blur); + + }; + + const border = (data, context) => { + + if(!data.ok){ + !data.color && (data.color = settings(["border_color", "color"])); + isNaN(data.width) && (data.width = settings(["border_width", "width"])); + data.ok = true; + }; + + context.strokeStyle = data.color; + context.lineWidth = (dx < dy ? _x : _y)(data.width); + + }; + + const components = { + rotate : (data, context, kanvas, o) => { + if(data.ignore) + return; + + if(!data.ok){ + isNaN(data.x) && (data.x = settings(["rotate_x", "x"])); + isNaN(data.y) && (data.y = settings(["rotate_y", "y"])); + isNaN(data.degrees) && (data.degrees = settings(["rotate_degrees", "degrees"])); + data.ok = true; + }; + + // console.log(JSON.stringify(data)); + // console.log(JSON.stringify([_x(data.x + mx), _y(data.y + my)])); + + context.save(); + context.translate(_x(data.x + o.mx), _y(data.y + o.my)); + context.rotate(data.degrees * Math.PI / 180); + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + }, + image : (data, context, kanvas, o) => { + if(data.ignore) + return; + + const draw_image = () => { + + if(!data.ok){ + isNaN(data.swidth) && (data.swidth = cache[data.cache_i].width); + isNaN(data.sheight) && (data.sheight = cache[data.cache_i].height); + isNaN(data.width) && (data.width = data.swidth); + isNaN(data.height) && (data.height = data.sheight); + isNaN(data.x) && (data.x = settings(["image_x", "x"])); + isNaN(data.y) && (data.y = settings(["image_y", "y"])); + isNaN(data.alpha) && (data.alpha = settings(["image_alpha", "alpha"])); + isNaN(data.sx) && (data.sx = 0); + isNaN(data.sy) && (data.sy = 0); + isNaN(data.mx) && (data.mx = 0); + isNaN(data.my) && (data.my = 0); + data.ok = true; + }; + + const half_width = data.width / 2, + half_height = data.height / 2; + + context.save(); + context.globalAlpha = data.alpha; + context.translate(_x(o.mx + data.x + data.mx + half_width), _y(o.my + data.y + data.my + half_height)); + context.rotate(data.rotate * Math.PI / 180); + context.drawImage( + cache[data.cache_i], + data.sx, data.sy, data.swidth, data.sheight, + _x(-half_width), _y(-half_height), _x(data.width), _y(data.height) + ); + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + }; + + if(isNaN(data.cache_i)){ + + const i = get_new_cache_i(data); + + cache[i] = new Image(); + cache[i].src = data.source || data.image; + cache[i].crossOrigin = "anonymous"; + cache[i].onload = draw_image; + + }else + draw_image(); + + }, + cache : (data, context, kanvas, o) => { + if(data.ignore) + return; + + context.save(); + + if(isNaN(data.cache_i)){ + + const cache_canvas = cache_container.appendChild(document.createElement("canvas")), + cache_context = cache_canvas.getContext("2d"), + width = data.width || canvas.width, + height = data.height || canvas.height; + image = new Image(); + + cache_canvas.width = width; + cache_canvas.height = height; + + get_new_cache_i(data); + cache_context.save(); + // cache_context.translate(_x(-o.mx), _y(-o.my)); + draw(data.childs, cache_context, {mx : 0, my : 0}); + image.src = cache_canvas.toDataURL("image/png"); + cache[data.cache_i] = image; + cache_context.restore(); + + cache_canvas.remove(); + + }; + + context.drawImage(cache[data.cache_i], 0, 0); + context.restore(); + + }, + rectangle : (data, context, kanvas, o) => { + if(data.ignore)return; + + const proportion = canvas.width > canvas.height ? canvas.width / canvas.height : canvas.height / canvas.width; + + if(!data.ok){ + isNaN(data.alpha) && (data.alpha = settings(["rectangle_alpha", "alpha"])); + !data.color && (data.color = settings(["rectangle_color", "color"])); + isNaN(data.x) && (data.x = settings(["rectangle_x", "x"])); + isNaN(data.y) && (data.y = settings(["rectangle_y", "y"])); + isNaN(data.width) && (data.width = proportion * c); + isNaN(data.height) && (data.height = proportion * c); + isNaN(data.mx) && (data.mx = 0); + isNaN(data.my) && (data.my = 0); + data.ok = true; + }; + + context.save(); + data.shadow && (shadow(data.shadow, context)); + context.globalAlpha = data.alpha; + context.fillStyle = data.color; + context.translate(_x(o.mx + data.x + data.mx), _y(o.my + data.y + data.my)); + context.rotate(data.rotate * Math.PI / 180); + context.translate(_x(-data.mx), _y(-data.my)); + context.fillRect(_x(data.x), _y(data.y), _x(data.width), _y(data.height)); + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + }, + text : (data, context, kanvas, o) => { + if(data.ignore) + return; + + if(!data.ok){ + typeof data.italic != "boolean" && (data.italic = settings(["text_italic", "italic"])); + isNaN(data.bold) && typeof data.bold != "boolean" && (data.bold = settings(["text_bold", "bold"])); + isNaN(data.size) && (data.size = settings(["text_size", "size"])); + data.font && (data.font_family = data.font); + !data.font_family && (data.font_family = settings(["text_font_family", "text_font", "font"])); + !data.align && (data.align = settings(["text_align", "align"])); + isNaN(data.x) && (data.x = settings(["text_x", "x"])); + isNaN(data.y) && (data.y = settings(["text_y", "y"])); + !data.text && (data.text = ""); + isNaN(data.alpha) && (data.alpha = settings(["text_alpha", "alpha"])); + !data.baseline && (data.baseline = settings(["text_baseline", "baseline"])); + data.ok = true; + }; + + context.save(); + data.shadow && (shadow(data.shadow, context)); + context.globalAlpha = data.alpha; + context.textAlign = data.align; + context.textBaseline = data.baseline; + context.font = ( + (data.italic ? "italic " : "") + + (data.bold ? isNaN(data.bold) ? "bold " : data.bold + " " : "") + + (dx < dy ? _x : _y)(data.size) + "px " + + data.font_family + ); + if(data.color){ + context.fillStyle = data.color; + context.fillText(data.text, _x(data.x + mx), _y(data.y + my)); + }; + if(data.border){ + border(data.border, context); + context.strokeText(data.text, _x(data.x + mx), _y(data.y + my)); + }; + context.restore(); + + }, + block : (data, context, kanvas, o) => { + if(data.ignore) + return; + + if(!data.ok){ + isNaN(data.alpha) && (data.alpha = settings(["block_alpha", "alpha"])); + data.ok = true; + }; + + context.save(); + context.globalAlpha = data.alpha; + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + } + }; + + this.add_components = (json, overwrite) => { + if(!json) + return; + + !json.push && (json = [json]); + typeof overwrite != "bool" && (overwrite = settings("overwrite")); + + json.forEach((items) => { + if(!items) + return; + if(items.push) + self.add_components(items, overwrite); + else if(typeof items == "object") + for(let key in items) + (overwrite || !components[key]) && (components[key] = items[key]); + }); + + }; + + this.check_mouse = (item, event) => { + + item_self.setAttribute("data-mouse-x", mouse.x = (event.clientX * q * qx / s) - mx); + item_self.setAttribute("data-mouse-y", mouse.y = (event.clientY * q * qy / s) - my); + + execute_event("mouse_move"); + + }; + + const on_event = this.on_event = (name, method, range) => { + + if(typeof method != "function") + return null; + + !events[name] && (events[name] = { + methods : [], + l : 0, + ranges : [] + }); + + let i = 0; + + for(; i < events[name].l; i ++) + if(!events[name].methods[i]) + break; + + events[name].methods[i] = method; + events[name].ranges[i] = range; + events[name].l = events[name].methods.length; + + return i; + }; + + const remove_event = this.remove_event = (name, i) => events[name] && !isNaN(i) && i >= 0 && i < events[name].l && events[name].methods[i] && (events[name].methods[i] = null); + + const execute_event = this.execute_event = (name, input) => { + + if(events[name] && events[name].l) + for(let i = 0; i < events[name].l; i ++) + events[name].methods[i] && events[name].methods[i](range_analyze(events[name].ranges[i]), input); + + }; + + const event_range = this.event_range = (name, i) => events[name] && !isNaN(i) && i >= 0 && i < events[name].l ? events[name].ranges[i] : null; + + this.on_mouse_move = (method, range) => on_event("mouse_move", method, range); + this.on_resize = (method, range) => on_event("resize", method, range); + this.on_click = (method, range) => on_event("click", method, range); + this.on_key_down = (method, range) => on_event("key_down", method, range); + this.on_key_up = (method, range) => on_event("key_up", method, range); + + this.remove_mouse_move = i => {remove_event("mouse_move", i);}; + this.remove_resize = i => {remove_event("resize", i);}; + this.remove_click = i => {remove_event("click", i);}; + this.remove_key_down = i => {remove_event("key_down", i);}; + this.remove_key_up = i => {remove_event("key_up", i);}; + + this.range_mouse_move = i => event_range("mouse_move", i); + this.range_resize = i => event_range("resize", i); + this.range_click = i => event_range("click", i); + this.range_key_down = i => event_range("key_down", i); + this.range_key_up = i => event_range("key_up", i); + + this.key_down = (item, event) => execute_event("key_down", {code : event.keyCode}); + this.key_up = (item, event) => execute_event("key_up", {code : event.keyCode}); + + this.get_margins = () => {return {x : mx, y : my};}; + this.get_position = () => {return {x : position.x, y : position.y};}; + this.get_cells = () => c; + this.get_canvas_distance = () => {return {x : dx, y : dy};}; + this.get_cell_size = () => s; + + construct(); + +}; diff --git a/Public/git_update.php b/Public/git_update.php new file mode 100755 index 0000000..0879a28 --- /dev/null +++ b/Public/git_update.php @@ -0,0 +1,4 @@ +&1"); diff --git a/Public/images/kanvas-180.png b/Public/images/kanvas-180.png new file mode 100755 index 0000000000000000000000000000000000000000..986d9ce1b2608831744ca5350bebaffc95d7f233 GIT binary patch literal 27799 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 `F!ZTGz!LSqBdKw|MytJUN; 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 z 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 literal 0 HcmV?d00001 diff --git a/Public/images/kanvas-270.png b/Public/images/kanvas-270.png new file mode 100755 index 0000000000000000000000000000000000000000..e90900375e5643a34e9b25dcf540a49a89992a54 GIT binary patch literal 28787 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 Yhc8Kb21i>6yc7bFlTwzf6*ms~AF0T$Bme*a literal 0 HcmV?d00001 diff --git a/Public/images/kanvas-32.png b/Public/images/kanvas-32.png new file mode 100755 index 0000000000000000000000000000000000000000..ab4a3270fdcd86c01cae6ca3eff4364c637608bf GIT binary patch literal 7913 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 literal 0 HcmV?d00001 diff --git a/Public/images/kanvas-512.png b/Public/images/kanvas-512.png new file mode 100755 index 0000000000000000000000000000000000000000..749136d692992a2edb234279e71b868efc513f37 GIT binary patch literal 6447 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 V9qBsdDi^k(d2<%dE}bRM{U1eBJn{el literal 0 HcmV?d00001 diff --git a/Public/images/kanvas.png b/Public/images/kanvas.png new file mode 100755 index 0000000000000000000000000000000000000000..749136d692992a2edb234279e71b868efc513f37 GIT binary patch literal 6447 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 V9qBsdDi^k(d2<%dE}bRM{U1eBJn{el literal 0 HcmV?d00001 diff --git a/Public/test/index.html b/Public/test/index.html new file mode 100755 index 0000000..5955ddd --- /dev/null +++ b/Public/test/index.html @@ -0,0 +1,85 @@ + + + + Kanvas - Test + + + + + + + + + + + + diff --git a/Public/wmd.php b/Public/wmd.php new file mode 100755 index 0000000..1ad86a0 --- /dev/null +++ b/Public/wmd.php @@ -0,0 +1,6 @@ + "update_scripts", + "author" => "KyMAN", + "project" => "Kanvas", + "class" => "Kanvas", + "object" => "kanvas", + "url" => "https://kanvas.k3y.pw", + "project_author" => "KyMAN", + "key_words" => "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library", + "logo" => "/images/kanvas.png", + "language" => "es", + "wmd_file" => "/../WMarkDown/HTML/script.w.md", + "wmd_file_empty" => "/../WMarkDown/HTML/file.w.md", + "ignore_script_paths" => [], + "only" => "/Public" + ], Kanvas\Secrets::wmarkdown)); diff --git a/WMD/JSON/html.files.json b/WMD/JSON/html.files.json new file mode 100755 index 0000000..6dbcddc --- /dev/null +++ b/WMD/JSON/html.files.json @@ -0,0 +1 @@ +{"files":["\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.quality.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.settings.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.starting.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.targets.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/index.html","\/mnt\/d\/git\/Kanvas\/Public\/index.html"],"directories":["\/JSON","\/es","\/es\/doc"]} \ No newline at end of file diff --git a/WMD/dev/ECMAScript/index.w.md b/WMD/dev/ECMAScript/index.w.md new file mode 100755 index 0000000..8fa6e89 --- /dev/null +++ b/WMD/dev/ECMAScript/index.w.md @@ -0,0 +1,24 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225 +}]] +# ECMAScript + +[[header_level 0]] +[[include /WMD/dev/Public/Kanvas.ecma.js.w.md]] + + + +[[html_data { + "title" : "ECMAScript - Kanvas", + "url" : "https://kanvas.k3y.pw/dev/ECMAScript/index.html", + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225, + "key_words" : "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library,developt,desarrollo,programación,ecmascript", + "description" : "Parte ECMAScript del Kanvas.", + "project" : "Kanvas", + "logo" : "/images/kanvas.png", + "language" : "es" +}]] diff --git a/WMD/dev/PHP/index.w.md b/WMD/dev/PHP/index.w.md new file mode 100755 index 0000000..e720aa1 --- /dev/null +++ b/WMD/dev/PHP/index.w.md @@ -0,0 +1,27 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225 +}]] +# PHP + +[[header_level 0]] +[[include /WMD/dev/Public/wmd.php.w.md]] + +[[header_level 0]] +[[include /WMD/dev/Public/wmd_scripts.php.w.md]] + + + +[[html_data { + "title" : "PHP - Kanvas", + "url" : "https://kanvas.k3y.pw/dev/PHP/index.html", + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225, + "key_words" : "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library,developt,desarrollo,programación,php", + "description" : "Parte PHP del Kanvas.", + "project" : "Kanvas", + "logo" : "/images/kanvas.png", + "language" : "es" +}]] diff --git a/WMD/dev/Public/Kanvas.ecma.js.w.md b/WMD/dev/Public/Kanvas.ecma.js.w.md new file mode 100755 index 0000000..bc4dcf5 --- /dev/null +++ b/WMD/dev/Public/Kanvas.ecma.js.w.md @@ -0,0 +1,958 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225 +}]] +# Kanvas.ecma.js + +```txt +/Public/Kanvas.ecma.js +``` + +## [[plain Kanvas.null_or_undefined]] + +[[wdoc +Método object. +@name Kanvas.null_or_undefined +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 719d9b7663b42ce8e70a4b651eb27d92 +#value - optional Parámetro value +#return - - Retorno. +]] + +## [[plain Kanvas.allow_nulls]] + +[[wdoc +Método object. +@name Kanvas.allow_nulls +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash a1c98a84d6d8b0b8f14fedd400bb007d +#nulls - optional Parámetro nulls +#return - - Retorno. +]] + +## [[plain Kanvas.default_value]] + +[[wdoc +Método object. +@name Kanvas.default_value +@see Kanvas.allow_nulls +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 6699f3c074ebd26160e6b3a8794c6493 +#_default - optional Parámetro _default +#nulls - optional Parámetro nulls +#return - - Retorno. +]] + +## [[plain Kanvas.settings]] + +[[wdoc +Método object. +@name Kanvas.settings +@see Kanvas.default_value +@see Kanvas.allow_nulls +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash c05780df830b296ef8a270d7fcadeb98 +#names - optional Parámetro names +#inputs - optional Parámetro inputs +#_default - optional Parámetro _default +#nulls - optional Parámetro nulls +#return - - Retorno. +]] + +## [[plain Kanvas.threads_function]] + +[[wdoc +Método object. +@name Kanvas.threads_function +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash 30f4ba8b76dce56fc41434dd6465f058 +#return - - Retorno. +]] + +## [[plain Kanvas.threads_start]] + +[[wdoc +Método object. +@name Kanvas.threads_start +@see Kanvas.settings +@see Kanvas.threads_function +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash cce23b880e33d3e85679d59e082812d8 +#frames_per_second - optional Parámetro frames_per_second +]] + +## [[plain Kanvas.threads_stop]] + +[[wdoc +Método object. +@name Kanvas.threads_stop +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 628fab132ecb593ed3accbec9427a6ea +]] + +## [[plain Kanvas.threads_add]] + +[[wdoc +Método object. +@name Kanvas.threads_add +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 98547e004e14d60c8577718368ffe69e +#callback - optional Parámetro callback +#return - - Retorno. +]] + +## [[plain Kanvas.threads_remove]] + +[[wdoc +Método object. +@name Kanvas.threads_remove +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash a73d5bb9c37dd290aef7f312f8fa2c81 +#i - optional Parámetro i +]] + +## [[plain Kanvas.is_html_object]] + +[[wdoc +Método object. +@name Kanvas.is_html_object +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash f8cca6ce9a87f4ddf2c68884218d1c12 +#variable - optional Parámetro variable +#return - - Retorno. +]] + +## [[plain Kanvas.preload]] + +[[wdoc +Método object. +@name Kanvas.preload +@see Kanvas.is_html_object +@see Kanvas.settings +@see Kanvas.threads_add +@see Kanvas.threads_remove +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash b6298d139217967603995bbc155fa81b +#selector - optional Parámetro selector +#callback - optional Parámetro callback +]] + +## [[plain Kanvas.hash]] + +[[wdoc +Método object. +@name Kanvas.hash +@see Kanvas.settings +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash cbd619e186a3b4cc88e42b48092e138a +#return - - Retorno. +]] + +## [[plain Kanvas.set_attribute]] + +[[wdoc +Método object. +@name Kanvas.set_attribute +@see Kanvas.is_html_object +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 66c62f05275a277af2cae6fa0ce15bec +#item - optional Parámetro item +#custom_attributes - optional Parámetro custom_attributes +]] + +## [[plain Kanvas.construct]] + +[[wdoc +Método object. +@name Kanvas.construct +@see Kanvas.settings +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash 37628051533825ee303450db783c043e +]] + +## [[plain Kanvas.range_analyze]] + +[[wdoc +Método object. +@name Kanvas.range_analyze +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash b70d0d7c55cff052650f923dfff238cf +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.on_resize_method]] + +[[wdoc +Método object. +@name Kanvas.on_resize_method +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash a76d2493ecfc4e769f416dbf0b6512b3 +#screen - optional Parámetro screen +]] + +## [[plain Kanvas.position_set]] + +[[wdoc +Método object. +@name Kanvas.position_set +@see Kanvas.settings +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash a5797156cb2c84f1be97d89806ec8ea8 +]] + +## [[plain Kanvas.start]] + +[[wdoc +Método object. +@name Kanvas.start +@see Kanvas.settings +@see Kanvas.position_set +@see Kanvas.threads_start +@see Kanvas.preload +@see Kanvas.hash +@see Kanvas.set_attribute +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash c5c42914486aa98c690dfee43cf0022b +]] + +## [[plain Kanvas.draw]] + +[[wdoc +Método object. +@name Kanvas.draw +@see Kanvas.draw +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 3e0658a54766de9a8b226dff8e290b09 +#map - optional Parámetro map +#context - optional Parámetro context +]] + +## [[plain Kanvas.refresh_draw]] + +[[wdoc +Método object. +@name Kanvas.refresh_draw +@see Kanvas.draw +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash 13eb2f6574df5ab6d8a4b042ad90f347 +]] + +## [[plain Kanvas.thread_method]] + +[[wdoc +Método object. +@name Kanvas.thread_method +@see Kanvas.refresh_draw +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash af433469fec83091580ca5ada20b6bb9 +]] + +## [[plain Kanvas.value]] + +[[wdoc +Método object. +@name Kanvas.value +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash f5494430f37abdc8690b52732565c629 +#value - optional Parámetro value +#quality - optional Parámetro quality +#return - - Retorno. +]] + +## [[plain Kanvas._x]] + +[[wdoc +Método object. +@name Kanvas._x +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 559ab3da3b95bf8d10a31f3d719b2ea1 +#value - optional Parámetro value +#return - - Retorno. +]] + +## [[plain Kanvas._y]] + +[[wdoc +Método object. +@name Kanvas._y +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 559ab3da3b95bf8d10a31f3d719b2ea1 +#value - optional Parámetro value +#return - - Retorno. +]] + +## [[plain Kanvas.cache_set]] + +[[wdoc +Método object. +@name Kanvas.cache_set +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 603f76ca5fda76d86b5be256077b25e9 +#item - optional Parámetro item +#return - - Retorno. +]] + +## [[plain Kanvas.get_new_cache_i]] + +[[wdoc +Método object. +@name Kanvas.get_new_cache_i +@see Kanvas.cache_set +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash b0d2a1389083540a4357d495c5f0d08c +#item - optional Parámetro item +#return - - Retorno. +]] + +## [[plain Kanvas.cache_clean]] + +[[wdoc +Método object. +@name Kanvas.cache_clean +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash a2b63581e6003dd7d145d86349ed146c +#i - optional Parámetro i +]] + +## [[plain Kanvas.preload_cache_items]] + +[[wdoc +Método object. +@name Kanvas.preload_cache_items +@see Kanvas.preload_cache_items +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 9828faf1c71dd7d96543e60c7b9b9aea +#items - optional Parámetro items +#callback_per_item - optional Parámetro callback_per_item +#callback - optional Parámetro callback +]] + +## [[plain Kanvas.angle]] + +[[wdoc +Método object. +@name Kanvas.angle +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash f80170728f63e977a7b75020e9a2efb1 +#x - optional Parámetro x +#y - optional Parámetro y +#randians - optional Parámetro randians +#return - - Retorno. +]] + +## [[plain Kanvas.shadow]] + +[[wdoc +Método object. +@name Kanvas.shadow +@see Kanvas.settings +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash 3e5838dd96848e07e9ec73496e08c62f +#data - optional Parámetro data +#context - optional Parámetro context +]] + +## [[plain Kanvas.border]] + +[[wdoc +Método object. +@name Kanvas.border +@see Kanvas.settings +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash fab5ac8f9418215b319a17e166843729 +#data - optional Parámetro data +#context - optional Parámetro context +]] + +## [[plain Kanvas.draw_image]] + +[[wdoc +Método object. +@name Kanvas.draw_image +@see Kanvas.settings +@see Kanvas._x +@see Kanvas._y +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash 109a8296cc4383971af7cc4bd13b46b5 +]] + +## [[plain Kanvas.add_components]] + +[[wdoc +Método object. +@name Kanvas.add_components +@see Kanvas.settings +@see Kanvas.add_components +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash f55803884eb16241230454adbefa6c6b +#json - optional Parámetro json +#overwrite - optional Parámetro overwrite +]] + +## [[plain Kanvas.check_mouse]] + +[[wdoc +Método object. +@name Kanvas.check_mouse +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 876b893e02510899ca548c73f0adfe56 +#item - optional Parámetro item +#event - optional Parámetro event +]] + +## [[plain Kanvas.on_event]] + +[[wdoc +Método object. +@name Kanvas.on_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 686ebb7d44d117801dc85b8a30b0bf57 +#name - optional Parámetro name +#method - optional Parámetro method +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.remove_event]] + +[[wdoc +Método object. +@name Kanvas.remove_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash ca7e3e68240c00374b401e488407f8d6 +#name - optional Parámetro name +#i - optional Parámetro i +]] + +## [[plain Kanvas.execute_event]] + +[[wdoc +Método object. +@name Kanvas.execute_event +@see Kanvas.range_analyze +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 33c8ba6d8e6f32c4c4da1dd60db07513 +#name - optional Parámetro name +#input - optional Parámetro input +]] + +## [[plain Kanvas.event_range]] + +[[wdoc +Método object. +@name Kanvas.event_range +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash e4b8585c6a74d2b41538b1774d2fee40 +#name - optional Parámetro name +#i - optional Parámetro i +#return - - Retorno. +]] + +## [[plain Kanvas.on_mouse_move]] + +[[wdoc +Método object. +@name Kanvas.on_mouse_move +@see Kanvas.on_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash e40de2381f36b3c9d8312d6ef8a762f2 +#method - optional Parámetro method +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.on_resize]] + +[[wdoc +Método object. +@name Kanvas.on_resize +@see Kanvas.on_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash b006e249f4d5adf74d0f7ec45978c1f2 +#method - optional Parámetro method +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.on_click]] + +[[wdoc +Método object. +@name Kanvas.on_click +@see Kanvas.on_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 85d6ad332ff2ceb5cbca13e4546ed361 +#method - optional Parámetro method +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.on_key_down]] + +[[wdoc +Método object. +@name Kanvas.on_key_down +@see Kanvas.on_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 79025f1cdcb67186db97d1132bb43e62 +#method - optional Parámetro method +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.on_key_up]] + +[[wdoc +Método object. +@name Kanvas.on_key_up +@see Kanvas.on_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 73067b92317dc0f59adbd3eab025ca50 +#method - optional Parámetro method +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.remove_mouse_move]] + +[[wdoc +Método object. +@name Kanvas.remove_mouse_move +@see Kanvas.remove_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 2adc625bafbab06d1d6385aab844693c +#i - optional Parámetro i +]] + +## [[plain Kanvas.remove_resize]] + +[[wdoc +Método object. +@name Kanvas.remove_resize +@see Kanvas.remove_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash f0192c53117c1b3e57ec834096136ad2 +#i - optional Parámetro i +]] + +## [[plain Kanvas.remove_click]] + +[[wdoc +Método object. +@name Kanvas.remove_click +@see Kanvas.remove_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 696c4277e38f06fae1fd0781622bad53 +#i - optional Parámetro i +]] + +## [[plain Kanvas.remove_key_down]] + +[[wdoc +Método object. +@name Kanvas.remove_key_down +@see Kanvas.remove_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 63b0a8449fb2a64a6c272aaca90c429b +#i - optional Parámetro i +]] + +## [[plain Kanvas.remove_key_up]] + +[[wdoc +Método object. +@name Kanvas.remove_key_up +@see Kanvas.remove_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 8b8f69cc65cec69309d7bbee875c877b +#i - optional Parámetro i +]] + +## [[plain Kanvas.range_mouse_move]] + +[[wdoc +Método object. +@name Kanvas.range_mouse_move +@see Kanvas.event_range +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 7496d8ac7ff8f0b4f0a406317732b4a4 +#i - optional Parámetro i +#return - - Retorno. +]] + +## [[plain Kanvas.range_resize]] + +[[wdoc +Método object. +@name Kanvas.range_resize +@see Kanvas.event_range +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 5f48d71ce7258c7d8f9c35a6ff24ce9c +#i - optional Parámetro i +#return - - Retorno. +]] + +## [[plain Kanvas.range_click]] + +[[wdoc +Método object. +@name Kanvas.range_click +@see Kanvas.event_range +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 4dcfaba4ec9eb40c29226dd21f2b3fbc +#i - optional Parámetro i +#return - - Retorno. +]] + +## [[plain Kanvas.range_key_down]] + +[[wdoc +Método object. +@name Kanvas.range_key_down +@see Kanvas.event_range +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 8da99fdb35bb1906c7f00a41ad9ad26d +#i - optional Parámetro i +#return - - Retorno. +]] + +## [[plain Kanvas.range_key_up]] + +[[wdoc +Método object. +@name Kanvas.range_key_up +@see Kanvas.event_range +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash c628c7bef3b981fb42437f6de0e44ab8 +#i - optional Parámetro i +#return - - Retorno. +]] + +## [[plain Kanvas.key_down]] + +[[wdoc +Método object. +@name Kanvas.key_down +@see Kanvas.execute_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 15ee3af73279aa7b18e41c157a0acdea +#item - optional Parámetro item +#event - optional Parámetro event +]] + +## [[plain Kanvas.key_up]] + +[[wdoc +Método object. +@name Kanvas.key_up +@see Kanvas.execute_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 426a68043d1c42008c39defe498dfe0e +#item - optional Parámetro item +#event - optional Parámetro event +]] + +## [[plain Kanvas.get_margins]] + +[[wdoc +Método object. +@name Kanvas.get_margins +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash e5aa5d927b4260ab1e6a8a4616b7cc8e +#return - - Retorno. +]] + +## [[plain Kanvas.get_position]] + +[[wdoc +Método object. +@name Kanvas.get_position +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 041721aebc4ba3428c96418025f07272 +#return - - Retorno. +]] + +## [[plain Kanvas.get_cells]] + +[[wdoc +Método object. +@name Kanvas.get_cells +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash d6b5083d8473799c6af510fdc459245d +#return - - Retorno. +]] + +## [[plain Kanvas.get_canvas_distance]] + +[[wdoc +Método object. +@name Kanvas.get_canvas_distance +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 22d705933b1771eed6a395154a1cff24 +#return - - Retorno. +]] + +## [[plain Kanvas.get_cell_size]] + +[[wdoc +Método object. +@name Kanvas.get_cell_size +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash b63b90521c2f76ea0c361fea33c23769 +#return - - Retorno. +]] + +[[html_data { + "title" : "Kanvas.ecma.js - Kanvas", + "url" : "https://kanvas.k3y.pw/Public/Kanvas.ecma.js.html", + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225, + "key_words" : "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library,developt,desarrollo,programación,cma", + "description" : "Kanvas.ecma.js del Kanvas.", + "project" : "Kanvas", + "logo" : "/images/kanvas.png", + "language" : "es" +}]] diff --git a/WMD/dev/Public/wmd.php.w.md b/WMD/dev/Public/wmd.php.w.md new file mode 100755 index 0000000..705c3e3 --- /dev/null +++ b/WMD/dev/Public/wmd.php.w.md @@ -0,0 +1,23 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225 +}]] +# wmd.php + +```txt +/Public/wmd.php +``` + +[[html_data { + "title" : "wmd.php - Kanvas", + "url" : "https://kanvas.k3y.pw/Public/wmd.php.html", + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225, + "key_words" : "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library,developt,desarrollo,programación,main", + "description" : "wmd.php del Kanvas.", + "project" : "Kanvas", + "logo" : "/images/kanvas.png", + "language" : "es" +}]] diff --git a/WMD/dev/Public/wmd_scripts.php.w.md b/WMD/dev/Public/wmd_scripts.php.w.md new file mode 100755 index 0000000..fa8a374 --- /dev/null +++ b/WMD/dev/Public/wmd_scripts.php.w.md @@ -0,0 +1,23 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225 +}]] +# wmd_scripts.php + +```txt +/Public/wmd_scripts.php +``` + +[[html_data { + "title" : "wmd_scripts.php - Kanvas", + "url" : "https://kanvas.k3y.pw/Public/wmd_scripts.php.html", + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225, + "key_words" : "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library,developt,desarrollo,programación,main", + "description" : "wmd_scripts.php del Kanvas.", + "project" : "Kanvas", + "logo" : "/images/kanvas.png", + "language" : "es" +}]] diff --git a/WMD/dev/index.w.md b/WMD/dev/index.w.md new file mode 100755 index 0000000..1eab0c9 --- /dev/null +++ b/WMD/dev/index.w.md @@ -0,0 +1,89 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225 +}]] + +# ECMAScript + +- [/dev/ECMAScript#Kanvas-ecma-js-2 /Public/Kanvas.ecma.js] + - [/dev/ECMAScript#Kanvas-null-or-undefined-2 Kanvas.null\_or\_undefined] + - [/dev/ECMAScript#Kanvas-allow-nulls-2 Kanvas.allow\_nulls] + - [/dev/ECMAScript#Kanvas-default-value-2 Kanvas.default\_value] + - [/dev/ECMAScript#Kanvas-settings-2 Kanvas.settings] + - [/dev/ECMAScript#Kanvas-threads-function-2 Kanvas.threads\_function] + - [/dev/ECMAScript#Kanvas-threads-start-2 Kanvas.threads\_start] + - [/dev/ECMAScript#Kanvas-threads-stop-2 Kanvas.threads\_stop] + - [/dev/ECMAScript#Kanvas-threads-add-2 Kanvas.threads\_add] + - [/dev/ECMAScript#Kanvas-threads-remove-2 Kanvas.threads\_remove] + - [/dev/ECMAScript#Kanvas-is-html-object-2 Kanvas.is\_html\_object] + - [/dev/ECMAScript#Kanvas-preload-2 Kanvas.preload] + - [/dev/ECMAScript#Kanvas-hash-2 Kanvas.hash] + - [/dev/ECMAScript#Kanvas-set-attribute-2 Kanvas.set\_attribute] + - [/dev/ECMAScript#Kanvas-construct-2 Kanvas.construct] + - [/dev/ECMAScript#Kanvas-range-analyze-2 Kanvas.range\_analyze] + - [/dev/ECMAScript#Kanvas-on-resize-method-2 Kanvas.on\_resize\_method] + - [/dev/ECMAScript#Kanvas-position-set-2 Kanvas.position\_set] + - [/dev/ECMAScript#Kanvas-start-2 Kanvas.start] + - [/dev/ECMAScript#Kanvas-draw-2 Kanvas.draw] + - [/dev/ECMAScript#Kanvas-refresh-draw-2 Kanvas.refresh\_draw] + - [/dev/ECMAScript#Kanvas-thread-method-2 Kanvas.thread\_method] + - [/dev/ECMAScript#Kanvas-value-2 Kanvas.value] + - [/dev/ECMAScript#Kanvas-x-2 Kanvas.\_x] + - [/dev/ECMAScript#Kanvas-y-2 Kanvas.\_y] + - [/dev/ECMAScript#Kanvas-cache-set-2 Kanvas.cache\_set] + - [/dev/ECMAScript#Kanvas-get-new-cache-i-2 Kanvas.get\_new\_cache\_i] + - [/dev/ECMAScript#Kanvas-cache-clean-2 Kanvas.cache\_clean] + - [/dev/ECMAScript#Kanvas-preload-cache-items-2 Kanvas.preload\_cache\_items] + - [/dev/ECMAScript#Kanvas-preload-cache-items-2 Kanvas.preload\_cache\_items] + - [/dev/ECMAScript#Kanvas-angle-2 Kanvas.angle] + - [/dev/ECMAScript#Kanvas-shadow-2 Kanvas.shadow] + - [/dev/ECMAScript#Kanvas-border-2 Kanvas.border] + - [/dev/ECMAScript#Kanvas-draw-image-2 Kanvas.draw\_image] + - [/dev/ECMAScript#Kanvas-add-components-2 Kanvas.add\_components] + - [/dev/ECMAScript#Kanvas-check-mouse-2 Kanvas.check\_mouse] + - [/dev/ECMAScript#Kanvas-on-event-2 Kanvas.on\_event] + - [/dev/ECMAScript#Kanvas-remove-event-2 Kanvas.remove\_event] + - [/dev/ECMAScript#Kanvas-execute-event-2 Kanvas.execute\_event] + - [/dev/ECMAScript#Kanvas-event-range-2 Kanvas.event\_range] + - [/dev/ECMAScript#Kanvas-on-mouse-move-2 Kanvas.on\_mouse\_move] + - [/dev/ECMAScript#Kanvas-on-resize-2 Kanvas.on\_resize] + - [/dev/ECMAScript#Kanvas-on-click-2 Kanvas.on\_click] + - [/dev/ECMAScript#Kanvas-on-key-down-2 Kanvas.on\_key\_down] + - [/dev/ECMAScript#Kanvas-on-key-up-2 Kanvas.on\_key\_up] + - [/dev/ECMAScript#Kanvas-remove-mouse-move-2 Kanvas.remove\_mouse\_move] + - [/dev/ECMAScript#Kanvas-remove-resize-2 Kanvas.remove\_resize] + - [/dev/ECMAScript#Kanvas-remove-click-2 Kanvas.remove\_click] + - [/dev/ECMAScript#Kanvas-remove-key-down-2 Kanvas.remove\_key\_down] + - [/dev/ECMAScript#Kanvas-remove-key-up-2 Kanvas.remove\_key\_up] + - [/dev/ECMAScript#Kanvas-range-mouse-move-2 Kanvas.range\_mouse\_move] + - [/dev/ECMAScript#Kanvas-range-resize-2 Kanvas.range\_resize] + - [/dev/ECMAScript#Kanvas-range-click-2 Kanvas.range\_click] + - [/dev/ECMAScript#Kanvas-range-key-down-2 Kanvas.range\_key\_down] + - [/dev/ECMAScript#Kanvas-range-key-up-2 Kanvas.range\_key\_up] + - [/dev/ECMAScript#Kanvas-key-down-2 Kanvas.key\_down] + - [/dev/ECMAScript#Kanvas-key-up-2 Kanvas.key\_up] + - [/dev/ECMAScript#Kanvas-get-margins-2 Kanvas.get\_margins] + - [/dev/ECMAScript#Kanvas-get-position-2 Kanvas.get\_position] + - [/dev/ECMAScript#Kanvas-get-cells-2 Kanvas.get\_cells] + - [/dev/ECMAScript#Kanvas-get-canvas-distance-2 Kanvas.get\_canvas\_distance] + - [/dev/ECMAScript#Kanvas-get-cell-size-2 Kanvas.get\_cell\_size] + +# PHP + +- [/dev/PHP#wmd-php-2 /Public/wmd.php] +- [/dev/PHP#wmd-scripts-php-2 /Public/wmd_scripts.php] + + +[[html_data { + "title" : "Código - Kanvas", + "url" : "https://kanvas.k3y.pw/dev/index.html", + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225, + "key_words" : "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library,developt,desarrollo,programación,todo,all", + "description" : "Parte Todo del Kanvas.", + "project" : "Kanvas", + "logo" : "/images/kanvas.png", + "language" : "es" +}]] diff --git a/WMD/es/20230707/index.w.md b/WMD/es/20230707/index.w.md new file mode 100755 index 0000000..2372ab5 --- /dev/null +++ b/WMD/es/20230707/index.w.md @@ -0,0 +1,32 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20230707, + "version" : 20230707 +}]] +# Kanvas + +El proyecto Kanvas no es más que un pequeño motor gráfico basado en CANVAS para gestionar gráficos en 2D, basado en el sistema que usa JavaScript y CSS para interpretar los mismos: un mapeado de parámetros que determinan el GUI. En este caso se unifican los diferentes tipos de gráficos que se puedan establecer como básicos, y sobre éstos, éste trabaja. + +La idea es compactar todos los gráficos sobre un simple JSON, y mediante la accesibilidad de los elementos, irlos variando, siendo más libiano modificar parámetros sobre unn entorno de interpretación que ejecutar cambios sobre el mismo. + +A nivel de HTML se trata de un DIV que contiene un DIV para elementos cacheados y un elemento CANVAS el cual será el GUI. + +A la hora de gestionar los gráficos, Kanvas puede hacer uso de bloques que se cachean en otros componentes CANVAS, los cuales se almacenarán en el DIV caché. + +Por otro lado, en caso de quererse añadir cosas al bloque HTML Kanvas, éstos pueden ser agregados sin problema. + +El objeto Kanvas viene siendo un objeto JavaScript basado en función y no en clase. Puede ser extendido mediante la función "extends" sobre otros objetos. El objeto Kanvas consta de 3 fases iniciales las cuales: + +1. **Constructor**: + +[[html_data { + "title" : "Kanvas - Manual", + "url" : "https://kanvas.k3y.pw/es/20230707/", + "author" : "KyMAN", + "since" : 20230707, + "version" : 20230707, + "key_words" : "kanvas,canvas,kyman,2d,graphics", + "description" : "Manual del proyecto Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/es/doc/kanvas.idea.w.md b/WMD/es/doc/kanvas.idea.w.md new file mode 100755 index 0000000..5de3b78 --- /dev/null +++ b/WMD/es/doc/kanvas.idea.w.md @@ -0,0 +1,76 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211230, + "version" : 20211230 +}]] +# Idea + +La idea del proyecto es hacer un motor que se encargue de crear imágenes a partir de un Array de +diccionarios con anidamiento que contiene las formas, gráficos, bloques y grupos que dan en sí la +imagen final. Las imágenes se refrescarán cada X tiempo según configuración o según rendimiento del +equipo o navegador donde se esté ejecutando. Con ello facilitará a nivel de proceso iteraciones y +dinamismos con la imagen final, que será lo que vea el usuario, haciendo que con una simple +variación de uno o más valores dentro del Array de diccionarios se permita visualizar este cambio, +permitiendo con ello, movimientos y cualquier otro tipo de interactuación con el entorno. + +El motor constará de un gestor de formas, objetos, etc. Unos serán por defecto y otros pueden ser +añadidos por el usuario, de esta forma permitimos un sistema simplificado de formas y objetos, así +como conjuntos que se repiten y así poder hacer reciclaje de objetos y elementos sin que el usuario +tenga que hacer un sistema en esprofeso para ello. También constará de los eventos que permitan no +solo interactuar al programador o a los elementos entre sí, sino también a los usuarios que consuman +el producto final. + +Todo ello se moverá en JSON con Arrays que contengan diccionarios u objetos. Los Arrays pueden tener +anidados Arrays para hacer capas o bloques, y los objetos pueden tener hijos, por lo general es el +atributo "childs". El orden de las capas se otorga al orden en que se encuentren en los Arrays, +siendo los índices más bajos los que estén al fondo y los que tengan el índica más alto los que +estén más al frente. + +También ha de mencionarse el posicionamiento, que en el plano principal constará de 9 posiciones de +inicio por el hecho de que estamos hablando de un entorno dinámico que muy posiblemente no tenga un +tamaño preestablecido y que se adapte a la pantalla, variando si ésta varía, no siendo igual empezar +a dibujar desde el centro que desde un lado u otro. Las posiciones se basan en el teclado numérico +de un teclado normal de PC de 105 teclas, con los valores del 1 al 9. Es importante destacar que +esto es para empezar el dibujado, a partir de ahí, todo se iniciará en el punto 0x0 desde el objeto, +es decir, si un objeto se pone en la posición 3x5, el punto 0x0 de un elemento hijo será el punto +3x5 del padre, y si se anida otro objeto en el hijo, siendo el nieto del objeto maestro sería la +suma de la posición del hijo y la del padre, y así sucesivamente. Por lo que hay que tener especial +cuidado en las anidaciones, incluso la rotación y el efecto Alpha se heredan. Todo ello no impide +que se pueda trabajar desde el objeto base y anidar con simples Array, lo que sería realmente +agrupar, como sucede en el juego [https://xgravity.k3y.pw/ XGravity]. + +Las iteracciones humanas con el entorno se harán a partir de eventos sobre el objeto HTML CANVAS, +por lo que ha de estar disponible cara el usuario sin que halla elementos por delante, si se monta +un objeto por delante, éste impedirá que se interactúe con el objeto HTML CANVAS en la parte que +éste ocupe. Los eventos recogen posición por lo que se pueden hacer rangos y analizar si se +encuentra en una posición concreta o no, como por ejemplo, para hacer botones o interactuar como +Shooter contra objetos en pantalla. + +Finalmente, nos encontramos ante un entorno gráfico que intenta representar lo mismo en cualquier +proporción y resolución, aunque halla recortes en los lados o extremos superiores e inferiores, así +como variación de calidad por resolución. Para ello se basa en un entorno cuadrado que se conforma +con un lado equivalente al lado más estrecho, es decir, si estamos en un entorno visual horizontal, +el cuadrado se adaptará a la altura del mismo; mientras que si es un entorno vertical se adaptará al +ancho, de esta forma, simplemente ha de extenderse la imagen o el procesado fuera del rango +cuadrado, permitiendo que la parte importante, que es el cuadrado que centra la imagen sea completo. +Con respecto a la resolución se utiliza un sistema de celdas que indica los puntos que tiene el +dibujo (No confundir los puntos de dibujado que son áreas con un número X de píxeles con los propios +píxels), lo que permite que en cualquier resolución salga el mismo dibujo puesto que el dibujo +ocupará Y celdas o cuadrados de dibujo; y cada celda ocupará X píxeles de dibujo. + +Con todo esto, se entiende que la idea es hacer un sistema muy ágil de interpretación del esquema de +dibujo (Arrays y diccionarios), lo que daría lugar a que la complejidad de proceso sea el número de +partículas (Imágenes, formas, etc.) y no los dinamismos ni las interactuaciones humanas sobre el +entorno. + +[[html_data { + "title" : "Kanvas - Objetivos", + "url" : "https://kanvas.k3y.pw/es/doc/kanvas.idea.html", + "author" : "KyMAN", + "since" : 20211230, + "version" : 20211230, + "key_words" : "kanvas,canvas,kyman,2d,graphics,idea,planteamiento", + "description" : "La idea del proyecto Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/es/doc/kanvas.quality.w.md b/WMD/es/doc/kanvas.quality.w.md new file mode 100755 index 0000000..7baef0c --- /dev/null +++ b/WMD/es/doc/kanvas.quality.w.md @@ -0,0 +1,108 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20210620, + "version" : 20210620 +}]] +# Calidad + +Como ya se dijo anteriormente, Kanvas se basa en la etiqueta HTML CANVAS, a la cual se le puede +establecer un parámetro de codificación de la imagen a mostrar y pocos parámetros referidos a la +calidad más. Un punto importante para este tipo de trabajos es la resolución pues a mayor resolución +más puntos por refresco ha de procesarse, y por lo tanto, también da un aumento significativo del +rendimiento, sin embargo, CANVAS no tiene ningún atributo que gestione esto a excepción de *WIDTH* y +*HEIGHT*, atributos que establecen los píxeles de ancho y alto consecutivamente, que no tienen +porqué coincidir con el ancho y alto real de la imagen, la cual puede ser alterada mediante CSS, sin +ir más lejos, para adaptarse a la pantalla, por lo tanto, la resolución en sí no es dinámica, sino +fija, cuando dicho tamaño puede ser dinámico. Para ello se pensó en 4 atributos los cuales son: + +- **quality**: Calidad global del CANVAS. +- **quality_x**: Calidad en el eje X. +- **quality_y**: Calidad en el eje Y. +- **cells**: Número de celdas en el lado más estrecho. + +Estos atributos representan la calidad porcentual comprendida en el rango \(0,1\] para representar +la resolución real dinámica del elemento CANVAS y por tanto, tener la misma relación de calidad ante +la posibilidad de cambiar de tamaño o aspecto (Proporción). Para poder conseguir ésto, Kanvas +trabaja por detrás adaptando las posiciones y medidas a éstos valores, quedando las siguientes +fórmulas: + +```maths +\displaylines{ + f_x = x \cdot q \cdot qx \\ + f_y = y \cdot q \cdot qy +} +``` + +Por lo tanto, si tenemos una pantalla FullHD y el marco HTML está a pantalla completa, la calidad +global está al 80%, la calidad del eje X está al 90% y del eje Y al 100% tendríamos el siguiente +resultado: + +```maths +\displaylines{ + W_{ancho} = x \cdot q \cdot qx = 1920 \cdot \frac{80}{100} \cdot \frac{90}{100} = 1920 \cdot 0.8 \cdot 0.9 = 1920 \cdot 0.72 = 1382.4 \\ + H_{alto} = y \cdot q \cdot qy = 1080 \cdot \frac{80}{100} \cdot \frac{100}{100} = 1080 \cdot 0.8 \cdot 1 = 1080 \cdot 0.8 = 864 +} +``` + +> **IMPORTANTE**: No se aconseja la modificación de los parámetros de configuración **quality\_x** +ni **quality\_y** por poder alterar de forma inesperada la respuesta a ciertas operaciones, posiciones, o +matices, así como variar el régimen de calidad de forma abrupta. + +El resultado de estas operaciones se pondrán como atributo WIDTH y HEIGHT del elemento HTML CANVAS, +lo que aumentará o disminiurá la calidad de la imagen, y por tanto, menor o mayor consumo de +recursos, así como a la inversa en rendimiento. + +> **IMPORTANTE**: Los valores **quality**, **quality_x** y **quality_y** son valores que no deberían +de ser nunca mayores que 1 (El 100%) por el hecho de lo aquí mostrado, que sería la resolución real +a la que trabajar, lo mismo que tampoco puede ser cero o menor pues supondría una calidad absurda o +imposible. + +Todo esto permite hacer una relación de calidad con resolución variable tanto en el tamaño como +relación de aspecto del marco HTML donde se encuentre el elemento CANVAS, así como poder gestionar a +nivel de código cambios en la calidad sin detener la vista ejecutada, ahora bien, también nos deja +ver que no hay ahora un concepto de posición fijo y que éste depende plenamente de calidad, para +ello se usará una relación de tamaño al número de celdas en el lado más estrecho del marco HTML a +partir del atributo **cells**, de esta forma, si queremos posicionar un objeto dentro del campo de +visión del Kanvas, a partir del resultado anterior, tendríamos la siguiente formulación: + +```maths +\displaylines{ + p_x = \frac{x \cdot q \cdot qx}{c} \\ + p_y = \frac{y \cdot q \cdot qy}{c} \\ + \\ + p_x = \frac{f_x}{c} \\ + p_y = \frac{f_y}{c} +} +``` + +Continuando con el ejemplo anterior, si ponemos que queremos 20 celdas y que queremos un punto el +cual esté en el 5 del eje X y en el 7 del eje Y tenemos: + +> **NOTA**: Cogemos del ejemplo anterior, para determinar el tamaño real de la celda el eje Y por +ser más pequeño que el eje X. + +```maths +\displaylines{ + {tc} = \frac{f_y}{c} = \frac{864}{20} = 43.2 \text{(Tamaño celda)} \\ + \\ + i_x = X \cdot {tc} = 5 \cdot 43.2 = 216 \\ + i_y = Y \cdot {tc} = 7 \cdot 43.2 = 302.4 +} +``` + +De esta forma podemos mover un objeto a partir de las celdas, entendiendo que se puede mover a un +fragmento de una celda concreta con valores absolutos al lienzo y no a la resolución. Dicha idea +imita los DPI de una pantalla Android por ejemplo, que hace una equivalencia de puntos, pero aquí +también se ignora el tamaño, quedando para cualquier monitor, resolución, etc. Exactamente igual. + +[[html_data { + "title" : "Kanvas - Calidad", + "url" : "https://kanvas.k3y.pw/es/doc/kanvas.quality.html", + "author" : "KyMAN", + "since" : 20210620, + "version" : 20210620, + "key_words" : "kanvas,canvas,kyman,2d,graphics,calidad", + "description" : "Manual de los parámetros de configuración del Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/es/doc/kanvas.settings.w.md b/WMD/es/doc/kanvas.settings.w.md new file mode 100755 index 0000000..014d468 --- /dev/null +++ b/WMD/es/doc/kanvas.settings.w.md @@ -0,0 +1,275 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20210620, + "version" : 20210620 +}]] +# Configuración + +Al ser una simple librería no contamos con archivos externos de configuración por lo que si queremos +hacer uso de ésta o cambiar los parámetros por defecto de la misma, hemos de hacer a partir del +propio constructor, a partir de meterle al constructor, como primer parámetro, un diccionario con +los parámetros que queremos alterar. + +> **NOTA**: Por defecto, si se deja vacío, se usará la configuración por defecto; si se le mete un +valor String se entenderá como el nombre de la instancia dentro de JavaScript para poder ser +referenciada en los eventos; y si es un diccionario, éste representará cada uno de los parámetros +que queramos alterar o incluso añadir, para hacer uso de éstos, por ejemplo, para nuevos componentes +que se le agreguen al Kanvas o para hacer uso de forma externa al mismo usando el sistema de gestión +de parámetros de configuración del propio Kanvas. Para agregar más parámetros simplemente hemos de +escribirlos con un valor y listo. + +> **IMPORTANTE**: Cuidado a la hora de agregar nuevos parámetros pues si se agrega uno que ya +existe, al existente se le cambiará el valor, pudiendo dar resultados inesperados. + +> **IMPORTANTE**: Si el nombre del objeto no se corresponde con el real, los eventos sobre éste no +funcionarán y se puede correr el riesgo de que los eventos tiren contra otro objeto no esperado. + +Un ejemplo de como gestionar los parámetros puede ser lo siguiente: + +```js +// Objeto Kanvas con los valores de configuración por defecto. +kanvas = new Kanvas(); + +// Objeto Kanvas con cambio de nombre del objeto. +kanvas2 = new Kanvas("kanvas2"); + +// Múltiples objetos Kanvas por diccionario. +objetos_kanvas = { + prueba_1 : new Kanvas("objetos_kanvas.prueba_1"), + prueba_2 : new Kanvas("objetos_kanvas.prueba_2"), + prueba_3 : new Kanvas("objetos_kanvas.prueba_3"), + prueba_n : new Kanvas("objetos_kanvas.prueba_n") +}; + +// Objeto Kanvas con los FPS alterados. +kanvas_slow = new Kanvas({ + object_name : "kanvas_slow", + frames_per_second : 12 +}); + +``` + +Los parámetros de configuración que tiene Kanvas por defecto internamente son los siguientes: + +## quality + +Valor decimal mayor que 0 y menor o igual que 1, que representa porcentualmente la calidad global +del objeto HTML CANVAS. Su valor por defecto es 1. + +```maths +\text{quality} = (0, 1] +``` + +## quality_x + +Valor decimal mayor que 0 y menor o igual que 1, que representa porcentualmente la calidad en el eje +X del objeto HTML CANVAS. Su valor por defecto es 1. + +```maths +\text{quality_x} = (0, 1] +``` + +> **NOTA**: Se aconseja dejar dicho valor en 1 por la posibilidad de dar una visualización no +deseada, así como posicionamientos inesperados. + +## quality_y + +Valor decimal mayor que 0 y menor o igual que 1, que representa porcentualmente la calidad en el eje +Y del objeto HTML CANVAS. Su valor por defecto es 1. + +```maths +\text{quality_y} = (0, 1] +``` + +> **NOTA**: Se aconseja dejar dicho valor en 1 por la posibilidad de dar una visualización no +deseada, así como posicionamientos inesperados. + +## cells + +Valor decimal mayor que 0 que representa el número de celdas en que se divide el lado más estrecho +del objeto HTML CANVAS (El lienzo donde se plasmarán los gráficos 2D). Este valor es orientativo +para permitir dar posicionamientos absolutos a los objetos que se metan dentro del CANVAS, similar +al sistema de DPI en Android. Su valor por defecto es 100. + +## origin + +Valor entero positivo comprendido entre 1 y 9, ambos inclusive, que representa el punto 0 (Eje X 0 y +eje Y 0) u origen del cual se empieza a contar positivo o negativo. Este valor representa la +posición de origen según el teclado numérico, siendo los siguientes: + +# Esquina inferior izquierda. +# Inferior centro. +# Esquina inferior derecha. +# Medio izquierda. +# Centro del lienzo. +# Medio derecha. +# Esquina superior izquierda. +# Superior centro. +# Esquina superior derecha. + +
+ + + + + + + + + + + + + + + + + + +
789
456
123
+
+ +Su valor por defecto es 5. + +## frames\_per\_second + +Valor decimal mayor que 0 que representa los fotogramas por segundo, es decir, la tasa de refresco +por segundo, o la cantidad de imágenes o vistas a procesar cada segundo. Por defecto es 60. + +> **IMPORTANTE**: La tasa de fotogramas puede bajar según la capacidad del equipo y los recursos que +consuma el procesado del mapeado del Kanvas. + +> **NOTA**: Los fotogramas no los dará exacto puede excederse en el caso de los Webkit cosa de 3 o 4 +FPS. + +## ratio + +Valor decimal igual o superior a 0 que representa el ratio o relación de aspecto del CANVAS +(Lienzo). Dicho valor puede ser también un valor equivalente a 0 con tipado diferente como puede ser +_null_, _false_, _""_, etc. Los cuales representan que cogerá el ratio por defecto que tenga el +marco donde se instala el GUI del objeto Kanvas. Su valor por defecto es _null_. + +```maths +r = \frac{x}{y} +``` + +> **NOTA**: Para facilitar la visualización del ratio se puede hacer uso de una pequeña división +donde el numerador sea el ancho y el denominador sea el alto, o un un valor decimal que represente +el resultado de dividir el ancho entre el alto. Se entiende con un ratio de pantalla vertical a un +valor superior a 1; una pantalla cuadrada un 1; y una pantalla horizontal cuando es inferior a 1. + +> **NOTA**: El ratio no impedirá que el CANVAS intente coger el máximo área posible del marco HTML +donde se encuentre, simplemente que en el lado donde sobre, éste se centrará automáticamente. + +## overwrite + +Valor booleano que verifica si donde se llame a dicho parámetro, algún o algunos elementos puedan +ser sobreescritos si se da la ocasión. Por defecto es _false_. + +Dicho valor es usado para cuando se intenta agregar elementos nuevos a la configuración entre otros +posibles casos de este tipo. + +## position + +Posición HTML donde instalar el objeto Kanvas, es decir, el DIV con sus contenido CANVAS y cachés. +Dicho valor puede ser un objeto ya cargado propiamente dicho o bien, un selector CSS en formato +String. Su valor por defecto es el selector CSS _"body"_ para ser cargado directamente sobre el +BODY. + +## autostart + +Valor Booleano que verifica si se autoinicia (_true_) o se hace un inicio manual (_false_). Por +defecto su valor es _true_. Para hacer el inicio manual ha de llamarse a la función "start", por +ejemplo: + +```js +// Objeto Kanvas autoiniciado. +kanvas_autoiniciado = new Kanvas({ + object_name : "kanvas_autoiniciado", + autostart : true +}); + +// Objeto Kanvas no autoiniciado. +kanvas_manual = new Kanvas({ + object_name : "kanvas_manual", + autostart : false +}); +// Para iniciar el objeto Kanvas manualmente hemos de hacer tal que así: +kanvas_manual.start(); + +``` + +## object_name + +Valor String que representa el nombre del objeto. Por defecto es _"kanvas"_, sin embargo, si éste +no es el nombre del objeto ha de darse en el constructor del objeto, ya sea mandando como primera +parámetro un String con el nombre de la instancia o bien, en el diccionario de entrada, una llave +con este nombre con el valor del nombre de la instancia. + +Este parámetro es fundamental para que los eventos ataquen al objeto Kanvas en cuestión. + +> **IMPORTANTE**: Si está errado el nombre del objeto éste no funcionará correctamente, incluso +pudiendo atacar a otros objetos Kanvas por cruce de nombres, por ejemplo, usando siempre el valor +por defecto del mismo. + +## class + +Valor String que representa la clase o clases HTML para identificar, por ejemplo, desde JavaScript o +CSS. Por defecto es _"kanvas"_. + +> **IMPORTANTE**: Es importante que si se altera la clase, ésta contenga, entre otras clases +opcionales a decisión del desarrollador, la clase _kanvas_. + +## application + +Valor String que representa el nombre de la aplicación. Por defecto su valor es _Kanvas_, pero puede +ser alterado sin consecuencia alguna, simplemente, el atributo del objeto Kanvas HTML raíz +"data-application" pasará a ser dicho valor. + +## x + +Valor decimal que representa el valor del eje X de cualquier elemento por defecto. Por defecto, +dicho valor es 0. + +> **NOTA**: Generalmente no se hace uso de este valor pues cada componente o elemento de un +componente ya tiene sus valores por defecto, éste se deja por si no existen dichos valores en la +configuración. + +## y + +Valor decimal que representa el valor del eje Y de cualquier elemento por defecto. Por defecto, +dicho valor es 0. + +> **NOTA**: Generalmente no se hace uso de este valor pues cada componente o elemento de un +componente ya tiene sus valores por defecto, éste se deja por si no existen dichos valores en la +configuración. + +## width + +Valor decimal que representa el valor del ancho de cualquier elemento por defecto. Por defecto, +dicho valor es 0. + +> **NOTA**: Generalmente no se hace uso de este valor pues cada componente o elemento de un +componente ya tiene sus valores por defecto, éste se deja por si no existen dichos valores en la +configuración. + +## height + +Valor decimal que representa el valor del alto de cualquier elemento por defecto. Por defecto, +dicho valor es 0. + +> **NOTA**: Generalmente no se hace uso de este valor pues cada componente o elemento de un +componente ya tiene sus valores por defecto, éste se deja por si no existen dichos valores en la +configuración. + +[[html_data { + "title" : "Kanvas - Configuración", + "url" : "https://kanvas.k3y.pw/es/doc/kanvas.settings.html", + "author" : "KyMAN", + "since" : 20210620, + "version" : 20210620, + "key_words" : "kanvas,canvas,kyman,2d,graphics,configuración,parámetros,atributos", + "description" : "Manual de los parámetros de configuración del Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/es/doc/kanvas.starting.w.md b/WMD/es/doc/kanvas.starting.w.md new file mode 100755 index 0000000..074648a --- /dev/null +++ b/WMD/es/doc/kanvas.starting.w.md @@ -0,0 +1,69 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20210620, + "version" : 20210620 +}]] +# Iniciando + +Kanvas no es más que una pequeña librería ECMAScript 2015 totalmente autosuficiente, por lo que sólo +requiere de la implementación en HTML de dicha librería para poder ser iniciada. Para ello podemos +hacer uso de cualquiera de las direcciones puestas al principio del manual ([/es/#Kanvas]). El +siguiente ejemplo HTML muestra la creación de un Kanvas vacío que ocupa todo el marco HTML del +navegador. + +```html + + + + Kanvas - Test + + + + + + + + + + + + +``` + +Como podemos ver en el ejemplo, que el propio Kanvas es una clase objeto con la cual creamos un +objeto el cual será el objeto que gestiona todo lo que se verá en este manual. Cada instancia Kanvas +gestionará un único Kanvas en el GUI, permitiendo poder hacer uso de más de un elemento al mismo +tiempo dentro del entorno HTML. + +[[html_data { + "title" : "Kanvas - Iniciando", + "url" : "https://kanvas.k3y.pw/es/doc/kanvas.starting.html", + "author" : "KyMAN", + "since" : 20210620, + "version" : 20210620, + "key_words" : "kanvas,canvas,kyman,2d,graphics,iniciar,implementar,incluir", + "description" : "Manual para iniciar Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/es/doc/kanvas.targets.w.md b/WMD/es/doc/kanvas.targets.w.md new file mode 100755 index 0000000..6d32a1e --- /dev/null +++ b/WMD/es/doc/kanvas.targets.w.md @@ -0,0 +1,29 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20210621, + "version" : 20211229 +}]] +# Objetivos + +Aquí aparecerán reflejadas todas las tareas acerca de las tareas que hay que llevar a cabo en el +Kanvas. + +- [X] Crear logo. +- [-] Documentar Kanvas. + - *Repasar funcionalidad.* +- [ ] Generar ejemplos para la documentación del Kanvas. +- [ ] Generar Delta Time Constant. +- [ ] Deslimitar los FPS de forma opcional, reduciendo la tasa de refresco de los 4ms por defecto de +los Intervals. + +[[html_data { + "title" : "Kanvas - Objetivos", + "url" : "https://kanvas.k3y.pw/es/doc/kanvas.targets.html", + "author" : "KyMAN", + "since" : 20210621, + "version" : 20211229, + "key_words" : "kanvas,canvas,kyman,2d,graphics,objetivos,tareas", + "description" : "Tareas a realizar o realizadas en el proyecto Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/es/index.w.md b/WMD/es/index.w.md new file mode 100755 index 0000000..79259f8 --- /dev/null +++ b/WMD/es/index.w.md @@ -0,0 +1,55 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20210620, + "version" : 20211230 +}]] +# Kanvas + +El proyecto Kanvas no es más que una pequeña librería JavaScript en ECMAScript 2015 que nos permite +crear y gestionar gráficos 2D sobre un elemento CANVAS gestionado dentro de una etiqueta de capa +DIV, de forma sencilla y limpia, basado en un mapeado Array anidado que nos permite tener tanto la +profundidad como agrupar elementos en diferentes niveles de profundidad, todos ellos ordenados entre +sí. Dichos elementos también están gestionados dentro de la propia librería como elementos de dibujo +o para dibujar. Para poder descargar o hacer uso como CDN de ésta librería se puede utilizar los +siguientes links: + +- https://kanvas.k3y.pw/Kanvas.ecma.js +- https://git.k3y.pw/KyMAN/Kanvas/-/raw/master/Public/Kanvas.ecma.js + +La idea es crear un mapa de los gráficos que se quieren representar en un Array a partir de los +componentes de dibujo que contenga la librería, si hay alguno del cual se quiera hacer uso y no lo +tiene, éste ha de ser implementado por el usuario desarrollador, permitiendo dicha metodología la +reutilización de código para diversos fines. En JavaScript, los objetos almacenados en una variable +funcionan por Mark and Sweep, por tanto son elementos referenciados en memoria y por ello, podemos +moverlos a diferentes puntos del código enviándolo funcionalmente como parámetro donde podrá ser +tratado tanto por Kanvas como por el desarrollador simultáneamente. + +[[header_level 0]] +[[include /WMD/es/doc/kanvas.idea.w.md]] + +[[header_level 0]] +[[include /WMD/es/doc/kanvas.starting.w.md]] + +[[header_level 0]] +[[include /WMD/es/doc/kanvas.settings.w.md]] + +[[header_level 0]] +[[include /WMD/es/doc/kanvas.quality.w.md]] + +[[header_level 0]] +[[include /WMD/es/doc/kanvas.targets.w.md]] + +[[header_level 0]] +[[wdictionaries Diccionario https://wdictionaries.k3y.pw/?es/users,values,own_projects,projects,digital,common]] + +[[html_data { + "title" : "Kanvas - Manual", + "url" : "https://kanvas.k3y.pw/es/", + "author" : "KyMAN", + "since" : 20210620, + "version" : 20211230, + "key_words" : "kanvas,canvas,kyman,2d,graphics", + "description" : "Manual del proyecto Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/index.w.md b/WMD/index.w.md new file mode 100755 index 0000000..a1b65ea --- /dev/null +++ b/WMD/index.w.md @@ -0,0 +1,25 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20210620, + "version" : 20211230 +}]] +# Kanvas + +[[links_group [{ + "images" : ["https://i.imgur.com/im1o0gc.png"], + "link" : "/es/", + "text" : "Español", + "self" : true +}] ]] + +[[html_data { + "title" : "Kanvas - Manual", + "url" : "https://kanvas.k3y.pw/es/", + "author" : "KyMAN", + "since" : 20210620, + "version" : 20211230, + "key_words" : "kanvas,canvas,kyman,2d,graphics", + "description" : "Manual del proyecto Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/push.bat b/push.bat new file mode 100755 index 0000000..ab8e9c4 --- /dev/null +++ b/push.bat @@ -0,0 +1,12 @@ +@echo off + +if "%~1" == "" ( + set /p text="Text commit: " +) else ( + set text=%~1 +) + +git pull +git add . +git commit -m "%text%" +git push \ No newline at end of file diff --git a/push.sh b/push.sh new file mode 100755 index 0000000..63a9673 --- /dev/null +++ b/push.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +text="$1" + +if [ -z "$1" ]; then + echo "Commit text:" + read text +fi + +git pull +git add . +git commit -m "$text" +git push \ No newline at end of file