package core; import js.html.Element; import js.html.DivElement; import js.html.CSSStyleDeclaration; import js.Browser; import core.DivDrawing; import zpartanlite.Enumerables; /* //TODO: change some code to use this enum Compass { North; South; East; West; } enum Orientation { Horizontal; Vertical; } */ using core.DivDrawing; class DivDrawing { public static function curveFromTo ( ddiv: DisplayDiv , p1x: Float , p1y: Float , p2x: Float , p2y: Float , p3x: Float , p3y: Float , _lineWidth: Int , _lineHeight: Int , ?c0: String = '#ff0000' ): List { //Credits for info PIXELWIT see: http://www.pixelwit.com/blog/2007/11/curveto-visualization/ var p12x: Float; var p12y: Float; var p23x: Float; var p23y: Float; var p123x: Int; var p123y: Int; var ratio: Float = 0; var _points = new List>(); var _grads = new List(); var __curve: DivElement; var __point: List; var __style: CSSStyleDeclaration; var steps: Int = 2*Math.ceil( Math.pow( Math.pow( p1x - p3x, 2) + Math.pow( p1y - p3y, 2), 0.5 ) ); var inter = new IntIterator( 0, steps ); var i: Int; for( i in inter ) { __point = new List(); ratio = i/steps; p12x = p1x + ( p2x - p1x )*ratio; p23x = p2x + ( p3x - p2x )*ratio; p123x = Std.int( p12x + ( p23x - p12x )*ratio ); p12y = p1y + ( p2y - p1y )*ratio; p23y = p2y + ( p3y - p2y )*ratio; p123y = Std.int( p12y + ( p23y - p12y )*ratio ); __curve = Browser.document.createDivElement(); //Element( 'div' );//+ ddiv._d++ _grads.push( __curve ); __point.add( p123x ); __point.add( p123y ); _points.add( __point ); __style = __curve.style; __style.paddingTop = _lineHeight + 'px'; __style.paddingLeft = _lineWidth + 'px'; __style.top = p123y + 'px'; __style.left = p123x + 'px'; __style.backgroundColor = c0; __style.position = 'absolute'; ddiv._dom.appendChild( __curve ); } // TODO: REMOVE EXTRA POINTS var _points2 = new List>(); var old: Int = 10000; for( i in _points.iterator() ) { if( i.last() != old ) { _points2.add(i); } old = i.last(); } //return _points2; return _grads; //Need to add clever code to only create on new points (maybe have a lookup of previous points) //Need current pen? } // Maybe not best way!! public static function drawElipse( ddiv: DisplayDiv, cx: Float, cy: Float, rx: Float, ry: Float, _lineWidth: Int, _lineHeight: Int ): Array> { var px: Float; var py: Float; var theta: Float = ( 2*Math.PI ) /8; var points = new Array>(); var iterPoints = new IntIterator( 0, 9 ); for( i in iterPoints ) { var point = new List(); point.add( cx + rx*Math.sin( theta*i )); point.add( cy + ry*Math.cos( theta*i )); points[ i ] = point; } var j: Int = 0; while( j < 8 ) { ddiv.curveThru( points[ j ].first(), points[ j ].last(), points[ j + 1 ].first(), points[ j + 1 ].last(), points[ j + 2 ].first(), points[ j + 2 ].last(), _lineWidth, _lineHeight ); j += 2; } return points; } public static function drawGradient( ddiv: DisplayDiv, x0: Int, y0: Int, w0: Int, h0: Int, c1_: Int, c0_: Int, ?_minPixel: Int = 1, ?direction: Orientation = null ): List { var _tot: Int; var _grads = new List(); var __grad: DivElement; var __style: CSSStyleDeclaration; //var point = drawElipse( x0 + w0/2, y0 + h0/2, w0/2, h0/2, 1 ,1 ); if( direction == Horizontal ) { _tot = Std.int( Math.floor( w0/_minPixel ) ); var iter = new IntIterator( 0, _tot ); for( i in iter) { __grad = Browser.document.createDivElement(); //Element( 'div' );//+ ddiv._d++ _grads.add( __grad ); __style = __grad.style; __style.height = h0 + 'px';//__style.paddingTop __style.width = _minPixel + 'px';//__style.paddingLeft __style.top = y0 + 'px'; __style.left = (x0 + _minPixel*i) + 'px'; __style.position = 'absolute'; ddiv._dom.appendChild( __grad ); } } else { _tot = Std.int( Math.floor( h0/_minPixel ) ); var iter = new IntIterator( 0, _tot ); for( i in iter) { __grad = Browser.document.createDivElement(); //Element( 'div' );//+ ddiv._d++ _grads.add( __grad ); __style = __grad.style; __style.height = _minPixel +'px'; __style.width = w0 + 'px'; __style.top = ( y0 + _minPixel*i ) + 'px'; __style.left = x0 +'px'; __style.position = 'absolute'; ddiv._dom.appendChild( __grad ); } } var gradfill = new GradientFiller( _grads ); gradfill.fill( c0_, c1_ ); return _grads; } public static function drawGradElipse( ddiv: DisplayDiv, x0: Int, y0: Int, w0: Int, h0: Int, c1_: Int, c0_: Int, ?_minPixel: Int = 1, ?direction: Orientation = null ): List { var _tot: Int; var _grads = new List(); var __grad: DivElement; var __style: CSSStyleDeclaration; // Elipse Equations // x2/a2 + y2/b2 = 1; // so... // y2 = b2( 1 - x2/a2 ) var rx0 = w0/2; //var a2 = Math.pow( rx0, 2 ); var ry0 = h0/2; //var b2 = Math.pow( ry0, 2 ); var cx0 = x0 + rx0; var cy0 = y0 + ry0; var delta: Float; //trace( 'direction ' + direction ) ; if( direction == Horizontal ) { //trace('horizontal') ; _tot = Std.int( Math.floor( w0/_minPixel ) ); var iter = new IntIterator( 0, _tot ); for( i in iter) { __grad = Browser.document.createDivElement();//( 'div' );//+ ddiv._d++ _grads.add( __grad ); __style = __grad.style; __style.width = _minPixel + 'px';//__style.paddingLeft delta = Math.pow( Math.pow( ry0, 2 )*( 1 - Math.pow( i - rx0 , 2 )/Math.pow( rx0, 2 ) ), 0.5 ); __style.top = Std.string( ( cy0 - delta) )+ 'px'; __style.height = Std.string( ( 2*delta) )+ 'px'; __style.left = (x0 + _minPixel*i) + 'px'; __style.position = 'absolute'; ddiv._dom.appendChild( __grad ); } } else { _tot = Std.int( Math.floor( h0/_minPixel ) ); var iter = new IntIterator( 0, _tot ); for( i in iter) { __grad = Browser.document.createDivElement(); //( 'div' );//+ ddiv._d++ _grads.add( __grad ); __style = __grad.style; __style.height = _minPixel + 'px'; delta = Math.pow( Math.pow( rx0, 2 )*( 1 - Math.pow( i - ry0 , 2 )/Math.pow( ry0, 2 ) ), 0.5 ); __style.left = Std.string( ( cx0 - delta) )+ 'px'; __style.width = Std.string( ( 2*delta) )+ 'px'; __style.top = (y0 + _minPixel*i) + 'px'; __style.position = 'absolute'; ddiv._dom.appendChild( __grad ); } } var gradfill = new GradientFiller( _grads ); gradfill.fill( c0_, c1_ ); return _grads; } public static function drawGradHexagon( ddiv: DisplayDiv, x0: Int, y0: Int, w0: Int, h0: Int, c1_: Int, c0_: Int, ?_minPixel: Int = 1, ?direction: Orientation = null ): List { var _tot: Int; var _grads = new List(); var __grad: DivElement; var __style: CSSStyleDeclaration; //trace( 'direction ' + direction ) ; if( direction == Horizontal ) { _tot = Std.int( Math.floor( w0/_minPixel ) ); var iter = new IntIterator( 0, _tot ); var deg30 = Math.PI/6; var smallTriBase = h0/2; var smallHypot = smallTriBase/Math.cos(deg30); var leftDist = smallHypot*Math.sin(deg30); // side length = smallHypot var rightDist = _tot - leftDist; for( i in iter) { __grad = Browser.document.createDivElement();//( 'div' );//+ ddiv._d++ _grads.add( __grad ); __style = __grad.style; __style.width = _minPixel + 'px';//__style.paddingLeft if( i < leftDist ) { //leftside __style.height = Math.floor((h0/leftDist)*(i)) + 'px'; __style.top = y0 + h0/2 - Math.floor((h0/leftDist)*i/2)+'px'; } else if( i > rightDist ) { __style.height = Math.floor((h0/leftDist)*(leftDist + rightDist - i )) + 'px'; __style.top = y0 - Math.floor((h0/leftDist)*(rightDist-i)/2)+'px'; } else { __style.height = cast h0 + 'px'; __style.top = cast y0 + 'px'; } //__style.top = y0 + 'px'; __style.left = (x0 + _minPixel*i) + 'px'; __style.position = 'absolute'; ddiv._dom.appendChild( __grad ); } } else { _tot = Std.int( Math.floor( h0/_minPixel ) ); var iter = new IntIterator( 0, _tot ); for( i in iter) { __grad = Browser.document.createDivElement(); //( 'div' );//+ ddiv._d++ _grads.add( __grad ); __style = __grad.style; __style.height = _minPixel +'px'; __style.top = ( y0 + _minPixel*i ) + 'px'; if( i > _tot/2 ) { //draw bottom half __style.width = Math.floor((w0/_tot)*(_tot-i+_tot/2)) + 'px'; __style.left = (x0 + w0/2 - Math.floor((w0/_tot)*(_tot-i+_tot/2)/2))+'px'; } else { //draw top half __style.width = Math.floor((w0/_tot)*(i+_tot/2)) + 'px'; __style.left = (x0 + w0/2 - Math.floor( (w0/_tot)*(i+_tot/2)/2 ))+'px'; } __style.position = 'absolute'; ddiv._dom.appendChild( __grad ); } } var gradfill = new GradientFiller( _grads ); gradfill.fill( c0_, c1_ ); return _grads; } public static function drawGradTriangle( ddiv: DisplayDiv, x0: Int, y0: Int, w0: Int, h0: Int, c1_: Int, c0_: Int, ?_compass: Compass = null, ?_minPixel: Int = 1, ?direction: Orientation = null ): List { // add code for direction var _tot: Int; var _grads = new List(); var __grad: DivElement; var __style: CSSStyleDeclaration; if( direction == Horizontal ) { //trace('horizontal') ; _tot = Std.int( Math.floor( w0/_minPixel ) ); var iter = new IntIterator( 0, _tot ); for( i in iter) { __grad = Browser.document.createDivElement(); //Element( 'div' );//+ ddiv._d++ _grads.add( __grad ); __style = __grad.style; //__style.height = h0 + 'px';//__style.paddingTop __style.width = _minPixel + 'px';//__style.paddingLeft if( _compass == West ) { __style.height = Math.floor((h0/_tot)*(_tot-i)) + 'px'; __style.top = (y0 + h0/2 - Math.floor((h0/_tot)*(_tot-i))/2)+'px'; } else { __style.height = Math.floor((h0/_tot)*i) + 'px'; __style.top = (y0 + h0/2 - Math.floor((h0/_tot)*i)/2)+'px'; } /* __style.top = y0 + 'px'; */ __style.left = (x0 + _minPixel*i) + 'px'; __style.position = 'absolute'; ddiv._dom.appendChild( __grad ); } } else { _tot = Std.int( Math.floor( h0/_minPixel ) ); var iter = new IntIterator( 0, _tot ); for( i in iter) { __grad = Browser.document.createDivElement(); //Element( 'div' );//+ ddiv._d++ _grads.add( __grad ); __style = __grad.style; __style.height = _minPixel +'px'; __style.top = ( y0 + _minPixel*i ) + 'px'; if( _compass == South ) { __style.width = Math.floor((w0/_tot)*(_tot-i)) + 'px'; __style.left = (x0 + w0/2 - Math.floor((w0/_tot)*(_tot-i))/2)+'px'; } else { __style.width = Math.floor((w0/_tot)*i) + 'px'; __style.left = (x0 + w0/2 - Math.floor((w0/_tot)*i)/2)+'px'; } __style.position = 'absolute'; ddiv._dom.appendChild( __grad ); } } var gradfill = new GradientFiller( _grads ); gradfill.fill( c0_, c1_ ); return _grads; } public static function lineFromTo( ddiv: DisplayDiv, p1x: Float, p1y: Float, p2x: Float, p2y: Float, _lineWidth: Int, _lineHeight: Int, ?c0: String = '#ff0000' ): List { var _grads = new List(); var __grad: DivElement; var __style: CSSStyleDeclaration; var ratio: Float; if( p1x - p2x == 0 ) { var steps: Int = 2*Math.ceil(Math.abs(p1y - p2y)); } else if( p1y - p2y == 0 ) { var steps: Int = 2*Math.ceil(Math.abs(p1x - p2x)); } var steps: Int = Math.ceil( Math.pow( Math.pow( p1x - p2x, 2 ) + Math.pow( p1y - p2y, 2 ), 0.5 ) ); var px: Int; var py: Int; var inter = new IntIterator( 0, steps ); for( i in inter ) { ratio = i/steps; px = Std.int(p1x + ( p2x - p1x )*ratio ); py = Std.int(p1y + ( p2y - p1y )*ratio ); __grad = Browser.document.createDivElement(); //createElement( 'div' );//+ ddiv._d++ _grads.add( __grad ); __style = __grad.style; __style.paddingTop = _lineHeight + 'px'; __style.paddingLeft = _lineWidth + 'px'; __style.top = py + 'px'; __style.left = px + 'px'; __style.backgroundColor = c0; __style.position = 'absolute'; ddiv._dom.appendChild( __grad ); } return _grads; } public static function curveThru( ddiv: DisplayDiv , p1x: Float , p1y: Float , p2x: Float , p2y: Float , p3x: Float , p3y: Float , _lineWidth: Int , _lineHeight: Int , ?c0: String ): List { var newx: Float = ( ( 2*p2x ) - .5*( p1x + p3x ) ); var newy: Float = ( ( 2*p2y ) - .5*( p1y + p3y ) ); return ddiv.curveFromTo( p1x, p1y, newx, newy, p3x, p3y, _lineWidth, _lineHeight, c0 ); } }