A Flash Developer Resource Site

Results 1 to 11 of 11

Thread: creating a draw rectangle tool

  1. #1
    Senior Member ninjakannon's Avatar
    Join Date
    Sep 2004
    Posts
    393

    creating a draw rectangle tool

    Hi,

    I want to get flash to draw a rectangle when you click and then drag, the dragging will resize the rectangle (like in flash itself) and when you let go, the rectangle will be drawn and placed on the stage, with a fill and edges.

    Regards,
    ninjakannon

    - My Website -

  2. #2
    Senior Member Dricciotti's Avatar
    Join Date
    Aug 2002
    Posts
    2,988
    Ok. You can do this with actionscript (kind of tricky) or no actionscript (pretty easy).
    Easy Way:
    You have a MC of a square in your library and attach it to the stage when the user clicks somewhere. Then, you rescale the size of the MC depending on where the mouse is with respect to where it was origionally clicked. So, lets pretend you have a square (top left alighned) movie clip with a name of "square". You would do something like this:
    Code:
    _root.onMouseDown = function()
    {
      box = attachMovie("square","b"+i,i++);
      box.XM = _root._xmouse;
      box.YM = _root._ymouse; 
      box._x = box.XM;
      box._y = box.YM;
      box._width = 1;
      box._height = 1;
      box.onEnterFrame = function()
      {
        this._width = _root._xmouse - this.XM;
        this._height = _root._ymouse - this.YM;
      }
    }
    _root.onMouseUp = function() // i believe this is correct
    {
      delete box.onEnterFrame;
    }
    As for the hard way, it would involved a lot of coding.

  3. #3
    Senior Member Dricciotti's Avatar
    Join Date
    Aug 2002
    Posts
    2,988
    side note: A cool way to also do this would be to do the same as above, with the square movie clip but dont give the square a fill, just have it be a border so when you move the mouse around you would have a black box/border moving around. Then, when you release the mouse again, you could use actionsript to draw a box around the existing box then use a fill to fill in the box. This way, you only see the fill color after you are done drawing the box. Also, using an actionscript fill would allow easier control of the color of the box (if you wanted to let the user control it)

    Ok, so that was probaly a lot of ranting that might not have made any sense but I hope that helps you. I will try to work up a little .fla file for you as soon as I get some time.

  4. #4

    An sctionscript solution

    Paste this in the first frame of a movie:

    Code:
    var canvas = this.createEmptyMovieClip("drawRect",1);
    
    var back = canvas.createEmptyMovieClip("back", 1);
    back.beginFill(0x000000, 0);
    back.moveTo(0, 0);
    back.lineTo(Stage.width, 0);
    back.lineTo(Stage.width, Stage.height);
    back.lineTo(0, Stage.height);
    back.lineTo(0, 0);
    back.endFill();
    
    canvas.x1, canvas.x2, canvas.y1, canvas.y2;
    canvas.rects = new Array();
    
    canvas.fillColor = 0x668822;
    canvas.strokeColor = 0x449977;
    canvas.strokWidth = 3;
    canvas.alpha = 80;
    
    canvas.onPress = function() {
    	this.x1 = this._xmouse;
    	this.y1 = this._ymouse;
    	this.onEnterFrame = function() {
    		this.clear();
    		this.lineStyle(1, 0x000099, 80);
    		this.moveTo(this.x1, this.y1);
    		this.lineTo(this._xmouse, this.y1);
    		this.lineTo(this._xmouse, this._ymouse);
    		this.lineTo(this.x1, this._ymouse);
    		this.lineTo(this.x1, this.y1);
    	};
    };
    canvas.onRelease = function() {
    	this.clear();
    	delete this.onEnterFrame;
    	var dpt = this.getNextHighestDepth();
    	
    	var nmc = this.createEmptyMovieClip("rect"+dpt, dpt);
    	nmc.beginFill(this.fillColor, this.alpha);
    	nmc.lineStyle(this.strokWidth, this.strokeColor, this.alpha);
    	nmc.moveTo(this.x1, this.y1);
    	nmc.lineTo(this._xmouse, this.y1);
    	nmc.lineTo(this._xmouse, this._ymouse);
    	nmc.lineTo(this.x1, this._ymouse);
    	nmc.lineTo(this.x1, this.y1);
    	nmc.endFill();
    	this.rects.push(nmc);
    };
    stuff and other stuff

  5. #5
    Senior Member Dricciotti's Avatar
    Join Date
    Aug 2002
    Posts
    2,988
    Yours works better

    redrawing the box every time on the onEnterFrame may get a little cpu-intensive though

  6. #6
    Yeah flash drawing sucks. Hopefully Maelstrom will help.

    Drawing four lines each frame shouldn't hurt much though.
    That mc your scaling will have to be redrawn each frame as well.
    I'd be interested to see what the speed differenced are.
    stuff and other stuff

  7. #7
    Senior Member Dricciotti's Avatar
    Join Date
    Aug 2002
    Posts
    2,988
    I would too. Maybe set up a timer program that does the two and compares.

    err... something to do when I have free time

  8. #8
    Senior Member ninjakannon's Avatar
    Join Date
    Sep 2004
    Posts
    393
    oh, wow thanxs,
    your really good at this!

    As your so good I'm gonna ask you how you can do the same, but with a circle (or oval) and if possible get it so that it draws a perfect circle if u hold shift. But a oval tool would be fine.

    Thanks for all the help,
    ninjakannon

    - My Website -

  9. #9
    Senior Member
    Join Date
    Feb 2001
    Location
    On the fifth floor.
    Posts
    1,202
    For rectangle
    Code:
    this.onMouseDown = function() {
    	newBox.clear();
    	startX = _xmouse;
    	startY = _ymouse;
    	dragging = true;
    	
    }
    this.onMouseMove = function() {
    	if (dragging) {
        	    endX = _xmouse;
    	        endY = _ymouse;
    	        _root.createEmptyMovieClip("newBox",1);
    	        with(_root.newBox) {
    				lineStyle(0,0xFF0000,100);
            		beginFill(0xff0000, 20);
    	        	moveTo(_root.startX,_root.startY);
    	    	    lineTo(_root.endX,_root.startY);
    		        lineTo(_root.endX,_root.endY);
    		        lineTo(_root.startX,_root.endY);
    		        lineTo(_root.startX,_root.startY);
    		        endFill();
    			}
    		}
    }
    this.onMouseUp = function() {
    	dragging = false;
    }
    For circle
    Code:
    this.onMouseDown = function() {
    	startX = _xmouse;
    	startY = _ymouse;
    	dragging = true;
    	
    }
    this.onMouseMove = function() {
    	if (dragging) {
           endX = _xmouse;
    	   endY = _ymouse;
    _root.createEmptyMovieClip("circle",0);
    	with(circle){
    	k = Math.PI /180;
    	R =  Math.sqrt(((endX-startX)*(endX-startX))+((endY-startY)*(endY-startY)));
    	lineStyle(1, 0x0000FF, 100);
    	moveTo(R,0);
    	beginFill(0xFF00FF,20)	
    	_spotx = R;
    	_spoty = 0;
    
    for (var i=0; i<360; i++) {
    	getSpot(i);
    	curveTo(_spotX, _spotY, endX, endY);
    	}
    }
    circle._x = startX;
    circle._y = startY;
    	}
    }
    function getSpot(i) {
    	endX = _spotx;
    	endY = _spoty;
    	_spotx = R * Math.cos(i*k);
    	_spoty = R * Math.sin(i*k);
    	endFill();
    }
    this.onMouseUp = function() {
    	dragging = false;
    }

  10. #10
    Senior Member Dricciotti's Avatar
    Join Date
    Aug 2002
    Posts
    2,988
    nice code snipets sergwiz. I am also curious though on the efficency of that one versus using a MC and changing its _width and _height. It probably dosent matter in the long run, just curious.

  11. #11
    I did this a bit fast so it could probably be structured better. Using AS 2 and some OOP would probably be a good idea too but then you would loose the coolness of the cut and paste one frame movie.

    The two shapes in the upper left corner are buttons. Click on them to draw different shapes.

    Code:
    function drawRect(mc, x1, y1, x2, y2) {
    	mc.moveTo(x1, y1);
    	mc.lineTo(x2, y1);
    	mc.lineTo(x2, y2);
    	mc.lineTo(x1, y2);
    	mc.lineTo(x1, y1);
    }
    ///////////////////
    //took this from here: http://actionscript-toolbox.com/flashmx_drawingtools.php
    function drawCircle(mc, r, x, y) {
    	mc.moveTo(x+r, y);
    	a = Math.tan(22.5*Math.PI/180);
    	for (var angle = 45; angle<=360; angle += 45) {
    		// endpoint:
    		var endx = r*Math.cos(angle*Math.PI/180);
    		var endy = r*Math.sin(angle*Math.PI/180);
    		// control:
    		// (angle-90 is used to give the correct sign)
    		var cx = endx+r*a*Math.cos((angle-90)*Math.PI/180);
    		var cy = endy+r*a*Math.sin((angle-90)*Math.PI/180);
    		mc.curveTo(cx+x, cy+y, endx+x, endy+y);
    	}
    }
    ////////////////////
    
    var canvas = this.createEmptyMovieClip("drawRect", 1);
    var back = canvas.createEmptyMovieClip("back", 1);
    back.beginFill(0x000000, 0);
    back.moveTo(0, 0);
    back.lineTo(Stage.width, 0);
    back.lineTo(Stage.width, Stage.height);
    back.lineTo(0, Stage.height);
    back.lineTo(0, 0);
    back.endFill();
    
    
    var GUI = this.createEmptyMovieClip("GUI", 3);
    GUI.canvas = canvas;
    
    var rectButton = GUI.createEmptyMovieClip("rectButton", 2);
    var circleButton = GUI.createEmptyMovieClip("circleButton", 3);
    
    rectButton.lineStyle(1, 0x000000, 100);
    rectButton.beginFill(0x666666, 100);
    drawRect(rectButton, 0, 0, 20, 10);
    rectButton.endFill();
    rectButton._x = 20;
    rectButton._y = 10;
    rectButton.onRelease = function() {
    	this._parent.canvas.setTool("RECT");
    };
    
    
    circleButton.lineStyle(1, 0x000000, 100);
    circleButton.beginFill(0x666666, 100);
    drawCircle(circleButton, 10, 0, 0);
    circleButton.endFill();
    circleButton._x = 30;
    circleButton._y = 40;
    circleButton.onRelease = function() {
    	this._parent.canvas.setTool("CIRCLE");
    };
    
    canvas.x1, canvas.y1;
    canvas.shapes = new Array();
    canvas.fillColor = 0x668822;
    canvas.strokeColor = 0x449977;
    canvas.strokWidth = 3;
    canvas.alpha = 80;
    
    
    canvas.setTool = function(tool) {
    	switch (tool) {
    	case "RECT" :
    		this.onRelease = function() {
    			this.clear();
    			delete this.onEnterFrame;
    			var dpt = this.getNextHighestDepth();
    			var nmc = this.createEmptyMovieClip("rect"+dpt, dpt);
    			nmc.beginFill(this.fillColor, this.alpha);
    			nmc.lineStyle(this.strokWidth, this.strokeColor, this.alpha);
    			drawRect(nmc, this.x1, this.y1, this._xmouse, this._ymouse);
    			nmc.endFill();
    			this.shapes.push(nmc);
    		};
    		this.onPress = function() {
    			this.x1 = this._xmouse;
    			this.y1 = this._ymouse;
    			this.onEnterFrame = function() {
    				this.clear();
    				this.lineStyle(1, 0x000099, 80);
    				drawRect(this, this.x1, this.y1, this._xmouse, this._ymouse);
    			};
    		};
    		break;
    	case "CIRCLE" :
    	this.onRelease = function() {
    			this.clear();
    			delete this.onEnterFrame;
    			var dpt = this.getNextHighestDepth();
    			var nmc = this.createEmptyMovieClip("rect"+dpt, dpt);
    			nmc.beginFill(this.fillColor, this.alpha);
    			nmc.lineStyle(this.strokWidth, this.strokeColor, this.alpha);
    			drawCircle(nmc, this._xmouse - this.x1, this.x1, this.y1);
    			nmc.endFill();
    			this.shapes.push(nmc);
    		};
    		this.onPress = function() {
    			this.x1 = this._xmouse;
    			this.y1 = this._ymouse;
    			this.onEnterFrame = function() {
    				this.clear();
    				this.lineStyle(1, 0x000099, 80);
    				var r = this._xmouse - this.x1;
    				drawCircle(this, r, this.x1, this.y1);
    			};
    		};
    		break;
    	}
    };
    
    canvas.setTool("RECT");
    stuff and other stuff

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center