Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html>
- <html>
- <head>
- <meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>CAP</title>
- <style>
- body{
- margin:0;
- padding:0;
- }
- #toolbox{
- position:fixed;
- margin:0;
- padding:7px;
- left:0;
- right:0;
- background-color:#aaccff;
- }
- canvas{
- position:absolute;
- top:0;
- left:0;
- border:2px solid black;
- }
- dot{
- position:absolute;
- width:10px;
- height:10px;
- margin-left:-5px;
- margin-top:-5px;
- z-index:99999;
- background-color:black;
- opacity:0.25;
- border-radius:15px;
- }
- dot.slct{
- background-color:#c000c0;
- }
- dot:hover, dot.slct:hover, dot.hovr{
- background-color:#00ff10;
- }
- #dtbx{
- position:absolute;
- left:5px;
- padding:0;
- }
- #dbx2{
- position:fixed;
- padding:5pt;
- }
- button.slct{
- border-style:inset;
- }
- #toolbox button{
- font-size:12pt;
- border: 1px solid #d0d0d0;
- }
- #toolbox button.slct{
- border:2px solid black;
- }
- #toolbox button:hover{
- background-color:#808080;
- }
- button c{
- display: inline-block;
- position: relative;
- top: 2px;
- width:20px;
- height:11px;
- background-color:black;
- }
- #sWdh{
- position:fixed;
- top:50px;
- left:50%;
- width:300px;
- height:100px;
- background-color:white;
- border:2px solid black;
- padding:5px;
- margin-left:-205px;
- }
- dot div{
- top:5px;left:5px;width:0;height:0;margin:0;position:absolute;z-index:-200;
- }
- dot div div{
- margin:-2px 0px 0px;height:4px;background-color:black;top:0;left:0;z-index:-20;pointer-events:none;
- }
- #ctx_mnu{
- background-color: white;
- border: 1px solid grey;
- z-index: 9999999;
- position: fixed;
- margin: 3px;
- padding: 7px;
- }
- #ctx_mnu button {
- border: none;
- border-bottom: 1px solid gray;
- background-color: inherit;
- flex-wrap: wrap;
- flex-direction: column;
- display: block;
- width: 100%;
- text-align: left;
- padding: 3px;
- }
- #ctx_mnu button:hover {
- background-color: #3072FF;
- color:white;
- }
- #fib_1{
- position:fixed;
- z-index:9999999;
- padding:10px;
- margin-left:-150px;
- top:150px;
- left:50%;
- width:300px;
- height:150px;
- border:; 2px solid black;
- background-color:white;
- }
- .hid{
- display:none;
- }
- button.tlsy{
- width: 145pt;
- }
- </style>
- </head>
- <body>
- <script type="text/javascript" src="https://docs.google.com/uc?id=0Bxb5iFgmM3V6eTRINGZ0Zm1zMkk"></script>
- <div id="toolbox">
- Edit Mode:
- <select id="emod" title="Select an Edit Mode">
- <option value="draw">Draw</option>
- <option value="ani">Animate</option>
- <option value="vid">Video edit</option>
- </select>
- <!-- modify change box (cbx) span with a different span for each mode -->
- <span id="cbx">
- <span id="draw_mod">
- Line Cap Style: <select title="Select a Line Cap Style"><option value="butt">flat</option><option value="round">round</option><option value="square">square</option></select>
- Line Join Style: <select title="Select a Line Join Style (very most corner)"><option value="miter">sharp</option><option value="bevel">flat</option><option value="round">round</option></select>
- Shape Fill Style: <select title="Select a shape fill-in style"><option value="none">none (no fill)</option><option value="color">solid color</option><option value="gradient">gradient</option><option value="pattern">pattern</option></select>
- <button class="tlsy">
- <span name="none">---</span>
- <span name="color" class="hid">choose a color <c></c></span>
- <span name="gradient" class="hid">configure a gradient</span>
- <span name="pattern" class="hid">choose a pattern</span>
- </button>
- Line Style: <select title="Select a Line Style"><option value="color">solid color</option><option value="gradient">gradient</option><option value="pattern">pattern</option></select>
- <button class="tlsy">
- <span name="color">choose a color <c></c></span>
- <span name="gradient" class="hid">configure a gradient</span>
- <span name="pattern" class="hid">choose a pattern</span>
- </button>
- <button title="Set Line width">Line Width</button>
- <!-- paintbrush 🖌 -->
- <span name="atool">
- Shape/Draw tools:
- <button name="line" title="line"> \ </button>
- <button name="bezi" title="bezier curve"> S </button>
- <button name="arc" title="arc">◝</button>
- <button name="elps" title="ellipse / circle">◯</button>
- <button name="rect" title="rectangle">▭</button>
- <button name="fill" title="fill (with solid color)"><sub>💧</sub>🔿</button>
- <button name="n0t" class="slct">nothing</button>
- </span>
- </span>
- <span id="vid_mod" class="hid">
- <button title="Add (load) new video source file">+ New Vid Src</button>
- </span>
- <span id="ani_mod" class="hid">
- </span>
- </span>
- </div>
- <div id="dbx2">
- <div id="dtbx">
- <canvas id="Canvas1" width="800" height="500"></canvas>
- <canvas id="CnvsTop" width="800" height="500"></canvas>
- </div>
- </div>
- <div id="sWdh" class="hid">
- Adjust slider or type # of pixels:<input type="range"><input type="number"><button >Done</button>
- </div>
- <div id="ctx_mnu" class="hid">
- <button>Copy (Ctrl+C)</button>
- <button>Cut (Ctrl+X)</button>
- <button>Paste (Ctrl+V)</button>
- <button title="Delete Selected" >Delete (Ctrl+D)</button>
- <button title="Merge Stacked dots at clicked location" >Merge (Ctrl+M)</button>
- <button title="Show the real Context (right click) Menu" >Real ContextMenu</button>
- </div>
- <div id="fib_1" class="hid">
- <button title="upload a file from your computer" >Upload file</button>
- or enter url below:<br>
- <input><button title="Load the URL typed in the input box" >Load URL</button>
- </div>
- <script type="text/javascript">
- /*
- note, for all triginometric systems, be sure to correct cos error with: ang=+(xi<0?Math.PI:0);
- xo=cos(ang)*r, yo=sin(ang)*r;
- where "xi" is x-input, "ang" is angle mesure, "r" is radius, "xo" is x-output, "yo" is y-output;
- when addition or subtraction is performed on ang (theta) with another cartiesian originating angle measure ("ang2"), use this
- ang+ang2+(((xi<0)^(xi2<0))?Math.PI:0);
- where xi2 is the source x input of ang2. "^" is the javascript binary XOR, you know
- NOTE: Math.arctan2(x,y) automatically corrects this
- */
- HTMLCollection.prototype.forEach=Array.prototype.forEach;// << temp
- var d=document,cE="createElement",aC="appendChild",cTN="createTextNode",cN="cloneNode",gI="getElementById",gT="getElementsByTagName",qS="querySelector",qSA="querySelectorAll",aEL="addEventListener",
- frms_sec,res=[800,500],
- tlbx=d[gI]("toolbox"),dtbx=d[gI]("dtbx"), //dtbx= dot-box (for click point circles)
- Canvs1=d[gI]("Canvas1"),ctx=Canvs1.getContext('2d'),
- Cnvs2=d[gI]("CnvsTop"),ctx2=Cnvs2.getContext('2d'),
- IDB=ctx.createImageData(800,500), //rgba
- tIDB=ctx.createImageData(800,500), //tmp
- ldfrm=function(){
- ctx.putImageData(IDB,0,0);
- },
- Dps=function(x,y){
- if(x>res[0]||x<0||y>res[1]||y<1) return -1;
- y=res[1]-y;
- return ((y*res[0])+x)*4;
- },
- dTPM=function(){
- var i=0;
- while(i<IDB.data.length){
- if(tIDB.data[i]>0){
- IDB.data[i]=tIDB.data[i];
- tIDB.data[i]=0;
- }
- i++;
- }},
- pxC=function(D,b,c){ //set a pixel value (c) in an image data object (D) at data array index (b)
- if(b+1&&b<D.data.length){D.data[b]=c[0];
- D.data[b+1]=c[1];
- D.data[b+2]=c[2];
- D.data[b+3]=c[3];}
- },
- sqr=function(x){return x*x;}, //number x to the 2nd power
- VGBI2=(function(){
- var pt="prototype",is_=function VectorGraphicBoxInstance2D(w,h,cs,shp){//use this to create 2D boxes for orientations of segments of animatable characters; cs=centers (joints/attach points); shp=all the lines and curves; later, make function to average several boxes together: seemingly differant shapes and centers, properties of different VGBI2s, with the same name where the said VGBI2s are part of the same VGBI3: the shapes are actually the same shapes seen from differant angles
- var rt={'constructor':is_,'__proto__':is_p,'width':w||is_p.width,'height':h||is_p.height,'centers':cs||[],'shapes':shp||{}};
- return rt;},
- is_p=is_[pt]?is_[pt]:{};
- Object.assign(is_p,{"width":0,"height":0,"centers":[],"shapes":{}});
- return is_;}()),
- VGBI3=(function(){
- var pt="prototype",get2Pweight=function(ar,ro){
- var gots=[[361,-1],[361,-1]]; //[lesser angle,greater angle] than ro
- ar.forEach(function(v,i){var dif=Math.abs(i-ro);if(i==ro)gots=[[0,i]];else
- if(i>ro&&dif<gots[1][0])gots[1]=[dif,i];else
- if(i<ro&&dif<gots[0][0])gots[0]=[dif,i];});
- var gi_=gots[0][0]+gots[1][0];
- gots[0][2]=gi_/gots[0][0];//get weight (multiply each value by its weight, add weights & put in denominator);
- gots[1][2]=gi_/gots[1][0];
- return gots;},
- is_=function VectorGraphicBoxInstance3D(arg/*arg=xr[yr[zr]] is a 3d array of all x-rotations (available viewing angles used to compute 3d apperance), containing all y rotations containing all z rotations*/){
- var rt={'constructor':is_,'__proto__':is_p,'arg':arg?arg:is_p.arg};
- return rt;}, //14 viewing angle 2D boxes by default (cube); include x & y mirroring functions
- is_p=is_[pt]?is_[pt]:{};
- is_p.arg=[];
- is_p.Get2DBox=function(xr,yr,zr){/*the arguments declare the viewing angle;round to the nearest degree;take averages (usually weighted) of nearest existing 2D boxes of the angle ceilinged and floord on all axies.*/};
- return is_;}()),
- //2020Jun15 edit note: I might not use the VectorGraphicBoxInstance system after all; I might invent a system that uses 3d shapes converted to 2d shapes.
- // new:
- AllShps=[], //all shapes (for save)
- AllVids=[], //all video sources
- xp=0,yp=0,zm=1, //x pan, y pan, zoom (global)
- /* //this comment is old code for toolbox rendering
- nwBtn=function(t,f,c,s,h){
- var B=d[cE]("button");h?B.title=h:0;
- B.innerHTML=t;B.onclick=f;B.className=c||"";typeof s=="object"?Object.assign(B.style,s):0;
- return B;
- },
- nwSlc=function(L,f,opt,h){
- var S=d[cE]("select");h?S.title=h:0;S.onchange=f;L?S.L=L:0;
- opt.forEach(function(op){var oe=d[cE]("option");typeof op=="string"?op=[op]:0;oe.value=op[0];oe.innerHTML=op[1]||op[0];S[aC](oe);});
- return S;
- }, */
- eAePt=function ElementAddEventPassThru(elm,evn,evf,b){
- elm[aEL](evn,evf.bind(elm),b);
- if(!elm["LF_"+evn])elm["LF_"+evn]=[]; //temp debug?
- elm["LF_"+evn].push([evf,b]);
- return elm;
- },
- dotRp=function(x,y,S){ //dot RePosition
- x=x||this.co[0]; y=y||this.co[1];
- S=this.style; S.left=(((x+xp))+Canvs1.cx)+"px";
- S.top=(Canvs1.cy-((y+yp)))+"px"; this.lc=this.co; this.co=[x,y];
- if(typeof this.om=="function") this.om();
- }, //remember y is negated (HTML5 Canvas y is top down counting #s up)
- nwDot=function(x,y,om,rp){
- var D=d[cE]("dot");D.co=[x,y];(D.rps=(rp||dotRp).bind(D))(x,y);if(typeof om=="function")D.om=om.bind(D);
- dtbx[aC](D);
- return D;
- },
- avgCo=function(ca){//average an array of coordinates
- var i=ca.length,j=i/2,ac0=0,ac1=0;
- while(i-=2){ac0+=ca[i];ac1+=ca[i+1];}
- return [ac0/j,ac1/j];
- },
- PyThg=function(x,y){//pythagorean theorem 2 short sides input (do not use sqr because that would increase function calls)
- return Math.sqrt((x*x)+(y*y));
- },
- Cnv_Coa=function(coa,fC){//convert coordinate array; use the center coordinate given in fC to convert from standard carteseian to HTML5 canvas coordinate values
- var i=coa.length,coa2=[],y;
- while(i--){y=i%2;coa2[i]=fC[y]+((y?-1:1)*(coa[i]+(y?yp:xp)));}//add x, subtract y
- return coa2;
- },
- Clr=function(c,C){ //clear the canvas given by its ctx object (c)
- c.clearRect(0,0,(C=c.canvas).width,C.height);
- },
- P2mO=function(oa,pn,pv){//property to multiple objects
- oa.forEach(function(O){O[pn]=pv;});
- },
- NpGs=function(DO,so,pn,dpn){ //new property get/set (make a new object property (dpn)(destination property name) of destination object (DO) that is a link to another object property (pn) of source object (so)
- var _F=function(v){return v?so[pn]=v:so[pn];};
- Object.defineProperty(DO,dpn||pn,{"get":_F,"set":_F});
- return DO;
- },
- dotSlct=function(shp,slc,v){ //toggle selection of all the dots in a shape (shp)
- v=slc?"slct":"";for(var i=0;i<shp.dots.length;i++)shp.dots[i].className=v;
- },
- $B={"bc":[ctx2,ctx],"ef":function(){},
- //mtf is supposed to be for saving drawing tool options
- "mtf":{"lineWidth":1,"lineCap":"round","lineJoin":"miter","strokeStyle":"#000000","fillStyle":"#000000","doFill":!1},
- "kdc":function(sy){/*keep draw customization (line & fill options etc.)*/Object.assign($B.bc[0],sy);Object.assign($B.bc[1],sy); }
- };
- $B.mtf2=Object.assign({},$B.mtf);//buffer variable (use to store temp data & save html file bytes)
- Object.defineProperties(HTMLCanvasElement.prototype,{
- "cx":{"get":function(){return (this.width/2);}},
- "cy":{"get":function(){return (this.height/2);}}
- });
- var hdAll=function(nL){
- var i=nL.length;
- while(i--)nL[i].className="hid";
- },
- dbx2=d[gI]("dbx2");
- self.onresize=function(){
- var tlbh=tlbx.clientHeight+20,
- wkw=d.body.clientWidth-20,
- wkh=d.documentElement.clientHeight-tlbh-50;
- dbx2.style.top=tlbh+"px";
- dbx2.style.width=wkw+"px";
- dbx2.style.height=wkh+"px";
- };
- //main toolbox handler functions
- Object.assign(tlbx,
- {"emod":d[gI]("emod"),"slcT":!1, //slcT = selcted Tool
- "sClr":Object.assign(d[cE]("input"),{"type":"color"}), //color select dialog
- "sWdh":(function(){ //set Width
- var sWdh=d[gI]("sWdh"),n1=sWdh[qS]("input[type=range]"),
- n2=sWdh[qS]("input[type=number]"),
- cls=function(){ sWdh.className="hid"; },
- F=function(n){
- if(!isNaN(n)){ $B.mtf.lineWidth=n;dtbx.slctS?dtbx.slctS.mtf.lineWidth=n:0;}
- };
- n1[aEL]("mousemove",function(){F(n2.value=n1.value/2);});
- n2[aEL]("keyup",function(){var n=n2.value*1;isNaN(n)?0:(n>50?n2.value=(n=50):0)+F(n)+(n1.value=n*2);});
- n1.value=2;n2.value=1;
- sWdh[gT]("button")[0][aEL]("click",cls);
- sWdh[aEL]("mouseleave",cls);
- return sWdh;
- })(),
- "uslo":function(){tlbx.emdT[tlbx.emod.value].cntnr[qS]("[name=atool]").geta("button").forEach(function(b){b.className="";});},//unselect buttons
- "cbx":d[gI]("cbx"),
- "emdT":{ //emod (edit mode) Tools
- "draw":$B.ted={
- "cntnr":$B.dbc=d[gI]("draw_mod"),
- "btns":{
- "lnCpSty":eAePt(($B.dbc_s=$B.dbc[gT]("select"))[0],"change",function(){$B.mtf.lineCap=this.value;dtbx.slctS?dtbx.slctS.mtf.lineCap=this.value:0;}),
- "lnJnSty":eAePt($B.dbc_s[1],"change",function(){$B.mtf.lineJoin=this.value;dtbx.slctS?dtbx.slctS.mtf.lineJoin=this.value:0;}),
- "SpFlSty":eAePt($B.sfc=$B.dbc_s[2],"change",function(){var v=this.value,btn=$B.ted.btns.SpFlBtn;
- hdAll(btn.children);
- if(v=="none"){ $B.mtf.doFill=!1; }else{ $B.mtf.doFill=!0; }
- btn[qS]("[name="+v+"]").className="";
- if(v=="color")btn[gT]("c")[0].backgroundColor=$B.mtf.fillStyle;
- }), //end SpFlSty
- "SpFlBtn":Object.assign(NpGs(eAePt(($B.dbc_b=$B.dbc[gT]("button"))[0],"click",$B.sty_d=function(){
- var v=this.sle.value;
- if(v=="color"){var T=this,C=tlbx.sClr,c=T.geta('c')[0].style,bc='backgroundColor';C.onchange=function(){T.put=(c[bc]=this.value);dtbx.slctS?dtbx.slctS.mtf[T.nm]=T.put:0;};c[bc]=(C.value=$B.mtf[T.nm]);C.click();}
- else if(v=="gradient"){}
- else if(v=="pattern"){}
- }),
- $B.mtf,"fillStyle","put"),{"nm":"fillStyle","sle":$B.sfc}),
- "lnSty":eAePt($B.lsy=$B.dbc_s[3],"change",function(){var v=this.value,btn=$B.ted.btns.lnSyBtn;
- hdAll(btn.children); btn[qS]("[name="+v+"]").className="";
- if(v=="color")btn[gT]("c")[0].backgroundColor=$B.mtf.fillStyle;
- }), //end lnSty
- "lnSyBtn":Object.assign(NpGs(eAePt($B.dbc_b[1],"click",$B.sty_d),
- $B.mtf,"strokeStyle","put"),{"nm":"strokeStyle","sle":$B.lsy}),
- "lnWdh":eAePt($B.dbc_b[2],"click",function(){tlbx.sWdh.className="";}),
- "line":eAePt($B.dbc_b[3],"click",function(){tlbx.uslo();tlbx.slcT=$B.ted.line;this.className="slct";}),
- "bezierCurve":eAePt($B.dbc_b[4],"click",function(){tlbx.uslo();tlbx.slcT=$B.ted.bezierCurve;this.className="slct";}),
- "arc":eAePt($B.dbc_b[5],"click",function(){tlbx.uslo();tlbx.slcT=$B.ted.arc;this.className="slct";}),
- "nothing":eAePt($B.dbc[qS]("button[name=n0t]"),"click",function(){tlbx.uslo();tlbx.slcT=!1;this.className="slct";})
- },
- //end buttons, begin shape maker objects with drawer functions
- "line":{"type":"line",
- "nw":function newLine(co){ /*draw new line*/
- var lnArg=co.length==4?co:co.concat(co),c0=lnArg, drawr=function(M,nB,nS,_F){ //M = Boolean (draw on main canvas), true=yes,false=no;
- lnArg.splice.apply(lnArg,([0,4]).concat(D1.co,D2.co));
- Clr(ctx2);
- var cx_=M?ctx:ctx2, coa2=Cnv_Coa(lnArg,[Canvs1.cx,Canvs1.cy]);
- dtbx.slctS==sho?Object.assign(sho.mtf,$B.mtf):0;
- if(!nB){cx_.beginPath();
- $B.kdc(sho.mtf);
- cx_.moveTo(coa2[0],coa2[1]);}
- cx_.lineTo(coa2[2],coa2[3]);
- nS?0:cx_.stroke();
- _F?cx_.fill():0;
- },
- D1=nwDot(c0[0],c0[1],drawr),
- D2=(dtbx.slctD=nwDot(c0[2],c0[3],drawr)),
- sho={"type":this.type,"points":lnArg,"dots":[D1,D2],"drawr":drawr,"mtf":Object.assign({},$B.mtf)}; D2.oS=(D1.oS=sho); AllShps.push(sho); dotSlct(dtbx.slctS=sho);//.oS = owning Shape
- }
- },
- "bezierCurve":{"type":"bezierCurve",
- "nw":function newBezierCurve(co){/*draw new bezierCurve*/
- var Uths=this, curvArg=co.length>=8?co:co.concat.apply(co,(new Array(4-(co.length/2))).fill(co)),c0=curvArg, dD=!1,drawr=function(M,nB,nS,_F){if(!dD){dD=!0;//did Draw (recently within 1/200th of a second)
- /*dot on-move function (re-draw the whole curve in Cnvs2)*/
- Clr(ctx2);
- var cx_=M?ctx:ctx2, coa2=Cnv_Coa(curvArg,[Canvs1.cx,Canvs1.cy]),i_S=dtbx.slctS==sho;
- i_S?Object.assign(sho.mtf,$B.mtf):0;
- if(!nB){cx_.beginPath(); //nB==no Begin (use for drawing fill-inable shapes)
- $B.kdc(sho.mtf);
- cx_.moveTo(coa2[0],coa2[1]);}
- cx_.bezierCurveTo.apply(cx_,coa2.slice(2));
- nS?0:cx_.stroke();
- _F?cx_.fill():0;
- setTimeout(function(){dD=!1;},5);
- }},
- itm=function(){if(Uths.mmwe){
- //in the middle: (move D2 & D3 when either D1 or D4 moves)
- var ev,ev2,mvD={1:[D1.co[0]-D1.lc[0],D1.co[1]-D1.lc[1]],4:[D4.co[0]-D4.lc[0],D4.co[1]-D4.lc[1]]},
- oc=[(D1.lc[0]+D4.lc[0])/2,(D1.lc[1]+D4.lc[1])/2], oma=Math.atan2((D4.lc[1]-D1.lc[1]),(D4.lc[0]-D1.lc[0])),
- nc=[(D1.co[0]+D4.co[0])/2,(D1.co[1]+D4.co[1])/2], or=PyThg(D1.lc[0]-oc[0],D1.lc[1]-oc[1]), nr=PyThg(D1.co[0]-nc[0],D1.co[1]-nc[1]), rc=or?nr/or:1, n1,n2,
- ops={2:{'r':PyThg(n1=D2.co[0]-oc[0],D2.co[1]-oc[1],1),'a':Math.atan2((D2.co[1]-oc[1]),(D2.co[0]-oc[0]))}, 3:{'r':PyThg(n2=D3.co[0]-oc[0],D3.co[1]-oc[1],1),'a':Math.atan((D3.co[1]-oc[1])/(ev=D3.co[0]-oc[0]))+(ev<0?(Math.PI):0)}};
- mvD.a=Math.atan2((D4.co[1]-D1.co[1]),(ev=D4.co[0]-D1.co[0]))-oma;
- var r_=ops[2].r*rc,a_=mvD.a+ops[2].a;
- D2.rps((Math.cos(a_)*r_)+nc[0],(Math.sin(a_)*r_)+nc[1]);
- D3.rps((Math.cos(a_=mvD.a+ops[3].a)*(r_=ops[3].r*rc))+nc[0],(Math.sin(a_)*r_)+nc[1]);
- //D2 & D3 by a line between D1 & D4, & move parallel to that line keeping relative distances between points the same along the line; AKA make D2 and D3 move about the same axis, and same angle degrees as D1 & D4 movements, changing their distance to the axis based on the change of D1 and D4 axis distance change and their coordinate closeness to each
- }else drawr();},
- D1=nwDot(c0[0],c0[1],function(){curvArg.splice(0,2,D1.co[0],D1.co[1]);itm();}), //beggining dot
- D2=nwDot(c0[2],c0[3],function(){curvArg.splice(2,2,D2.co[0],D2.co[1]);drawr();}), //1st control point dot
- D3=nwDot(c0[4],c0[5],function(){curvArg.splice(4,2,D3.co[0],D3.co[1]);drawr();}), //2nd control point dot
- D4=(dtbx.slctD=nwDot(c0[6],c0[7],function(){curvArg.splice(6,2,D4.co[0],D4.co[1]);itm();})), //ending dot (select it so you can streatch the curve out)
- //put this whole curve onto Cnvs2 and adjust curve & Cnvs2 as needed when the Dots are moved (simillar process for other draw shapes); need to add rotation option that rotates the whole shape (use the dot rps functions as part), move whole option also;
- sho={"type":this.type,"points":curvArg,"dots":[D1,D2,D3,D4],"drawr":drawr,"mtf":Object.assign({},$B.mtf)}; P2mO([D1,D2,D3,D4],"oS",sho); AllShps.push(sho); dotSlct(dtbx.slctS=sho);
- },
- "mmwe":!0 //move middle with ends (see line 160ish in function 'itm' in bezierCurve.nw)
- },
- "arc":{"type":"arc",
- "nw":function newArc(co){
- var Uths=this,arcG=co.length>=6?co:co.concat.apply(co,(new Array(3-(co.length/2))).fill(co)),c0=arcG,drawr=function(M,nB,nS,_F){
- //ctx.arcTo(x1,y1,x2,y2,radius);
- Clr(ctx2);
- var cx_=M?ctx:ctx2, coa2=Cnv_Coa(arcG,[Canvs1.cx,Canvs1.cy]);
- dtbx.slctS==sho?Object.assign(sho.mtf,$B.mtf):0;
- if(!nB){cx_.beginPath();
- $B.kdc(sho.mtf);
- cx_.moveTo(coa2[0],coa2[1]);}
- cx_.arcTo.apply(cx_,coa2.slice(2).concat([sho.R]));
- nS?0:cx_.stroke();
- _F?cx_.fill():0;
- },
- itm=function(){if(Uths.mmwe){
- //in the middle: (move D2 & D3 when either D1 or D4 moves)
- var mvD={1:[D1.co[0]-D1.lc[0],D1.co[1]-D1.lc[1]],3:[D3.co[0]-D3.lc[0],D3.co[1]-D3.lc[1]]},
- oc=[(D1.lc[0]+D3.lc[0])/2,(D1.lc[1]+D3.lc[1])/2], oma=Math.atan2((D3.lc[1]-D1.lc[1]),(D3.lc[0]-D1.lc[0])),
- nc=[(D1.co[0]+D3.co[0])/2,(D1.co[1]+D3.co[1])/2], or=PyThg(D1.lc[0]-oc[0],D1.lc[1]-oc[1]), nr=PyThg(D1.co[0]-nc[0],D1.co[1]-nc[1]), rc=or?nr/or:1, n1,n2,
- ops={'r':PyThg(n1=D2.co[0]-oc[0],D2.co[1]-oc[1],1),'a':Math.atan2((D2.co[1]-oc[1]),(D2.co[0]-oc[0]))};
- mvD.a=Math.atan2((D3.co[1]-D1.co[1]),(D3.co[0]-D1.co[0]))-oma;
- var r_=ops.r*rc,a_=mvD.a+ops.a;
- D2.rps((Math.cos(a_)*r_)+nc[0],(Math.sin(a_)*r_)+nc[1]);
- //D2 by a line between D1 & D3, & move parallel to that line keeping relative distances between points the same along the line; AKA make D2 move about the same axis, and same angle degrees as D1 & D3 movements, changing it's distance to the axis based on the change of D1 and D3 axis distance change and it's coordinate closeness to each
- }else drawr();},
- //DR is not needed. D2 makes 2 mirrored right triangles with a combined hypotonoose, 1 with D1 at the right angle & 1 with D3 at the right angle, the hypotonose is not the radius, it's a side other than the one(s) made by lines D2-D1, D2-D3, the hypotonoose is always perpendicular to a line D1-D3, D2 is always the same distance from D1 as from D3, the hypotonoose is always lined up along D1-D3 with D2
- crft=function crft(){ //ClacRadiusFromTangent
- var d1_3x=D1.co[0]-D3.co[0],d1_3y=D1.co[1]-D3.co[1],d1_3d=PyThg(d1_3x,d1_3y), d1_2x=D1.co[0]-D2.co[0],d1_2y=D1.co[1]-D2.co[1],
- d1_2ang=Math.atan2(d1_2y,d1_2x),d1_3ang=Math.atan2(d1_3y,d1_3x); sho.R=zm*(d1_3d/2)/Math.abs(Math.cos((Math.PI/2)-Math.abs(d1_2ang-d1_3ang)));
- if(crft.caller==D2.om){
- var d3_2x=D3.co[0]-D2.co[0],d3_2y=D3.co[1]-D2.co[1],d3_2d=PyThg(d3_2x,d3_2y),d1_2d=PyThg(d1_2x,d1_2y), aang=(d1_3ang+(Math.PI/2)), ad2=(d3_2d+d1_2d)/2; //Math.tan(?);
- }
- },
- D1=nwDot(c0[0],c0[1],function(){arcG.splice(0,2,D1.co[0],D1.co[1]);crft();itm();}),
- D2=nwDot(c0[2],c0[3],function(){arcG.splice(2,2,D2.co[0],D2.co[1]);crft();drawr();}),
- D3=(dtbx.slctD=nwDot(c0[4],c0[5],function(){arcG.splice(4,2,D3.co[0],D3.co[1]);crft();itm();})),
- D2_rps=function tf(x,y,S){ /*confine x & y:
- need to find point of intersection the x & y axis of this point have with a the line bisecting and perpendicular to line D1-D2,
- choose the point of intersection that is closest to this point and move this point there
- use a point on the line that I know (middle of D1-D2), use rise/run to find intersection point of coordinate using other coordinate
- wait actually, make imaginary line paralel to D1-D2 with one end at x,y and the other on the line perpendicular to D1-D2,
- move x,y to where this imag line is on perpendicular line,
- could do this by averaging x_i_y & y_i_x ?*/
- x==null?x=this.co[0]:0;y==null?y=this.co[1]:0;//keep
- var ctr=[(D1.co[0]+D3.co[0])/2,(D1.co[1]+D3.co[1])/2],cx,cy,rise=D3.co[1]-D1.co[1],run=D3.co[0]-D1.co[0],ang=Math.atan2(rise,run)+(Math.PI/2);
- var x_i_y=((x-ctr[0])*Math.tan(ang))+ctr[1]; //y coord of x-intercept ?
- var y_i_x=((y-ctr[1])/Math.tan(ang))+ctr[0]; //x coord of y-intercept ?
- var x_i_dis=PyThg(x-ctr[0],x_i_y-ctr[1]); //inefficient code, fix later, works, but needs improving
- var y_i_dis=PyThg(y_i_x-ctr[0],y-ctr[1]);
- //test:
- //self.to1=function(a,b){return (a/(a+b))+(b/(a+b));}
- var y_i_m,x_i_m,both=y_i_dis+x_i_dis;
- if(x_i_dis==0){y_i_m=1;x_i_m=0;}
- else if(y_i_dis==0){x_i_m=1;y_i_m=0;}
- else{x_i_m=y_i_dis/both;y_i_m=x_i_dis/both;}
- var newcoord=[((y_i_x*y_i_m)+(x*x_i_m)),((x_i_y*x_i_m)+(y*y_i_m))]; x=newcoord[0];y=newcoord[1]; //gets wacky as distance between pointer (mouse) and D2 increases, works mostly the way I want at realy close range
- //if(x_i_dis>y_i_dis){x=y_i_x;}else{y=x_i_y;} //uncomment this if test fail
- S=this.style;S.left=(((x+xp))+Canvs1.cx)+"px";S.top=(Canvs1.cy-((y+yp)))+"px";this.lc=this.co;this.co=[x,y];if(typeof this.om=="function")this.om();//keep
- },
- sho={"type":this.type,"points":arcG,"R":0,"dots":[D1,D2,D3],"drawr":drawr,"mtf":Object.assign({},$B.mtf)};
- D2.rps=D2_rps.bind(D2);P2mO([D1,D2,D3],"oS",sho); AllShps.push(sho); crft(); dotSlct(dtbx.slctS=sho); D1.title="D1";D2.title="D2";D3.title="D3";
- },
- "mmwe":!0
- },
- //end simple shapes, begin combo shapes
- "ellipse":{ //2 bezier curves?
- },
- "rectangle":{
- //4 lines
- },
- "triangle":{
- //3 lines
- }
- //end shape maker objects
- },
- "ani":{
- "cntnr":$B.anc=d[gI]("ani_mod")
- },
- "vid":{
- "cntnr":$B.vbc=d[gI]("vid_mod"),
- "doon":function(){if(!self.v_edity)TJA.require("https://docs.google.com/uc?id=0Bxb5iFgmM3V6TXVsakNTYV9hZVU");},
- "btns":{
- "nVidSrc":eAePt(($B.vbc_b=$B.vbc[gT]("button"))[0],"click",function(){ FIB_.cb=function F(dat,inf){ AllVids.push({"dat":dat,"nm":F.nm||inf.name,"type":inf?inf.type:F.xhr.getResponseHeader("Content-Type")});}; d.body[aC](FIB_); },0,0,"Add (load) new video source file")
- }
- }
- }
- });
- //main toolbox handler functions END
- tlbx.emod.onchange=function(){
- hdAll(tlbx.cbx.children);
- (mo=tlbx.emdT[this.value]).cntnr.className="";
- if(typeof mo.doon=="function")mo.doon();
- self.onresize();
- };
- tlbx.emod.onchange();
- /*dtbx.oca=[]; //on click array (probably won't use this now)
- dtbx.onclick=function(e){
- var co=[e.clientX,e.ClientY],t2=this;
- t2.oca.forEach(function(v){v.call(t2,co,t2.lc);});
- t2.lc=co;
- };*/
- self.onmousemove=function(e){let b;
- if(dtbx.md){ var tar=e.target||e.srcElement,co=[(((e.clientX-(dtbx.offsetLeft+dbx2.offsetLeft))-Canvs1.cx)/zm)-xp,((Canvs1.cy-(e.clientY-(dtbx.offsetTop+dbx2.offsetTop)))/zm)-yp];
- if(dtbx.slctD){
- dtbx.slctD.rps(co[0],co[1]);
- }
- dtbx.lc=co;
- }else if(b=dtbx.dc_){ xp=-(b[0]-e.clientX);yp=b[1]-e.clientY; Clr(ctx);Render(!0); }
- };
- var Render=function(dd){ //do dot
- var i=AllShps.length,L=i,j,S;
- while(i--){ if((S=AllShps[i])!=dtbx.slctS)S.drawr(!0);}
- if(dd){i=L;while(i--){(S=AllShps[i].dots)[0].rps();S[S.length-1].rps();}}
- if(dtbx.slctS)dtbx.slctS.drawr();
- };
- dtbx.onmousedown=function(e){
- if(e.button==2)return 0;
- else if(e.button==1){ dtbx.dc_=[e.clientX,e.clientY]; return 0;}
- var tar=e.target||e.srcElement,co=[((e.clientX-(dtbx.offsetLeft+dbx2.offsetLeft)-Canvs1.cx)/zm)-xp,((Canvs1.cy-(e.clientY-
- (dtbx.offsetTop+dbx2.offsetTop)))/zm)-yp],T=this; T.md=!0;T.fc=co;
- if(tar.nodeName=="DOT"){T.slctD=tar; //selected Dot
- Clr(ctx);
- if(T.slctD.oS){if(T.slctS)dotSlct(T.slctS);Object.assign($B.mtf,(T.slctS=T.slctD.oS).mtf);dotSlct(T.slctS,!0);} //selected Shape
- Render();
- }else if(tar==Canvs1||tar==Cnvs2){
- if(dtbx.slctS){dtbx.slctS.drawr(!0);dotSlct(dtbx.slctS,!1);}dtbx.slctS=!1;Object.assign($B.mtf,$B.mtf2);
- if(typeof tlbx.slcT.nw=="function"){tlbx.slcT.nw(co); dotSlct(dtbx.slctS,!0);} //"new" function for SeLecTed tool (this might only be for draw mode)
- }
- };
- self.onmouseup=function(e){ var tar=e.target||e.srcElement,co=[(((e.clientX-(dtbx.offsetLeft+dbx2.offsetLeft))-Canvs1.cx)/zm)-xp,((Canvs1.cy-(e.clientY-(dtbx.offsetTop+dbx2.offsetTop)))/zm)-yp];
- if(dtbx.md){
- if(dtbx.slctD){
- dtbx.slctD.rps(co[0],co[1]);
- }
- }
- dtbx.md=!1;dtbx.slctD=!1;dtbx.lc=co; if(dtbx.dc_){Clr(ctx);Render(!0);dtbx.dc_=!1;}
- };
- self.ondrag=function(e){e.preventDefault();};
- /*dtbx.onwheel=function(e){
- if(e.deltaY>0){ zm*=1.02; Clr(ctx);Render(!0); }else if(zm>0.2&&e.deltaY<0){ zm*=0.98; Clr(ctx); Render(!0); }
- dtbx.style.transform="scale("+zm+")";
- }; */
- dtbx.onmouseover=function(e){ var tar=e.target||e.srcElement;
- if(tar.nodeName=="DOT"){
- var dts=tar.oS.dots,i=dts.length;
- while(i--)dts[i].classList.add("hovr");
- }
- };
- dtbx.onmouseout=function(e){ var tar=e.target||e.srcElement;
- if(tar.nodeName=="DOT"){
- var dts=tar.oS.dots,i=dts.length;
- while(i--)dts[i].classList.remove("hovr");
- }
- };
- //ctx mnu
- var ctx_mnu=dtbx.ctx_mnu=d[gI]("ctx_mnu"),$n=null;
- ctx_mnu.onclick=(self.onclick=function(e){ if(e.button!=2)ctx_mnu.className="hid";});
- dtbx.oncontextmenu=function(e){ if(!ctx_mnu.ldf){ e.preventDefault(); ctx_mnu.le=e; var sy=dtbx.ctx_mnu.style; ctx_mnu.dfm=e.default; ctx_mnu.className=""; sy.top=(e.clientY-7)+"px"; sy.left=(e.clientX-7)+"px"; return !1;}else{ ctx_mnu.ldf--; return !0;}};
- ctx_mnu.copy=eAePt(($B.ctxmB=ctx_mnu[gT]("button"))[0],"click",function Copy(){});
- ctx_mnu.cut=eAePt($B.ctxmB[1],"click",function Cut(){});
- ctx_mnu.paste=eAePt($B.ctxmB[2],"click",function Paste(){});
- ctx_mnu.delete=eAePt($B.ctxmB[3],"click",function Delete(e,s){ if(s=dtbx.slctS){var i=AllShps.indexOf(s);dtbx.slctD=(dtbx.slctS=!1);AllShps.splice(i,1);ctx2.clearRect(0,0,Cnvs2.width,Cnvs2.height);i=s.dots.length;while(i--)s.dots[i].remove(); }});
- ctx_mnu.merge=eAePt($B.ctxmB[4],"click",function Merge(e){ var cd,ec=[ctx_mnu.le.clientX-Canvs1.cx,Canvs1.cy-ctx_mnu.le.ClientY],dts=dtbx.geta("dot"),i=dts.length; while(i--)if(PyThg((cd=dts[i]).co[0]-ec[0],cd.co[1]-ec[1])<5) "merge"; });
- ctx_mnu.rctxm=eAePt($B.ctxmB[5],"click",function Real_ctxmnu(e){ ctx_mnu.ldf=1; ctx_mnu.className="hid"; /*ctx_mnu.le.initEvent("contextmenu",!0,!1); dtbx.dispatchEvent(ctx_mnu.le); */});
- //File Input Box
- self.FIB_=d[gI]("fib_1");
- (FIB_.b=FIB_[gT]("button"))[0][aEL]("click",function(){if(typeof FIB_.cb=="function")TJA.openf(FIB_.cb);FIB_.remove();});
- var hACAO=(self.location.host+",ve.media.tumblr.com,media.tumblr.com,a.tumblr.com,cors-anywhere.herokuapp.com").split(",");
- FIB_.ub=FIB_[gT]("input")[0];
- $B.lfu_=function(){ if(typeof FIB_.cb=="function"){v_edity.load2(FIB_.cb.nm=FIB_.ub.value,FIB_.cb,hACAO.indexOf(TJA.gurl(FIB_.ub.value,"://","/"))>=0);} FIB_.className="hid";};
- FIB_.ub.onkeydown=function(e){if(e.keyCode==13)$B.lfu_();};
- FIB_.b[1][aEL]("click",$B.lfu_);
- //convert drawing to a save-able string
- self.saveShps=function(){ var A=AllShps,i=A.length,L=i,da=[],m,ma=[],j; while(i--){m=JSON.stringify(A[i].mtf); if((j=ma.indexOf(m))+1)m="A"+j;else ma[i]=m; da[i]=(A[i].type+";"+m+";"+A[i].points.join()); } return da.join("|"); };
- self.loadShps=function(d){ var A=d.split("|"),i=A.length,L=i,b; while(i--)A[i]=A[i].split(";");i=L;while(i--){b=A[i];$B.mtf=JSON.parse(b[1][0]=="A"?(A[b[1].substr(1)*1][1]):b[1]);tlbx.emdT.draw[b[0]].nw(b[2].split(",").map(function(n){return n*1;}));} Render(); dotSlct(dtbx.slctS,!0);dtbx.slctS.drawr(); };
- /*
- make multiplier vars for x and y and radius, panning (scrolling vertical or horizontal) vars for x and y,
- apply to all ctx.draw functions and all onclick or event coordinate functions, so that user can zoom in on shapes at different coords in their drawing without it looking pixelated
- self.hidd="data:text/css;base64,"+btoa("dot{ display:none; }");
- self.l2=Object.assign(d[cE]("link"),{type:"text/css",rel:"stylesheet",href:hidd});
- d.head[aC](l2); //append for hide dots,
- */
- </script>
- </body>
- </html>
Add Comment
Please, Sign In to add comment