Difference between revisions of "CanvasContext"

 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
[[Category:Image and canvas functions]]
 +
[[DensKeelin]
 
''New in [[Analytica 5.0]]''
 
''New in [[Analytica 5.0]]''
  
== CanvasContext( canvas'', clip, rotAngle, rotx, roty, shiftx, shifty, scalex, scaley'' ) ==
+
== CanvasContext( canvas'', clip, clipMode, rotAngle, rotx, roty, shiftx, shifty, scalex, scaley'' ) ==
  
 
Returns a drawing context with a new clip region or coordinate system. The result can be passed to the «canvas» parameter of any of the Canvas functions.
 
Returns a drawing context with a new clip region or coordinate system. The result can be passed to the «canvas» parameter of any of the Canvas functions.
Line 10: Line 12:
 
* «canvas» is a canvas obtained from calling the <code>[[Canvas]]()</code> function, or a canvas context obtained by calling the <code>[[CanvasContext]]()</code> function.
 
* «canvas» is a canvas obtained from calling the <code>[[Canvas]]()</code> function, or a canvas context obtained by calling the <code>[[CanvasContext]]()</code> function.
 
* «clip»: (Optional) When specified, four numbers must be provided: x, y, width, height. See [[#Clipping]] below.
 
* «clip»: (Optional) When specified, four numbers must be provided: x, y, width, height. See [[#Clipping]] below.
 +
* «clipMode»: (Optional) Specifies how the new «clip» should be combined with the previous clip. The possible values are <code>'Replace'</code>, <code>'Intersect'</code> (default), <code>'Union'</code>, <code>'Exclude'</code>, <code>'Complement'</code>, or <code>'Xor'</code>.
 
* «rotAngle», «rotx», «roty»: (Optional) Specifies the rotation. See [[#Rotations]] below.
 
* «rotAngle», «rotx», «roty»: (Optional) Specifies the rotation. See [[#Rotations]] below.
 
* «shiftx», «shifty»: (Optional) Specifies a translation for the context's coordinate system relative to the original coordinate system. See [[#Shifting]] below.
 
* «shiftx», «shifty»: (Optional) Specifies a translation for the context's coordinate system relative to the original coordinate system. See [[#Shifting]] below.
Line 20: Line 23:
 
Clipping limits the area where stuff that you draw shows up. You specify a clipping rectangle using the «clip» parameter. To illustrate, let's first consider an example with several items drawn without any clipping.
 
Clipping limits the area where stuff that you draw shows up. You specify a clipping rectangle using the «clip» parameter. To illustrate, let's first consider an example with several items drawn without any clipping.
  
  [[Var]] canv := [[Canvas]]( 200, 100, 'Yellow' );  
+
  [[Local]] canv := [[Canvas]]( 200, 100, 'Yellow' );  
 
  [[CanvasDrawRectangle]]( canv, 30, 15, 110, 70, fillColor:'lightgreen', lineColor:'Red' );
 
  [[CanvasDrawRectangle]]( canv, 30, 15, 110, 70, fillColor:'lightgreen', lineColor:'Red' );
 
  [[CanvasDrawLine]](canv, 20, 80, 180, 20 );
 
  [[CanvasDrawLine]](canv, 20, 80, 180, 20 );
Line 32: Line 35:
 
We'll leave the rectangle as is so we have a visual indication of where our clipping rectangle is, but the other items are now drawn to a new context with a clipping region with the same dimensions as the rectangle. Changes are highlighted.
 
We'll leave the rectangle as is so we have a visual indication of where our clipping rectangle is, but the other items are now drawn to a new context with a clipping region with the same dimensions as the rectangle. Changes are highlighted.
  
  [[Var]] canv := [[Canvas]]( 200, 100, 'Yellow' );  
+
  [[Local]] canv := [[Canvas]]( 200, 100, 'Yellow' );  
  <span style="background:yellow">[[Var]] cxt := [[CanvasContext]](canv, clip:[30,15,110,70]);</span>
+
  <span style="background:yellow">[[Local]] cxt := [[CanvasContext]](canv, clip:[30,15,110,70]);</span>
 
  [[CanvasDrawRectangle]]( canv, 30, 15, 110, 70, fillColor:'lightgreen', lineColor:'Red' );
 
  [[CanvasDrawRectangle]]( canv, 30, 15, 110, 70, fillColor:'lightgreen', lineColor:'Red' );
 
  [[CanvasDrawLine]](<span style="background:yellow">cxt</span>, 20, 80, 180, 20 );
 
  [[CanvasDrawLine]](<span style="background:yellow">cxt</span>, 20, 80, 180, 20 );
Line 42: Line 45:
  
 
::[[image:CanvasContext_afterClip.png]]
 
::[[image:CanvasContext_afterClip.png]]
 +
 +
When you extend an existing clip (i.e., when «canvas» is already a context), «clipMode» specifies how «clip» is combined with the previous clip. The shaded region in the following shows the resulting clip region for each clip mode.
 +
 +
::[[image:ClipModes.png]]
 +
 +
The clip modes act as follows:
 +
* <code>'Replace'</code>: Use «clip» as the new clip rect, regardless of the previous clip region.
 +
* <code>'Intersect'</code>:  Use the area in both «clip» and in the previous clip.
 +
* <code>'Union'</code>: Use the area in either «clip» or «canvas»'s clip..
 +
* <code>'Exclude'</code>: Use the area in the previous clip that is outside of «clip».
 +
* <code>'Complement'</code>: Use the area in «clip» that is outside of the previous clip.
 +
* <code>'Xor'</code>: Use the area in «clip» or the previous clip, but not both.
 +
 +
Each of the example clip regions above was drawn using:
 +
 +
[[Local]] c := [[For]] i:=Clip_mode Do [[Canvas]](200,200);
 +
[[CanvasDrawRectangle]](c,10,10,150,150);
 +
[[CanvasDrawRectangle]](c,40,40,150,150);
 +
[[CanvasDrawText]](c,"Existing clip", 15,15);
 +
[[CanvasDrawText]](c,"New clip", 185,185, hAlign:'Right', vAlign:'Bottom');
 +
&nbsp;
 +
[[Local]] cxt1 := [[CanvasContext]](c, clip:10,10,150,150);
 +
Local cxt2 := [[CanvasContext]](cxt1, clip:40,40,150,150, clipMode:Clip_mode);
 +
&nbsp;
 +
[[CanvasDrawRectangle]](cxt2,0,0,200,200,fillColor:0x60888811);
 +
&nbsp;
 +
[[CanvasImage]](c)
 +
 +
with
 +
:Index Clip_mode := <code>['Replace','Intersect','Union','Exclude','Complement','Xor']</code>
  
 
== Rotating ==
 
== Rotating ==
Line 47: Line 80:
 
To rotate the coordinate system, specify «rotAngle» in degrees, and optionally specify the point to rotation around using «rotx», «roty». A positive «rotAngle» will cause your new coordinate system to be rotated clockwise relative to the original coordinate system.
 
To rotate the coordinate system, specify «rotAngle» in degrees, and optionally specify the point to rotation around using «rotx», «roty». A positive «rotAngle» will cause your new coordinate system to be rotated clockwise relative to the original coordinate system.
  
  [[Var]] c := [[Canvas]](200,100);
+
  [[Local]] c := [[Canvas]](200,100);
  [[Var]] cxt := [[CanvasContext]]( c, rot:10, rotx:100, roty:50 );
+
  [[Local]] cxt := [[CanvasContext]]( c, rot:10, rotx:100, roty:50 );
 
  [[CanvasDrawEllipse]]( c, 25, 25, 150, 50, dash:'dot', lineColor:'Green' );
 
  [[CanvasDrawEllipse]]( c, 25, 25, 150, 50, dash:'dot', lineColor:'Green' );
 
  [[CanvasDrawEllipse]]( cxt, 25, 25, 150, 50, lineColor:'Blue' );
 
  [[CanvasDrawEllipse]]( cxt, 25, 25, 150, 50, lineColor:'Blue' );
Line 59: Line 92:
 
«Shiftx» and «shifty» specifies a point in the original context where the origin of your new context's coordinate system will be located.
 
«Shiftx» and «shifty» specifies a point in the original context where the origin of your new context's coordinate system will be located.
  
  [[Var]] c := [[Canvas]](200,100);
+
  [[Local]] c := [[Canvas]](200,100);
  [[Var]] cxt := [[CanvasContext]]( c, shiftx:20 );
+
  [[Local]] cxt := [[CanvasContext]]( c, shiftx:20 );
 
  [[CanvasDrawEllipse]]( c, 25, 25, 150, 50, dash:'dot', lineColor:'Green' );
 
  [[CanvasDrawEllipse]]( c, 25, 25, 150, 50, dash:'dot', lineColor:'Green' );
 
  [[CanvasDrawEllipse]]( cxt, 25, 25, 150, 50, lineColor:'Blue' );
 
  [[CanvasDrawEllipse]]( cxt, 25, 25, 150, 50, lineColor:'Blue' );
Line 80: Line 113:
 
In this example, after the scaling, the coordinates of the image extend from 0 to 1 in the y-axis, and from 0 to <code>[[IndexLength]](Time)</code> in the x-axis.
 
In this example, after the scaling, the coordinates of the image extend from 0 to 1 in the y-axis, and from 0 to <code>[[IndexLength]](Time)</code> in the x-axis.
  
  [[Var]] canv := [[Canvas]](200,50);
+
  [[Local]] canv := [[Canvas]](200,50);
  [[Var]] cxt := [[CanvasContext]](canv, scaley:-50, shifty:50, scalex:200/[[IndexLength]](Time) );
+
  [[Local]] cxt := [[CanvasContext]](canv, scaley:-50, shifty:50, scalex:200/[[IndexLength]](Time) );
 
  [[CanvasDrawLine]]( cxt, Time-1, data[Time=Time-1], Time, data );
 
  [[CanvasDrawLine]]( cxt, Time-1, data[Time=Time-1], Time, data );
 
  [[CanvasImage]](canv)
 
  [[CanvasImage]](canv)
Line 95: Line 128:
 
* [[Drawing images]]
 
* [[Drawing images]]
 
* [[Canvas]]
 
* [[Canvas]]
* [[CanvasDrawLine]], [[CanvasDrawRectangle]], [[CanvasDrawEllipse]], [[CanvasDrawText]], [[CanvasDrawImage]]
+
* [[CanvasDrawLine]], [[CanvasDrawRectangle]], [[CanvasDrawEllipse]], [[CanvasDrawText]], [[CanvasDrawImage]], [[CanvasDrawPolygon]]

Latest revision as of 18:40, 24 May 2021

[[DensKeelin] New in Analytica 5.0

CanvasContext( canvas, clip, clipMode, rotAngle, rotx, roty, shiftx, shifty, scalex, scaley )

Returns a drawing context with a new clip region or coordinate system. The result can be passed to the «canvas» parameter of any of the Canvas functions.

The clip or coordinate system of the original canvas or context is not changed, and you can continue to draw to the original canvas or coordinate system or to the new canvas.

Parameters

  • «canvas» is a canvas obtained from calling the Canvas() function, or a canvas context obtained by calling the CanvasContext() function.
  • «clip»: (Optional) When specified, four numbers must be provided: x, y, width, height. See #Clipping below.
  • «clipMode»: (Optional) Specifies how the new «clip» should be combined with the previous clip. The possible values are 'Replace', 'Intersect' (default), 'Union', 'Exclude', 'Complement', or 'Xor'.
  • «rotAngle», «rotx», «roty»: (Optional) Specifies the rotation. See #Rotations below.
  • «shiftx», «shifty»: (Optional) Specifies a translation for the context's coordinate system relative to the original coordinate system. See #Shifting below.
  • «scalex», «scaley»: (Optional) Specifies a scaling for the context's coordinate system -- how many of the original context's units correspond to one unit in the new coordinate system. See #Scaling below.

When multiple context changes are specified in one call, they are applied in this order: Rotation, translation, scaling then clipping. See #Order of context changes below.

Clipping

Clipping limits the area where stuff that you draw shows up. You specify a clipping rectangle using the «clip» parameter. To illustrate, let's first consider an example with several items drawn without any clipping.

Local canv := Canvas( 200, 100, 'Yellow' ); 
CanvasDrawRectangle( canv, 30, 15, 110, 70, fillColor:'lightgreen', lineColor:'Red' );
CanvasDrawLine(canv, 20, 80, 180, 20 );
CanvasDrawLine(canv,1,1,200,100); 
CanvasDrawEllipse(canv,10,50,50,60,fillColor:0x40FF33FF,sweepAngle:-90,pie:true,startAngle:-50,lineColor:'Black',lineWidth:0.5);
CanvasDrawImage( canv, pict of Analytica_Logo );
CanvasImage(canv )
CanvasContext beforeClip.png

We'll leave the rectangle as is so we have a visual indication of where our clipping rectangle is, but the other items are now drawn to a new context with a clipping region with the same dimensions as the rectangle. Changes are highlighted.

Local canv := Canvas( 200, 100, 'Yellow' ); 
Local cxt := CanvasContext(canv, clip:[30,15,110,70]);
CanvasDrawRectangle( canv, 30, 15, 110, 70, fillColor:'lightgreen', lineColor:'Red' );
CanvasDrawLine(cxt, 20, 80, 180, 20 );
CanvasDrawLine(cxt,1,1,200,100); 
CanvasDrawEllipse(cxt,10,50,50,60,fillColor:0x40FF33FF,sweepAngle:-90,pie:true,startAngle:-50,lineColor:'Black',lineWidth:0.5);
CanvasDrawImage( cxt, pict of Analytica_Logo );
CanvasImage(canv )
CanvasContext afterClip.png

When you extend an existing clip (i.e., when «canvas» is already a context), «clipMode» specifies how «clip» is combined with the previous clip. The shaded region in the following shows the resulting clip region for each clip mode.

ClipModes.png

The clip modes act as follows:

  • 'Replace': Use «clip» as the new clip rect, regardless of the previous clip region.
  • 'Intersect': Use the area in both «clip» and in the previous clip.
  • 'Union': Use the area in either «clip» or «canvas»'s clip..
  • 'Exclude': Use the area in the previous clip that is outside of «clip».
  • 'Complement': Use the area in «clip» that is outside of the previous clip.
  • 'Xor': Use the area in «clip» or the previous clip, but not both.

Each of the example clip regions above was drawn using:

Local c := For i:=Clip_mode Do Canvas(200,200);
CanvasDrawRectangle(c,10,10,150,150);
CanvasDrawRectangle(c,40,40,150,150); 
CanvasDrawText(c,"Existing clip", 15,15);
CanvasDrawText(c,"New clip", 185,185, hAlign:'Right', vAlign:'Bottom');
 
Local cxt1 := CanvasContext(c, clip:10,10,150,150);
Local cxt2 := CanvasContext(cxt1, clip:40,40,150,150, clipMode:Clip_mode);
 
CanvasDrawRectangle(cxt2,0,0,200,200,fillColor:0x60888811);
 
CanvasImage(c)

with

Index Clip_mode := ['Replace','Intersect','Union','Exclude','Complement','Xor']

Rotating

To rotate the coordinate system, specify «rotAngle» in degrees, and optionally specify the point to rotation around using «rotx», «roty». A positive «rotAngle» will cause your new coordinate system to be rotated clockwise relative to the original coordinate system.

Local c := Canvas(200,100);
Local cxt := CanvasContext( c, rot:10, rotx:100, roty:50 );
CanvasDrawEllipse( c, 25, 25, 150, 50, dash:'dot', lineColor:'Green' );
CanvasDrawEllipse( cxt, 25, 25, 150, 50, lineColor:'Blue' );
CanvasImage(c)
CanvasContext rotation.png

Shifting

«Shiftx» and «shifty» specifies a point in the original context where the origin of your new context's coordinate system will be located.

Local c := Canvas(200,100);
Local cxt := CanvasContext( c, shiftx:20 );
CanvasDrawEllipse( c, 25, 25, 150, 50, dash:'dot', lineColor:'Green' );
CanvasDrawEllipse( cxt, 25, 25, 150, 50, lineColor:'Blue' );
CanvasImage(c)
CanvasContext shifting.png

Scaling

You can shrink or magnify your context's coordinate frame compared to the original context using the «scalex» and «scaley» parameters. «Scalex» specifies the number of units in the original context that become one unit in the next context.

Initially, the y-axis increases as you go from the top of the image to the bottom. You can specify a negative scaling for «scaley» to flip the y-axis; however, when you do so you should also specify «shifty» to be the height of image in the parent context to move the origin to the bottom at the same time.

Assume these variables exist.

Index Time := 1..50
Variable Data := Random(over:Time)

In this example, after the scaling, the coordinates of the image extend from 0 to 1 in the y-axis, and from 0 to IndexLength(Time) in the x-axis.

Local canv := Canvas(200,50);
Local cxt := CanvasContext(canv, scaley:-50, shifty:50, scalex:200/IndexLength(Time) );
CanvasDrawLine( cxt, Time-1, data[Time=Time-1], Time, data );
CanvasImage(canv)
CanvasContext scaling.png

Order of context changes

TBD. To do: explain with examples how when multiple changes to the context are specified in a single call, rotation is applied first, then shifting, then then scaling, and lastly clipping.

See also

Comments


You are not allowed to post comments.