Detailed description of the non-zero surround principle when HTML5 Canvas is used to draw irregular images. html5canvas
Path direction and non-zero surround Principle
We usually draw well-organized images. If we use a line bar to draw an abstract work, just like the figure below, how do we use fill () to dye our shoes?
Here we need to use a mathematical method-the non-zero surround principle to determine which region is inside and which region is outside. Next, let's take a look at what is a non-zero surround principle.
First, we have to determine a path for the graph. We only need to "draw a stroke" and "do not take the recurring route ., Indicates a path direction. Let's first assume that the positive direction of the path is 1 (in fact, it can be-1, and the positive and negative directions are opposite to each other, not 0 ), the opposite direction is the opposite number-1.
Then, we take a ray in any direction for any point in the several areas cut by the sub-path. Here I only take the rays in three areas as an example, to determine whether the three regions are "Inside" or "outside ".
Next, let's judge. The ray L1 derived from S1 and the positive direction of the Child path of S1 are intersecting. Then we give the counter + 1 and the result is + 1, which is outside.
The X-ray L2 derived from S2 interacts with the positive direction of the two sub-paths. The counter is + 2 and the result is + 2.
The ray L3 in S3 is intersecting with the two sub-paths, but there is a reverse direction. The counter is + 1-1 and the result is 0. Yes, as long as the result is not 0, the ray is located outside.
Draw a ring
Do you remember the arc method? Its last parameter is to determine the direction of the path. If the two concentric circles with the opposite path are together, what is the magical effect of graph coloring?
The following code is used to implement it.
Copy the content to the clipboard using JavaScript Code
- <! DOCTYPE html>
- <Html lang = "zh">
- <Head>
- <Meta charset = "UTF-8">
- <Title> ring </title>
- <Style>
- Body {background: url ("./images/bg3.jpg") repeat ;}
- # Canvas {border: 1px solid # aaaaaa; display: block; margin: 50px auto ;}
- </Style>
- </Head>
- <Body>
- <Div id = "canvas-warp">
- <Canvas id = "canvas">
- Does your browser support Canvas ?! Just change one !!
- </Canvas>
- </Div>
- <Script>
- Window. onload = function (){
- Var canvas = document. getElementById ("canvas ");
- Canvas. width = 800;
- Canvas. height = 600;
- Var context = canvas. getContext ("2d ");
- Context. fillStyle = "# FFF ";
- Context. fillRect (0, 0, 800,600 );
- Context. shadowColor = "#545454 ";
- Context. shadowOffsetX = 5;
- Context. shadowOffsetY = 5;
- Context. shadowBlur = 2;
- Context. arc (400,300,200, 0, Math. PI * 2, false );
- Context. arc (400,300,230, 0, Math. PI * 2, true );
- Context. fillStyle = "#00 AAAA ";
- Context. fill ();
- };
- </Script>
- </Body>
- </Html>
Running result:
Hollow paper-cut effect
Next, we use the non-zero surround principle and shadow to draw a hollow paper-cut effect.
Copy the content to the clipboard using JavaScript Code
- <! DOCTYPE html>
- <Html lang = "zh">
- <Head>
- <Meta charset = "UTF-8">
- <Title> hollow-out paper-cutting effect </title>
- <Style>
- Body {background: url ("./images/bg3.jpg") repeat ;}
- # Canvas {border: 1px solid # aaaaaa; display: block; margin: 50px auto ;}
- </Style>
- </Head>
- <Body>
- <Div id = "canvas-warp">
- <Canvas id = "canvas">
- Does your browser support Canvas ?! Just change one !!
- </Canvas>
- </Div>
- <Script>
- Window. onload = function (){
- Var canvas = document. getElementById ("canvas ");
- Canvas. width = 800;
- Canvas. height = 600;
- Var context = canvas. getContext ("2d ");
- Context. fillStyle = "# FFF ";
- Context. fillRect (0, 0, 800,600 );
- Context. beginPath ();
- Context. rect (200,100,400,400 );
- Fig (context, 250,150,300,150 );
- Fig (context, 345,350,420,450,270,450 );
- Context. arc (500,400, 50, 0, Math. PI * 2, true );
- Context. closePath ();
- Context. fillStyle = "#058 ";
- Context. shadowColor = "gray ";
- Context. shadowOffsetX = 10;
- Context. shadowOffsetY = 10;
- Context. shadowBlur = 10;
- Context. fill ();
- };
- // Draw a rectangle counterclockwise
- Function drawPathRect (cxt, x, y, w, h ){
- /**
- * BeginPath and closePath cannot be used here,
- * Otherwise, it will not belong to the sub-path but to another new path,
- * The non-zero surround principle cannot be used.
- */
- Cxt. moveTo (x, y );
- Cxt. lineTo (x, y + h );
- Cxt. lineTo (x + w, y + h );
- Cxt. lineTo (x + w, y );
- Cxt. lineTo (x, y );
- }
- // Draw a triangle counterclockwise
- Function drawPathTriangle (cxt, x1, y1, x2, y2, x3, y3 ){
- Cxt. moveTo (x1, y1 );
- Cxt. lineTo (x3, y3 );
- Cxt. lineTo (x2, y2 );
- Cxt. lineTo (x1, y1 );
- }
- </Script>
- </Body>
- </Html>
Running result:
The reason for drawing the rectangle manually here is that we want to obtain the rectangle of the counterclockwise path, and the rect () method provided by the API is drawn as a clockwise rectangle. In addition, you must note that this paper-cut is a graph and a path. You cannot use beginPath () and closePath () in the method of drawing hollow triangles and hollow rectangles. Otherwise, they will be new paths and images, instead of the sub-paths and sub-images of paper-cut, the non-zero surround principle cannot be used.