Connecting two dots
Various ways to connect two points with rounded corners. Useful for creating animations with dynamic shapes.
/**
* Copyright leichtgewicht ( http://wonderfl.net/user/leichtgewicht )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/sZY7
*/
package {
import flash.text.TextFieldAutoSize;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.ui.Mouse;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.display.Sprite;
import com.bit101.components.HSlider;
public class ConnectingTheDots extends Sprite {
private static const INFOS: Object = {
"1": { color: 0x660000, hide: true, name: "horizontal bezier curve" },
"2": { color: 0x666600, hide: true, name: "vertical bezier curve" },
"3": { color: 0xAA0000, hide: true, name: "automatic bezier curve" },
"4": { color: 0x006600, hide: false, name: "adapted curve algorithm" },
"5": { color: 0x00AA00, hide: true, name: "horizontal rounding-perserved curve" },
"6": { color: 0x006666, hide: true, name: "vertical rounding-perserved curve" },
"7": { color: 0x0000AA, hide: true, name: "automatic rounding-perserved curve" },
"8": { color: 0xAA00AA, hide: true, name: "horizontal straight rounded line" },
"9": { color: 0x66AA00, hide: true, name: "vertical straight rounded line" },
"0": { color: 0x0066AA, hide: true, name: "automatic straight rounded line" }
};
private static const VISIBLE_ALPHA: Number = 0.575;
private static const IN_VISIBLE_ALPHA: Number = 0.035;
private var radius: HSlider = new HSlider();
public function ConnectingTheDots() {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
radius.maximum = 200.0;
radius.minimum = 1.0;
radius.value = 110.0;
Mouse.hide();
stage.addEventListener( MouseEvent.MOUSE_MOVE, updateLine );
stage.addEventListener( KeyboardEvent.KEY_DOWN, updateVisibility );
stage.addEventListener( MouseEvent.MOUSE_WHEEL, updateRadius );
createInfo();
updateLine();
}
private function updateVisibility( e: KeyboardEvent ): void
{
var code: String = String.fromCharCode( e.keyCode ).toUpperCase();
if( INFOS[code] )
{
INFOS[code].hide = !INFOS[code].hide;
updateLine();
}
}
private function updateRadius( e: MouseEvent ): void
{
radius.value += e.delta/3.0;
updateLine();
}
private function updateLine( e: Event = null ): void {
graphics.clear();
var startX: int = stage.stageWidth/2;
var startY: int = stage.stageHeight/2 ;
var endX: int = mouseX;
var endY: int = mouseY;
graphics.lineStyle( 1, INFOS["1"].color, INFOS["1"].hide ? IN_VISIBLE_ALPHA : VISIBLE_ALPHA );
drawNormalLineA( graphics, startX, startY, endX, endY, false, radius.value );
graphics.lineStyle( 1, INFOS["2"].color, INFOS["2"].hide ? IN_VISIBLE_ALPHA : VISIBLE_ALPHA);
drawNormalLineA( graphics, startX, startY, endX, endY, true, radius.value );
graphics.lineStyle( 1, INFOS["3"].color, INFOS["3"].hide ? IN_VISIBLE_ALPHA : VISIBLE_ALPHA );
drawNormalLineB( graphics, startX, startY, endX, endY, radius.value );
graphics.lineStyle( 1, INFOS["4"].color, INFOS["4"].hide ? IN_VISIBLE_ALPHA : VISIBLE_ALPHA );
drawAdaptedLine( graphics, startX, startY, endX, endY, radius.value );
graphics.lineStyle( 1, INFOS["5"].color, INFOS["5"].hide ? IN_VISIBLE_ALPHA : VISIBLE_ALPHA );
drawRoundedLineHorizontal( graphics, startX, startY, endX, endY, radius.value );
graphics.lineStyle( 1, INFOS["6"].color, INFOS["6"].hide ? IN_VISIBLE_ALPHA : VISIBLE_ALPHA );
drawRoundedLineVertical( graphics, startX, startY, endX, endY, radius.value );
graphics.lineStyle( 1, INFOS["7"].color, INFOS["7"].hide ? IN_VISIBLE_ALPHA : VISIBLE_ALPHA );
drawRoundedLine( graphics, startX, startY, endX, endY, radius.value );
graphics.lineStyle( 1, INFOS["8"].color, INFOS["8"].hide ? IN_VISIBLE_ALPHA : VISIBLE_ALPHA );
drawStraightRoundedLineH( graphics, startX, startY, endX, endY, radius.value );
graphics.lineStyle( 1, INFOS["9"].color, INFOS["9"].hide ? IN_VISIBLE_ALPHA : VISIBLE_ALPHA );
drawStraightRoundedLineV( graphics, startX, startY, endX, endY, radius.value );
graphics.lineStyle( 1, INFOS["0"].color, INFOS["0"].hide ? IN_VISIBLE_ALPHA : VISIBLE_ALPHA );
drawStraightRoundedLineA( graphics, startX, startY, endX, endY, radius.value );
with( graphics )
{
lineStyle( 1, 0 );
moveTo( startX-2, startY );
lineTo( startX+3, startY );
moveTo( startX, startY-2);
lineTo( startX, startY+3);
moveTo( endX-2, endY );
lineTo( endX+3, endY );
moveTo( endX, endY-2);
lineTo( endX, endY+3);
}
for( var i: String in INFOS ) {
INFOS[i].tF.alpha = INFOS[i].hide ? 0.2 : 0.8;
}
}
private function createInfo(): void{
var sprite: Sprite = new Sprite();
sprite.x = 5.0;
sprite.y = 5.0;
sprite.addChild(createText( 0x000000, "Enter 0-9 to change the visibility." ));
var tF: TextField;
var yOff: Number = 20.0;
for( var i: String in INFOS ) {
tF = createText( INFOS[i].color, "["+i+"] "+INFOS[i].name );
tF.y = yOff;
tF.x = 5.0;
yOff += 15.0;
INFOS[i].tF = tF;
sprite.addChild( tF );
}
tF = createText( 0x000000, "Radius of the lines" );
yOff += 10.0;
tF.y = yOff;
yOff += 20.0;
radius.y = yOff;
radius.x = 5.0;
sprite.addChild(radius);
sprite.addChild(tF);
addChild( sprite );
}
private function createText(color: uint, text:String):TextField {
var tF: TextField = new TextField();
tF.defaultTextFormat = new TextFormat("Verdana", 10, color );
tF.selectable = false;
tF.embedFonts = false;
tF.antiAliasType = AntiAliasType.ADVANCED;
tF.text = text;
tF.autoSize = TextFieldAutoSize.LEFT;
return tF;
}
}
}
import flash.display.Graphics;
function drawNormalLineA( graphics: Graphics, startX: Number, startY: Number, endX: Number, endY: Number, vertical: Boolean = false, radius: Number = 20 ): void {
var w: Number = endX-startX;
var h: Number = endY-startY;
var wA: Number = Math.abs(w);
var hA: Number = Math.abs(h);
var xDir: Number = w < wA ? -1.0 : 1.0;
var yDir: Number = h < hA ? -1.0 : 1.0;
radius = Math.min( wA/2.0, hA/2.0, radius );
var vTangent: Number = vertical ? radius * yDir : 0.0;
var hTangent: Number = vertical ? 0.0 : radius * xDir;
graphics.moveTo( startX, startY );
graphics.curveTo( startX + hTangent, startY + vTangent, startX + (w / 2.0), startY + (h / 2.0) );
graphics.curveTo( endX - hTangent, endY - vTangent, endX, endY );
}
function drawNormalLineB( graphics: Graphics, startX: Number, startY: Number, endX: Number, endY: Number, radius: Number = 20 ): void {
var w: Number = endX-startX;
var h: Number = endY-startY;
var wA: Number = Math.abs(w);
var hA: Number = Math.abs(h);
var xDir: Number = w < wA ? -1.0 : 1.0;
var yDir: Number = h < hA ? -1.0 : 1.0;
radius = Math.min( wA/2.0, hA/2.0, radius );
var vertical: Boolean = wA > hA;
var vTangent: Number = vertical ? radius * yDir : 0.0;
var hTangent: Number = vertical ? 0.0 : radius * xDir;
graphics.moveTo( startX, startY );
graphics.curveTo( startX + hTangent, startY + vTangent, startX + (w / 2.0), startY + (h / 2.0) );
graphics.curveTo( endX - hTangent, endY - vTangent, endX, endY );
}
function drawAdaptedLine( graphics: Graphics, startX: Number, startY: Number, endX: Number, endY: Number, radius: Number = 20 ): void {
var w: Number = endX-startX;
var h: Number = endY-startY;
var wA: Number = Math.abs(w);
var hA: Number = Math.abs(h);
var xDir: Number = w < wA ? -1.0 : 1.0;
var yDir: Number = h < hA ? -1.0 : 1.0;
radius = Math.min( wA/2.0, hA/2.0, radius );
var rXDir: Number = radius * xDir;
var rYDir: Number = radius * yDir;
var wD: Number = wA - radius * 2.0;
var hD: Number = hA - radius * 2.0;
var tangent: Number ;
var vertical: Boolean = wD > hD;
if( !vertical ) {
if( hD == 0 ) {
tangent = radius;
} else {
tangent = radius - ( wD / hD * radius);
}
} else {
if( wD == 0 ) {
tangent = radius;
} else {
tangent = radius - ( hD / wD * radius)
}
}
var vTangent: Number = vertical ? tangent * yDir : 0.0;
var hTangent: Number = vertical ? 0.0 : tangent * xDir;
graphics.moveTo( startX, startY );
graphics.curveTo( startX + hTangent, startY + vTangent, startX + rXDir, startY + rYDir );
graphics.lineTo( endX - rXDir, endY - rYDir );
graphics.curveTo( endX - hTangent, endY - vTangent, endX, endY );
}
function drawRoundedLineHorizontal( graphics: Graphics, startX: Number, startY: Number, endX: Number, endY: Number, radius: Number = 20 ): void {
var w: Number = Math.abs( endX-startX );
var h: Number = Math.abs( endY-startY );
var w2: Number = w/2.0;
var h2: Number = h/2.0;
radius = Math.min( w2, radius );
var h2r: Number = h2-radius;
var d2: Number = Math.sqrt( h2r*h2r+w2*w2-radius*radius );
var angle1: Number = Math.atan2(radius,d2);
var angle2: Number = Math.atan2(h2r,w2);
var angle: Number = -angle1-angle2;
var xDir: Number = startX > endX ? -1.0 : 1.0;
var yDir: Number = startY > endY ? -1.0 : 1.0;
var y1: Number = radius*yDir-Math.cos(angle)*radius*yDir;
var x1: Number = -Math.sin( angle )*radius*xDir;
var t: Number = radius*Math.tan( -angle/2.0 );
graphics.moveTo( startX, startY );
graphics.curveTo( startX+t*xDir, startY, startX+x1, startY+y1 );
graphics.lineTo( endX-x1, endY-y1);
graphics.curveTo( endX-t*xDir, endY, endX, endY );
}
function drawRoundedLineVertical( graphics: Graphics, startX: Number, startY: Number, endX: Number, endY: Number, radius: Number = 20 ): void {
var w: Number = Math.abs( endX-startX );
var h: Number = Math.abs( endY-startY );
var w2: Number = w/2.0;
var h2: Number = h/2.0;
radius = Math.min( h2, radius );
var w2r: Number = w2-radius;
var d2: Number = Math.sqrt( w2r*w2r+h2*h2-radius*radius );
var angle1: Number = Math.atan2(radius,d2);
var angle2: Number = Math.atan2(w2r,h2);
var angle: Number = -angle1-angle2;
var xDir: Number = startX > endX ? -1.0 : 1.0;
var yDir: Number = startY > endY ? -1.0 : 1.0;
var x1: Number = radius*xDir-Math.cos(angle)*radius*xDir;
var y1: Number = -Math.sin( angle )*radius*yDir;
var t: Number = radius*Math.tan( -angle/2.0 );
graphics.moveTo( startX, startY );
graphics.curveTo( startX, startY+t*yDir, startX+x1, startY+y1 );
graphics.lineTo( endX-x1, endY-y1);
graphics.curveTo( endX, endY-t*yDir, endX, endY );
}
function drawRoundedLine( graphics: Graphics, startX: Number, startY: Number, endX: Number, endY: Number, radius: Number = 20 ): void {
var w: Number = Math.abs(endX-startX);
var h: Number = Math.abs(endY-startY);
if( w < h )
{
drawRoundedLineHorizontal( graphics, startX, startY, endX, endY, radius );
}
else
{
drawRoundedLineVertical( graphics, startX, startY, endX, endY, radius );
}
}
function drawStraightRoundedLineH( graphics: Graphics, startX: Number, startY: Number, endX: Number, endY: Number, radius: Number = 20 ): void {
var w: Number = endX-startX;
var h: Number = endY-startY;
var w2: Number = w/2.0;
var h2: Number = h/2.0;
radius = Math.min( Math.abs(w2), Math.abs(h2), radius );
var xDir: Number = startX > endX ? -1.0 : 1.0;
var yDir: Number = startY > endY ? -1.0 : 1.0;
graphics.moveTo( startX, startY );
graphics.lineTo( startX+w2-radius*xDir, startY );
graphics.curveTo( startX+w2, startY, startX+w2, startY+radius*yDir );
graphics.lineTo( startX+w2, startY+h-radius*yDir );
graphics.curveTo( startX+w2, startY+h, startX+w2+radius*xDir, startY+h);
graphics.lineTo( endX, endY );
}
function drawStraightRoundedLineV( graphics: Graphics, startX: Number, startY: Number, endX: Number, endY: Number, radius: Number = 20 ): void {
var w: Number = endX-startX;
var h: Number = endY-startY;
var w2: Number = w/2.0;
var h2: Number = h/2.0;
radius = Math.min( Math.abs(w2), Math.abs(h2), radius );
var xDir: Number = startX > endX ? -1.0 : 1.0;
var yDir: Number = startY > endY ? -1.0 : 1.0;
graphics.moveTo( startX, startY );
graphics.lineTo( startX, startY+h2-radius*yDir);
graphics.curveTo( startX, startY+h2, startX+radius*xDir, startY+h2 );
graphics.lineTo( startX+w-radius*xDir, startY+h2 );
graphics.curveTo( startX+w, startY+h2, startX+w, startY+h2+radius*yDir);
graphics.lineTo( endX, endY );
}
function drawStraightRoundedLineA( graphics: Graphics, startX: Number, startY: Number, endX: Number, endY: Number, radius: Number = 20 ): void {
var w: Number = Math.abs(endX-startX);
var h: Number = Math.abs(endY-startY);
if( w < h )
{
drawStraightRoundedLineH( graphics, startX, startY, endX, endY, radius );
}
else
{
drawStraightRoundedLineV( graphics, startX, startY, endX, endY, radius );
}
}