<?
// Use Flash MX drawing API and PHP's GD and Ming modules
// to create images and convert them to
// PNG, JPEG, and static SWF formats
// Jerry Jasuta
// create the swf movie
ming_useswfversion(6);
$movie = new SWFMovie();
$movie->setDimension(300,250);
$movie->setBackground(255,255,255);
$movie->setRate(31);
// mx actionscript
$strAction = "
// variables
drawing=false;
fill=false;
snapTo=false;
ncolor='0x000000';
shapedata=new Array();
shapes=new Array();
shapecount=0;
// keypress listeners for keyboard shortcuts
createEmptyMovieClip('_keyListener',1000);
Key.addListener(_keyListener);
_keyListener.onKeyDown=function(){
if(Key.getCode()==49 || Key.getCode()==97){_root.linethickness.text=1;}
if(Key.getCode()==50 || Key.getCode()==98){_root.linethickness.text=2;}
if(Key.getCode()==51 || Key.getCode()==99){_root.linethickness.text=3;}
if(Key.getCode()==52 || Key.getCode()==100){_root.linethickness.text=4;}
if(Key.getCode()==53 || Key.getCode()==101){_root.linethickness.text=5;}
if(Key.getCode()==54 || Key.getCode()==102){_root.linethickness.text=6;}
if(Key.getCode()==55 || Key.getCode()==103){_root.linethickness.text=7;}
if(Key.getCode()==56 || Key.getCode()==104){_root.linethickness.text=8;}
if(Key.getCode()==57 || Key.getCode()==105){_root.linethickness.text=9;}
_root.cp._y=220-_root.linethickness.text/2;
_root.cp._height=_root.linethickness.text;
_root.cp._yscale=Math.floor(_root.cp._yscale);
if(Key.getCode()==76){_root.shape.text='line';}
if(Key.getCode()==67){_root.shape.text='curve';}
if(Key.getCode()==82){_root.shape.text='rectangle';}
if(Key.getCode()==79){_root.shape.text='circle';}
if(Key.getCode()==80){_root.shape.text='pen';if(drawing){moveTo(_xmouse,_ymouse);_root.tracker.clear();}}
if(Key.getCode()==83){if(snapTo){snapTo=false;}else{snapTo=true;}}
if(Key.getCode()==70){if(fill){_root.fillstatus.text='Fill '+fill=false;}else{_root.fillstatus.text='Fill '+fill=true;}}
if(Key.getCode()==88){for(sc=0;sc<_root.shapes.length;sc++){removeMovieClip(shapes[sc]);}_root.shapes=new Array();_root.shapedata=new Array();if(drawing && shape=='pen'){moveTo(_xmouse,_ymouse);}drawing=false;_root.tracker.clear();}
if(Key.getCode()==90){if(shapecount>0){removeMovieClip(shapes[shapecount]);shapes[shapecount]='';shapedata[shapecount]='';shapecount--;}}
};
// draw curves
function curve(it,startX,startY,mouseX,mouseY){
with(eval(it)){moveTo(startX,startY);curveTo(mouseX,startY,mouseX,mouseY);}
}
// draw ovals/circles
function circle(it,x,y,mouseX,mouseY){
if(Key.isDown(Key.SHIFT)){
a=b=Math.sqrt(Math.pow(Math.abs(mouseX-x),2)+Math.pow(Math.abs(mouseY-y),2));
}else{
a=Math.abs(mouseX-x);
b=Math.abs(mouseY-y);
}
j=a*0.70711;
n=b*0.70711;
i=j-(b-n)*a/b;
m=n-(a-j)*b/a;
with(eval(it)){
if(fill){beginFill(_root.ncolor,100);}
moveTo(x+a,y);
curveTo(x+a,y-m,x+j,y-n);
curveTo(x+i,y-b,x,y-b);
curveTo(x-i,y-b,x-j,y-n);
curveTo(x-a,y-m,x-a,y);
curveTo(x-a,y+m,x-j,y+n);
curveTo(x-i,y+b,x,y+b);
curveTo(x+i,y+b,x+j,y+n);
curveTo(x+a,y+m,x+a,y);
if(fill){endFill();}
}
}
// draw rectangles
function rectangle(it,startX,startY,mouseX,mouseY){
with(eval(it)){
if(fill){beginFill(_root.ncolor,100);}
lineTo(mouseX,startY);
lineTo(mouseX,mouseY);
lineTo(startX,mouseY);
lineTo(startX,startY);
if(fill){endFill();}
}
}
// root event handlers
with(_root){
onMouseDown=function(){
// check if mouse is on canvas
// and begin drawing if so
if(_root.canvas.hitTest(_root._xmouse,_root._ymouse,false) && _root.cp.hitTest(_root._xmouse,_root._ymouse,false)==false){
drawing=true;
startX=snapTo?Math.ceil(_xmouse/10)*10:_xmouse;
startY=snapTo?Math.ceil(_ymouse/10)*10:_ymouse;
if(_root.shape.text=='pen'){
// if current shape is pen, create new MC
penX=_xmouse;
penY=_ymouse;
shapecount++;
shapes[shapecount]='SMC_'+shapecount;
_root.createEmptyMovieClip(shapes[shapecount],1000+shapecount);
with(eval(shapes[shapecount])){moveTo(penX,penY);}
}
}
};
onMouseUp=function(){
// check if mouse is still drawing on the canvas
if(_root.canvas.hitTest(_root._xmouse,_root._ymouse,false)){
if(drawing){
drawing=false;
// clear the tracking clip and create the new shape
tracker.clear();
shapecount++;
shapes[shapecount]='SMC_'+shapecount;
_root.createEmptyMovieClip(shapes[shapecount],shapecount+1000);
thickness=_root.linethickness.text;
with(eval(shapes[shapecount])){
lineStyle(thickness,_root.ncolor);
moveTo(startX,startY);
}
endX=snapTo?Math.floor(_xmouse/10)*10:_xmouse;
endY=snapTo?Math.floor(_ymouse/10)*10:_ymouse;
if(_root.shape.text=='line'){shapedata[shapecount]='line_'+startX+'_'+startY+'_'+endX+'_'+endY+'_'+thickness+'_'+_root.ncolor+'_false-';with(eval(shapes[shapecount])){lineTo(endX,endY);}}
if(_root.shape.text=='curve'){shapedata[shapecount]='curve_'+startX+'_'+startY+'_'+endX+'_'+endY+'_'+thickness+'_'+_root.ncolor+'_false-';curve(shapes[shapecount],startX,startY,endX,endY);}
if(_root.shape.text=='rectangle'){shapedata[shapecount]='rectangle_'+startX+'_'+startY+'_'+endX+'_'+endY+'_'+thickness+'_'+_root.ncolor+'_'+fill+'-';rectangle(shapes[shapecount],startX,startY,endX,endY);}
if(_root.shape.text=='circle'){
if(Key.isDown(Key.SHIFT)){
r=Math.sqrt(Math.pow(Math.abs(startX-endX),2)+Math.pow(Math.abs(startY-endY),2));
shapedata[shapecount]='circle_'+startX+'_'+startY+'_'+(startX+r)+'_'+(startY+r)+'_'+thickness+'_'+_root.ncolor+'_'+fill+'-';circle(shapes[shapecount],startX,startY,endX,endY);
}else{
shapedata[shapecount]='circle_'+startX+'_'+startY+'_'+endX+'_'+endY+'_'+thickness+'_'+_root.ncolor+'_'+fill+'-';circle(shapes[shapecount],startX,startY,endX,endY);
}}
}
}
};
onMouseMove=function(){
// check if mouse is on the canvas
if(_ymouse<200){
// if pen tool is selected and drawing
if(_root.shape.text=='pen' && drawing==true){
// set line attributes and continue drawing
thickness=_root.linethickness.text;
shapelength=Math.sqrt(Math.pow(penX-_xmouse,2)+Math.pow(penY-_ymouse,2));
if(shapelength>5){
// only draw lines 5px or larger to prevent overload
shapecount++;
shapes[shapecount]='SMC_'+shapecount;
_root.createEmptyMovieClip(shapes[shapecount],1000+shapecount);
with(eval(shapes[shapecount])){moveTo(penX,penY);lineStyle(thickness,_root.ncolor);lineTo(_xmouse,_ymouse);}
shapedata[shapecount]='line_'+penX+'_'+penY+'_'+_xmouse+'_'+_ymouse+'_'+thickness+'_'+_root.ncolor+'_false-';
penX=_xmouse;
penY=_ymouse;
updateAfterEvent();
}}else{
// if any tool other than pen is selected
// create the temporary shape
if(drawing==true){
if(snapTo){endX=Math.floor(_xmouse/10)*10;}else{endX=_xmouse;}
if(snapTo){endY=Math.floor(_ymouse/10)*10;}else{endY=_ymouse;}
tracker.clear();
tracker.lineStyle(_root.linethickness.text,_root.ncolor);
tracker.moveTo(startX,startY);
if(_root.shape.text=='line'){tracker.lineTo(endX,endY);}
if(_root.shape.text=='curve'){curve('tracker',startX,startY,endX,endY);}
if(_root.shape.text=='rectangle'){rectangle('tracker',startX,startY,endX,endY);}
if(_root.shape.text=='circle'){circle('tracker',startX,startY,endX,endY);}
}
}
}
updateAfterEvent();
};
}
// end root event handlers
// create the canvas
_root.createEmptyMovieClip('canvas',1);
with(_root.canvas){
lineStyle(2);
moveTo(1,1);
lineTo(299,1);
lineTo(299,199);
lineTo(1,199);
lineTo(1,1);
}
// create the tracking movie clip
_root.createEmptyMovieClip('tracker',2000);
myformat=new TextFormat();
myformat.color=0x000000;
myformat.bullet=false;
myformat.font='Arial';
// create linethickness textfield
createTextField('linethickness',3,0,229,15,20);
linethickness.type='dynamic';
linethickness.selectable=false;
linethickness.multiline=false;
linethickness.wordWrap=false;
linethickness.text=1;
linethickness.setTextFormat(myformat);
myformat.size=10;
// create drawing tool textfield
createTextField('shape',2,0,200,45,20);
shape.type='dynamic';
shape.selectable=false;
shape.multiline=false;
shape.wordWrap=false;
shape.text='pen';
shape.setTextFormat(myformat);
// create fill status textfield
createTextField('fillstatus',4,20,220,30,40);
fillstatus.type='dynamic';
fillstatus.selectable=false;
fillstatus.multiline=true;
fillstatus.wordWrap=true;
fillstatus.text='Fill '+fill;
fillstatus.setTextFormat(myformat);
// create rgb color picker
_root.createEmptyMovieClip('cp',10);
with(_root.cp){
_x=0;_y=218;
createEmptyMovieClip('bg',11);
with(bg){
lineStyle(1,0x000000);beginFill(0x000000);
lineTo(255/2+5,0);lineTo(255/2+5,14);lineTo(0,14);lineTo(0,0);
endFill();
}}
_root.cp.onMouseDown=function(){
if(hitTest(_root._xmouse,_root._ymouse,true) && _root.cp.r.hitTest(_root._xmouse,_root._ymouse,false)==false && _root.cp.g.hitTest(_root._xmouse,_root._ymouse,false)==false && _root.cp.b.hitTest(_root._xmouse,_root._ymouse,false)==false){
with(_root.cp){
startDrag(0);
}
}
};
_root.cp.onMouseUp=function(){
stopDrag();
};
_root.cp.onMouseMove=function(){
if(_root.cp.hitTest(_root._xmouse,_root._ymouse,false)){
this._xscale=200;
this._yscale=200;
_root.cb._visible=false;
}else{
this._xscale=30;
this._height=_root.linethickness.text;
this._yscale=Math.round(this._yscale);
this._x=0;
this._y=220-_root.linethickness.text/2;
_root.cb._visible=true;
stopDrag();
}
if(dragging){
rv=this.r._x*2+1;
gv=this.g._x*2+1;
bv=this.b._x*2+1;
rv=rv.toString(16).length<2?'0'+rv.toString(16):rv.toString(16);
gv=gv.toString(16).length<2?'0'+gv.toString(16):gv.toString(16);
bv=bv.toString(16).length<2?'0'+bv.toString(16):bv.toString(16);
_root.nc.setRGB('0x'+rv+gv+bv);
_root.ncolor='0x'+rv+gv+bv;
}
updateAfterEvent();
};
_root.cp._xscale=30;
_root.cp._yscale=20;
for(c=1;c<4;c++){
if(c==1){cv='r';cf='0xff0000';
}else{if(c==2){cv='g';cf='0x00ff00';
}else{cv='b';cf='0x0000ff';}}
_root.cp.createEmptyMovieClip(cv,c+11);
with(eval('_root.cp.'+cv)){
lineStyle(0.25,0xffffff);
beginFill(cf);moveTo(0,-2);lineTo(5,-2);lineTo(5,2);lineTo(0,2);lineTo(0,-2);endFill();
_x=0;_y=c-3+c*4;
_root.cp[cv].onMouseDown=function(){
if(hitTest(_root._xmouse,_root._ymouse,false)){
drawing=false;
_root.dragging=true;
startDrag(0,0,_y,255/2,_y);
}
};
_root.cp[cv].onMouseUp=function(){
_root.dragging=false;
stopDrag();
};
}
}
_root.nc=new Color(_root.cp.bg);
// end rgb color picker
";
// end of actionscript block
// create a textfield to embed the font
$f=new SWFFont("Arial.fdb");
$tf=new SWFTextField(SWFTEXTFIELD_NOSELECT);
$tf->setFont($f);
$tf->setColor(0,0,0,0);
$tf->addChars("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
$movie->add($tf);
// create the buttons using getURL
// to post the data to the conversion scripts
$cb=new SWFSprite();
$t=new SWFText();
$t->setFont($f);
$t->setHeight(20);
$t->setColor(255,255,255);
$textWidth=$t->getWidth("JPEG PNG & Static SWF");
$textHeight=$t->getAscent()+$t->getDescent();
$t->moveTo(($t->getWidth("JPEG - PNG - Static SWF")-$t->getWidth("Convert Drawing To"))/2,0);
$t->addString("Convert Drawing To");
$t->moveTo(1,$textHeight);
$t->addString("JPEG PNG & Static SWF");
$s=new SWFShape();
$s->setRightFill(0,0,255);
$s->setLine(5,0,0,255);
$s->drawLine($textWidth+10,0);
$s->drawLine(0,$textHeight*2);
$s->drawLine(-($textWidth+10),0);
$s->drawLine(0,-$textHeight*2);
$so=new SWFShape();
$so->setRightFill(255,0,255);
$so->setLine(5,255,0,255);
$so->drawLine($textWidth+10,0);
$so->drawLine(0,$textHeight*2);
$so->drawLine(-($textWidth+10),0);
$so->drawLine(0,-$textHeight*2);
$b=new SWFButton();
$b->addShape($s, SWFBUTTON_UP | SWFBUTTON_HIT);
$b->addShape($so, SWFBUTTON_OVER | SWFBUTTON_DOWN);
$b->setAction(new SWFAction("_root.cb.data='';for(d=0;d<_root.shapedata.length;d++){_root.cb.data+=_root.shapedata[d];}getURL('convert.php','_blank','POST');"));
$i=$cb->add($b);
$i->moveTo(173-($textWidth/2),203);
$i=$cb->add($t);
$i->moveTo(173-($textWidth/2)+5,221);
$cb->nextFrame();
$i=$movie->add($cb);
$i->setName("cb");
$i->setDepth(30);
$movie->add(new SWFAction(str_replace("\r", "", $strAction)));
$movie->save("draw.swf");
$revitalizer=rand();
print "<html><body><center><OBJECT classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://active.macromedia.com/flash2/cabs/swflash.cab#version=6,0,0,0\" ID=objects WIDTH=\"300\" HEIGHT=\"250\">
<PARAM NAME=movie VALUE=\"draw.swf?$revitalizer\">
<EMBED src=\"draw.swf?$revitalizer\" WIDTH=\"300\" HEIGHT=\"250\" TYPE=\"application/x-shockwave-flash\" PLUGINSPAGE=\"http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash\">
</OBJECT></center></body></html>
";
?>