canvas画圆
为什么需要用canvas,如果用onmousemove
,每一次移动都会进行DOM重绘,非常消耗性能,这时我们需要看一下 canvas
< div id = " canvas" > </ div>
< script>
canvas. onmousemove = ( e ) => {
let div = document. createElement ( "div" ) ;
div. style. position = "absolute" ;
div. style. left = e. clientX + "px" ;
div. style. top = e. clientY + "px" ;
div. style. width = "6px" ;
div. style. height = "6px" ;
div. style. marginLeft = "-3px" ;
div. style. marginRight = "-3px" ;
div. style. borderRadius = "50%" ;
div. style. backgroundColor = "black" ;
canvas. appendChild ( div) ;
}
</ script>
我们现在已经给 canvas 设置一屏宽高,但还是出现滚动条,原因是 canvas 是 inline 元素,设置宽高不起作用,所以需要把它转换成块级元素(不要这样做,这样做会拉伸元素 )
< canvas id = " canvas" > </ canvas>
< style>
#canvas {
height : 100vh;
width : 100vw;
border : 1px solid red;
}
</ style>
<canvas>
标签只有两个属性**——** width
和height
,可以使用 JS 设置canvas 宽高,这里不能直接给 canvas 设置 height: 100vh;
width: 100vw;
let canvas = document. getElementById ( "canvas" ) ;
canvas. width = document. documentElement. clientWidth;
canvas. height = document. documentElement. clientHeight;
let painting = false ;
let ctx = canvas. getContext ( "2d" ) ;
ctx. fillStyle = "black" ;
ctx. strokeStyle = "none" ;
canvas. onmousedown = ( e ) => {
painting = true ;
}
canvas. onmousemove = ( e ) => {
if ( painting === true ) {
ctx. beginPath ( ) ;
ctx. arc ( e. clientX, e. clientY, 10 , 0 , 2 * Math. PI ) ;
ctx. stroke ( ) ;
ctx. fill ( )
}
}
canvas. onmouseup = ( ) => {
painting = false ;
}
Canvas
颜色、样式和阴影
线条样式
矩形
路径
转换
文本
图像绘制
像素操作
属性 描述 width 返回 ImageData 对象的宽度 height 返回 ImageData 对象的高度 data 返回一个对象,其包含指定的 ImageData 对象的图像数据
Canvas练习
绘制圆形和文本
ctx. beginPath ( ) ;
ctx. moveTo ( 50 , 50 ) ;
ctx. lineTo ( 50 , 300 ) ;
ctx. lineTo ( 300 , 100 ) ;
ctx. closePath ( ) ;
ctx. lineCap = "round" ;
ctx. lineJoin = "round"
ctx. strokeStyle = "aqua" ;
ctx. lineWidth = 20 ;
ctx. stroke ( )
ctx. arc ( 300 , 300 , 100 , 0 , 2 * Math. PI , true ) ;
ctx. fillStyle = "bisque" ;
ctx. fill ( ) ;
ctx. stroke ( ) ;
ctx. font = "50px sans-serif"
var x = 1200 ;
setInterval ( function ( ) {
ctx. clearRect ( 0 , 0 , 1200 , 1200 ) ;
x -= 10 ;
if ( x <= 0 ) {
x = 1200 ;
}
ctx. fillText ( "hello" , x, 100 ) ;
ctx. strokeText ( "world" , x, 200 ) ;
} , 40 )
绘制图形
var img = new Image ( ) ;
img. src = "./imgs/2.jpg" ;
img. onload = function ( ) {
ctx. drawImage ( img, 50 , 100 , 480 , 270 ) ;
}
var img2 = new Image ( ) ;
img2. src = "./imgs/3.jpg" ;
img2. onload = function ( ) {
ctx. drawImage ( img2, 400 , 400 , 480 , 270 , 100 , 400 , 480 , 270 ) ;
}
var video = document. querySelector ( "video" ) ;
var interval = null ;
video. onplay = function ( ) {
interval = setInterval ( function ( ) {
ctx. drawImage ( video, 0 , 800 , 800 , 400 )
} , 32 )
}
video. onpause = function ( ) {
clearInterval ( interval) ;
}
绘制时钟
ES6版本参考这个(附带效果):https://github.com/llwodexue/clock
let canvas1 = document. querySelector ( "#canvas1" ) ;
let ctx = canvas1. getContext ( "2d" ) ;
ctx. clearRect ( 0 , 0 , 800 , 600 ) ;
ctx. save ( ) ;
ctx. translate ( 400 , 300 ) ;
ctx. rotate ( - Math. PI / 2 ) ;
ctx. beginPath ( ) ;
ctx. arc ( 0 , 0 , 200 , 0 , 2 * Math. PI ) ;
ctx. strokeStyle = "darkgrey" ;
ctx. lineWidth = 10 ;
ctx. stroke ( ) ;
ctx. closePath ( ) ;
function renderClock ( ) {
ctx. clearRect ( 0 , 0 , 800 , 600 ) ;
ctx. save ( ) ;
ctx. translate ( 400 , 300 ) ;
ctx. rotate ( - Math. PI / 2 ) ;
ctx. beginPath ( ) ;
ctx. arc ( 0 , 0 , 200 , 0 , 2 * Math. PI ) ;
ctx. strokeStyle = "darkgrey" ;
ctx. lineWidth = 10 ;
ctx. stroke ( ) ;
ctx. closePath ( ) ;
function drawLine ( { count, start, end, width, color } ) {
let i = 0 ;
for ( ; i < count; i++ ) {
ctx. beginPath ( ) ;
ctx. rotate ( ( 2 * Math. PI ) / count) ;
ctx. moveTo ( start, 0 ) ;
ctx. lineTo ( end, 0 ) ;
ctx. lineWidth = width;
ctx. strokeStyle = color;
ctx. stroke ( ) ;
ctx. closePath ( ) ;
}
}
drawLine ( {
count: 60 ,
start: 180 ,
end: 190 ,
width: 2 ,
color: "orangered" ,
} ) ;
drawLine ( {
count: 12 ,
start: 180 ,
end: 200 ,
width: 10 ,
color: "darkgrey" ,
} ) ;
let time = new Date ( ) ;
let min = time. getMinutes ( ) ;
let sec = time. getSeconds ( ) ;
let hour = time. getHours ( ) ;
hour = hour > 12 ? hour - 12 : hour;
ctx. save ( ) ;
ctx. beginPath ( ) ;
ctx. rotate ( ( ( 2 * Math. PI ) / 60 ) * sec) ;
ctx. moveTo ( - 30 , 0 ) ;
ctx. lineTo ( 170 , 0 ) ;
ctx. lineWidth = 2 ;
ctx. strokeStyle = "red" ;
ctx. stroke ( ) ;
ctx. closePath ( ) ;
ctx. restore ( ) ;
ctx. save ( ) ;
ctx. beginPath ( ) ;
ctx. rotate ( ( ( 2 * Math. PI ) / 60 ) * min + ( ( 2 * Math. PI ) / 3600 ) * sec) ;
ctx. moveTo ( - 20 , 0 ) ;
ctx. lineTo ( 150 , 0 ) ;
ctx. lineWidth = 4 ;
ctx. strokeStyle = "darkblue" ;
ctx. stroke ( ) ;
ctx. closePath ( ) ;
ctx. restore ( ) ;
ctx. save ( ) ;
ctx. beginPath ( ) ;
ctx. rotate (
( ( 2 * Math. PI ) / 12 ) * hour +
( ( 2 * Math. PI ) / 12 / 60 ) * min +
( ( 2 * Math. PI ) / 12 / 60 / 60 ) * sec
) ;
ctx. moveTo ( - 10 , 0 ) ;
ctx. lineTo ( 130 , 0 ) ;
ctx. lineWidth = 6 ;
ctx. strokeStyle = "darkgrey" ;
ctx. stroke ( ) ;
ctx. closePath ( ) ;
ctx. restore ( ) ;
ctx. beginPath ( ) ;
ctx. arc ( 0 , 0 , 10 , 0 , 2 * Math. PI ) ;
ctx. fillStyle = "deepskyblue" ;
ctx. fill ( ) ;
ctx. closePath ( ) ;
ctx. restore ( ) ;
}
setInterval ( function ( ) {
renderClock ( ) ;
} , 1000 ) ;
Canvas 绘图板
绘图板参考(附带效果): https://github.com/llwodexue/canvas_painting
参考
Fira Code | 为写程序而生的字体
Canvas教程
Detecting touch screen devices with Javascript
HTML 5 Canvas 参考手册