JavaScript canvas (canvas), scratch card making, Sketchpad
1, First acquaintance with canvas
The emergence of canvas element can be said to open the door of drawing animation and graphics in the Web world. Its function is very powerful. Canvas element is the most powerful element in HTML5. Its ability is mainly expressed through the Context (drawing Context / drawing environment) object in canvas.
1. The getcontext () method is used to obtain the rendering context and its painting function.
2. Draw rectangle:
fillRect(x, y, width, height) draws a filled rectangle
strokeRect(x, y, width, height) draws a rectangular border
clearRect(x, y, width, height) clears the specified rectangular area and makes the cleared part completely transparent.
3. Draw path:
beginPath() creates a new path. After generation, the drawing command is directed to the path to generate the path.
After closePath() closes the path, the drawing command points back to the context.
stroke() draws the outline of the figure through lines.
fill() generates a solid shape by filling the content area of the path.
4. Move stroke: moveTo(x, y) moves the stroke to the specified coordinates x and y. Draw line path: lineTo(x, y) draws a line from the current position to the specified X and Y positions
5. Draw arc path:
Arc (x,y, radius, startAngle, endAngle, anticlockwise) draws an arc (circle) with radius and (x,y) as the center. It is generated from startAngle to endAngle according to the direction given by anticlockwise (clockwise by default).
arcTo(x1, y1, x2, y2, radius) draws an arc according to the given control point and radius, and then connects the two control points with a straight line.
js expression of angle and radian: radians=(Math.PI/180)*degrees
6. Fill color:
fillStyle = color sets the fill color of the drawing
strokeStyle = color sets the color of the shape outline
Transparency globalAlpha = transparencyValue this attribute affects the transparency of all graphics in canvas. The valid values range from 0.0 (fully transparent) to 1.0 (fully opaque). The default is 1.0.
7. Line styles
lineWidth = value sets the line width. Lines with odd width cannot be accurately rendered
lineCap = type sets the line end style.
lineJoin = type sets the style of the indirect joint between the line and the line.
Mitterlimit = value limits the maximum length at the junction when two lines intersect; The so-called joint length (miter length) refers to the length from the inner corner vertex to the outer corner vertex at the line joint.
canvas attribute quick reference table:
Step 1: introduce canvas
<body> <canvas id="canvas_1" width="600" height="600"> The content in this is not displayed on the normal canvas, canvas Three elements: id Unique identification width wide height high canvas It's just a canvas label. To draw content, you must use js draw </canvas> </body>
Step 2: introduce canvas
//1. Find canvas var canvas1 = document.querySelector("#canvas_1"); console.log([canvas1]) //2. Context object (brush) var pencil = canvas1.getContext("2d"); //3. Draw path pencil.rect(50,50,300,300);//Draw a rectangle //4 filling pencil.fillStyle = "pink"; pencil.fill() //Stroke, render path pencil.lineWidth = 20;//Set draw width pencil.strokeStyle = "salmon";//Set paint color pencil.stroke()
Example
draw rectangle
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <canvas id="canvas_1" width="600" height="600"> The content in this is not displayed on the normal canvas, canvas Three elements: id Unique identification width wide height high canvas It's just a canvas label. To draw content, you must use js draw </canvas> <script> //1. Find canvas var canvas1 = document.querySelector("#canvas_1"); console.log([canvas1]) //2. Context object (brush) var pencil = canvas1.getContext("2d"); console.log(pencil); //3. Draw path pencil.rect(50,50,300,300); //fill pencil.fillStyle = "pink"; pencil.fill() //Stroke, render path pencil.lineWidth = 20; pencil.strokeStyle = "salmon"; pencil.stroke() </script> </body> </html>
Draw line
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <canvas id="canvas_1" width="500" height="500"></canvas> <script> var canvas1 = document.querySelector("#canvas_1"); var cvs = canvas1.getContext('2d'); console.log(cvs) //Set start path cvs.beginPath() //Sets the starting point for passing through a position cvs.moveTo(50,50); //Set a position to pass cvs.lineTo(50,200); //Set a position to pass cvs.lineTo(60,300); //Set a position to pass cvs.lineTo(100,50); //Set end path cvs.closePath() //Draw path cvs.lineCap = "round";//Sets the edge the path passes through as a fillet cvs.lineJoin = "round"; cvs.strokeStyle = "pink"; cvs.lineWidth = 10; cvs.stroke(); </script> </body> </html>
2, Draw text
Draw text
cvs.font = "30px Microsoft YaHei ";
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <canvas id="canvas_1" width="500" height="500"></canvas> <script> var canvas1 = document.querySelector("canvas"); var cvs = canvas1.getContext("2d"); //Set shadows cvs.shadowBlur = 20; cvs.shadowColor = "skyblue"; cvs.shadowOffsetX = 10; cvs.shadowOffsetY = 10; cvs.font = "30px Microsoft YaHei "; cvs.strokeStyle = "#333"; var x = 500; setInterval(function(){ cvs.clearRect(0,0,500,500) x -=3; if(x<-100){ x=500 } cvs.strokeText("Isn't that cute",x,200); },30) </script> </body> </html>
3, Draw circle image, video
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> </head> <body> <canvas id="canvas_1" width="600" height="600"></canvas> <script> var canvas1 = document.querySelector("canvas"); var cvs = canvas1.getContext("2d"); //Draw image CVs DrawImage (picture object, x position, y position) //Draw image CVs DrawImage (picture object, x position, y position, width, height) //Draw image CVs DrawImage (picture object, clipping position x, clipping position Y, clipping width, clipping height, x position, y position, width, height) var img = new Image(); img.src = "../js study/imag/clockbg.png"; img.onload = function() { cvs.translate(400, 300); cvs.arc(0, 0, 200, 0, 2 * Math.PI); cvs.clip(); cvs.drawImage(img, -200, -200, 400, 400); cvs.strokeStyle = "orange"; cvs.lineWidth = 10; cvs.stroke(); }; </script> </body> </html>
design sketch
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <video src="../MP3/mda-mke7tdctjt86cnib.mp4" controls="controls" width="400" height=""></video> <canvas id="canvas" width="600" height="600"></canvas> <script> var interid; var video1 = document.querySelector("video"); var canvas1 = document.querySelector("canvas"); var cvs = canvas1.getContext("2d"); video1.onplay = function(){ interid = setInterval(function(){ cvs.clearRect(0,0,600,600) cvs.fillRect(0,0,600,600) cvs.drawImage(video1,100,70,400,225); },16) } video1.onpause = function(){ clearInterval(interid); } </script> </body> </html>
4, Clock
Save is used to save the current canvas state. Restore resets the canvas state to what it was when save was saved. Canvas states are divided into canvas coordinates (transform), canvas drawing area (clip), and the combination mode set in the canvas (global compositeoperation). When we use transform,clip and globalcompositeoperation, the state of the canvas will be changed, and this change will affect the next canvas drawing operation. Therefore, we need to use save to save the canvas before this operation, and use restore to reset the canvas state in the next operation after changing the state.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> </head> <body> <canvas id="canvas_1" width="800" height="600"></canvas> <script> var img = new Image(); img.src = "../js study/imag/clockbg.png"; var canvas1 = document.querySelector("canvas"); var cvs = canvas1.getContext("2d"); img.onload= function(){ xuanranclock(); setInterval(function() { xuanranclock(); }, 1000); } function xuanranclock() { cvs.clearRect(0, 0, 800, 600); //Draw dial cvs.beginPath(); cvs.arc(400, 300, 200, 0, 2 * Math.PI); cvs.clip(); cvs.drawImage(img, 200, 100, 400, 400); cvs.strokeStyle = "orange"; cvs.lineWidth = 10; cvs.stroke(); cvs.closePath(); //Save the status cvs.save(); //Move the coordinates of the canvas to the center of the canvas cvs.translate(400, 300); cvs.rotate((-2 * Math.PI) / 4); cvs.save(); //Draw clock scale for (var i = 0; i < 12; i++) { cvs.rotate((Math.PI * 2) / 12); cvs.beginPath(); cvs.moveTo(180, 0); cvs.lineTo(200, 0); cvs.strokeStyle = "orange"; cvs.stroke(); cvs.closePath(); } cvs.restore(); cvs.save(); //Draw second hand for (var i = 0; i < 60; i++) { cvs.beginPath(); cvs.rotate(Math.PI / 30); cvs.moveTo(180, 0); cvs.lineTo(200, 0); cvs.lineWidth = 2; cvs.strokeStyle = "orange"; cvs.stroke(); cvs.closePath(); } cvs.restore(); cvs.save(); var time = new Date(); var hour = time.getHours(); var min = time.getMinutes(); var sec = time.getSeconds(); //If the time is greater than 12, subtract 12 directly hour = hour > 12 ? hour - 12 : hour; //Draw second hand cvs.beginPath(); cvs.rotate(((2 * Math.PI) / 60) * sec); cvs.moveTo(-20, 0); cvs.lineTo(170, 0); cvs.lineWidth = 2; cvs.strokeStyle = "rgb(135, 197, 248)"; cvs.stroke(); cvs.closePath(); cvs.restore(); cvs.save(); //Draw fen pin cvs.beginPath(); cvs.rotate((2 * Math.PI * min) / 60 + ((2 * Math.PI) / 3600) * sec); cvs.moveTo(-20, 0); cvs.lineTo(160, 0); cvs.lineWidth = 4; cvs.strokeStyle = "#333"; cvs.stroke(); cvs.closePath(); cvs.restore(); cvs.save(); //Draw hour scale cvs.beginPath(); cvs.rotate( (2 * Math.PI * hour) / 12 + ((2 * Math.PI) / 60 / 12) * min + ((2 * Math.PI) / 12 / 60 / 60) * sec ); cvs.moveTo(-10, 0); cvs.lineTo(140, 0); cvs.lineWidth = 6; cvs.strokeStyle = " rgb(105, 69, 236)"; cvs.stroke(); cvs.closePath(); cvs.restore(); cvs.beginPath(); //lid cvs.arc(0, 0, 10, 0, 2 * Math.PI); cvs.fillStyle = "black"; cvs.fill(); cvs.closePath(); cvs.restore(); } </script> </body> </html>
design sketch
5, Scraping card making
Preparatory knowledge
globalCompositeOperation is used to control how the source image is displayed on the target image.
Source image: refers to the image you want to paint on the canvas
Target image: an image that has been drawn on the canvas
Attribute value:
value | describe |
---|---|
source-over | Default. Displays the source image on the target image. |
source-atop | The source image is transparent. Only the intersection between the source image and the target image displays the source image, and other parts are transparent |
source-in | Both the source image and the target image are transparent. Only the intersection of the source image and the target image is opaque, and the source image is displayed |
source-out | The target image is transparent and the source image is opaque. If there is an intersection between the target image and the source image, the image of the intersection part is transparent |
destination-over | Draw the source image on the lower layer of the target image |
destination-atop | The target image is transparent and the source image is opaque. If there is an intersection between the target image and the source image, the target image is displayed in the communication part |
destination-in | Both the source image and the target image are transparent. Only the intersection of the target image and the source image is opaque and the target image is displayed |
destination-out | The target image is opaque and the source image is transparent. If there is an intersection between the target image and the source image, the intersection part of the image is transparent |
lighter | The source image and the target image are drawn on the canvas together. If there is an intersection between them, the colors will be superimposed |
copy | Only the source image is displayed on the canvas, and the target image is not displayed on the canvas |
xor | Both the source image and the target image are displayed in the canvas. If there is an intersection between them, the intersection part does not display the image |
example
<script> var canvas1 = document.querySelector("canvas"); var cvs = canvas1.getContext("2d"); cvs.fillStyle = "red"; cvs.fillRect(0,0,200,200); cvs.fillStyle = "pink"; cvs.fillRect(100,100,200,200); </script>
design sketch
cvs.globalCompositeOperation = "source-over";
cvs.globalCompositeOperation = "source-atop";
cvs.globalCompositeOperation = "source-in";
cvs.globalCompositeOperation = "source-out";
cvs.globalCompositeOperation = "destination-over";
cvs.globalCompositeOperation = "destination-atop";
cvs.globalCompositeOperation = "destination-in";
cvs.globalCompositeOperation = "destination-out";
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> </head> <style> .ggk { width: 250px; height: 150px; position: relative; } .content, #canvas_1 { width: 250px; height: 150px; text-align: center; line-height: 150px; position: absolute; left: 0; top: 0; } </style> <body> <div class="ggk"> <div class="content">the first prize</div> <canvas id="canvas_1" width="250" height="150"></canvas> </div> <script> var isDraw; var canvas1 = document.querySelector("canvas"); var cvs = canvas1.getContext("2d"); var ggk = document.querySelector("div"); var content = document.querySelector(".content"); cvs.fillStyle = "red"; cvs.fillRect(0, 0, 250, 150); cvs.font = "30px Microsoft YaHei "; cvs.fillStyle = "#fff"; cvs.fillText("Scraping card", 85, 80); canvas1.onmousemove = function(e) { if (isDraw) { var x = e.pageX - ggk.offsetLeft; var y = e.pageY - ggk.offsetTop; cvs.globalCompositeOperation = "destination-out" cvs.arc(x, y, 18, 0, 2 * Math.PI); cvs.fill(); } }; canvas1.onmousedown = function(e) { isDraw = true; console.log(e); }; canvas1.onmouseup = function(e) { isDraw = false; console.log(e); }; </script> </body> </html>
6, Sketchpad exercise
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> <link rel="stylesheet" href="../css/huaban.css" /> <link rel="stylesheet" href="../js study//font/hubanfont/iconfont.css" /> </head> <body> <div class="tool"> <div class="btn"><span class="iconfont icon-huaban"></span></div> <div class="btn"><span class="iconfont icon-juxingxuanze"></span></div> <div class="btn"> <span class="iconfont icon-xingzhuang-tuoyuanxing"></span> </div> <div class="btn"><span class="iconfont icon-xianduan"></span></div> <div class="btn"><input type="color" class="color"></span></div> <div class="btn"><span class="iconfont icon-bold "></span></div> <div class="btn"><span class="iconfont icon-xiangpica "></span></div> <div class="btn"><span class="iconfont icon-xiazai "></span></div> <div class="btn" hidden><a href="">xiazai</a></div> </div> <canvas id="canvas1"></canvas> <script> var canvas = document.querySelector("canvas"); var huabiBtn = document.querySelector(".btn:nth-child(1)"); var rectBtn = document.querySelector(".btn:nth-child(2)"); var circleBtn = document.querySelector(".btn:nth-child(3)"); var weightBtn = document.querySelector(".btn:nth-child(4)"); var colorbtnBtn = document.querySelector(".btn:nth-child(5)"); var jiacuBtn = document.querySelector(".btn:nth-child(6)"); var xiangpiBtn = document.querySelector(".btn:nth-child(7)"); var downloadBtn = document.querySelector(".btn:nth-child(8)"); var colorInput = document.querySelector(".color"); var btnList = document.querySelectorAll(".btn"); canvas.setAttribute("width", canvas.offsetWidth); canvas.setAttribute("height", canvas.offsetHeight); var cvs = canvas.getContext("2d"); var huanban = { imgData: null, beginX: 0, beginY: 0, lineWidth:6, color:"#333", type: "none", isDraw: false, huabiFn: function(e) { var x = e.pageX - canvas.offsetLeft; var y = e.pageY - canvas.offsetTop; cvs.strokeStyle = huanban.color; cvs.lineTo(x,y); cvs.lineWidth = huanban.lineWidth; cvs.stroke(); }, rectFn: function(e) { var x = e.pageX - canvas.offsetLeft; var y = e.pageY - canvas.offsetTop; cvs.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight); if(huanban.imgData != null){ cvs.putImageData(huanban.imgData,0,0,0,0,canvas.offsetWidth,canvas.offsetHeight); } cvs.beginPath(); cvs.strokeStyle = huanban.color; cvs.rect( huanban.beginX, huanban.beginY, x - huanban.beginX, y - huanban.beginY ); cvs.stroke(); cvs.closePath(); }, circleFn: function(e) { var x = e.pageX - canvas.offsetLeft; var y = e.pageY - canvas.offsetTop; cvs.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight); if(huanban.imgData != null){ cvs.putImageData(huanban.imgData,0,0,0,0,canvas.offsetWidth,canvas.offsetHeight); } cvs.beginPath(); cvs.strokeStyle = huanban.color; cvs.arc( huanban.beginX, huanban.beginY, y - huanban.beginY ,0, 2 * Math.PI ); cvs.stroke(); cvs.closePath(); }, }; function clearclass() { btnList.forEach(function(item,index){ for(var i=1;i<9;i++){ item.classList.remove("active"+i); } }) } huabiBtn.onclick = function() { clearclass(); huabiBtn.classList.add("active1"); huanban.type = "huabi"; }; rectBtn.onclick = function() { clearclass(); rectBtn.classList.add("active2"); huanban.type = "rect"; }; circleBtn.onclick = function() { clearclass(); circleBtn.classList.add("active3"); huanban.type = "circle"; }; weightBtn.onclick = function() { clearclass(); weightBtn.classList.add("active4"); }; colorbtnBtn.onclick = function() { clearclass(); colorbtnBtn.classList.add("active5"); }; colorInput.onchange = function(e){ huanban.color = colorInput.value; console.log(colorInput.value) } jiacuBtn.onclick = function(){ clearclass(); jiacuBtn.classList.add("active6"); } xiangpiBtn.onclick = function(){ clearclass(); xiangpiBtn.classList.add("active7"); cvs.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight); huanban.imgData = null; } downloadBtn.onclick = function(){ clearclass(); var hiddenxiazaia = document.querySelector(".btn a"); downloadBtn.classList.add("active8"); huanban.type = "download"; var url = canvas.toDataURL(); hiddenxiazaia.setAttribute("href",url); hiddenxiazaia.click() console.log(url) } canvas.onmousedown = function(e) { huanban.isDraw = true; var x = e.pageX - canvas.offsetLeft; var y = e.pageY - canvas.offsetTop; huanban.beginX = x; huanban.beginY = y; if (huanban.type == "huabi"){ cvs.beginPath(); cvs.moveTo(x,y); } }; canvas.onmousemove = function(e) { if (huanban.isDraw) { var strFn = huanban.type + "Fn"; huanban[strFn](e); } }; canvas.onmouseup = function() { huanban.imgData = cvs.getImageData(0,0,canvas.offsetWidth,canvas.offsetHeight); huanban.isDraw = false; if (huanban.type == "huabi"){ cvs.closePath(); } }; </script> </body> </html>