h5新增元素,通過js腳本來繪製圖形
<canvas> 對出現,默認width:300px height:150px 畫布的高寬不要再css中去指定
替換內容,瀏覽器不支持canvas,會正常顯示
需要找到它的渲染上下文,通過getContext(‘2d’)方法
canvas中畫,只有矩形是原生的圖形繪製。
繪製矩形
在css中不支持小數像素。
同步思維,有別於瀏覽器本身渲染機制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
}
body{
background-color:burlywood;
}
#test{
background-color: azure;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
margin: auto;
}
</style>
</head>
<body>
<canvas id="test" width="300" height="300">
<span>不支持畫布元素,請您換成萌萌谷歌</span>
</canvas>
</body>
<script>
window.onload = function(){
var canvas = document.getElementById('test')
if(canvas.getContext){
var ctx = canvas.getContext("2d");//模式 2d
ctx.fillStyle = 'pink' //填充顏色
ctx.strokeStyle = 'blue'//邊框色
ctx.lineWidth = 5//邊框寬度
//樣式
ctx.lineJoin = bevel//round miter
//獲得渲染上下文和他的功能參數2d
ctx.fillRect(0,0,100,100) //填充的矩形
ctx.strokeRect(100,100,100,50)//邊框矩形
//在【偏移量處往上畫0.5,往下0.5
ctx.clearRect(100,100,100,100)//清楚這個區域內的矩形
//覆蓋渲染
}
}
</script>
</html>
繪製路徑
圖形的基本元素是路徑,路徑是不通道額顏色和寬度的線段或曲線相連成的不同形狀的點的集合
路徑封閉以後就可以通過渲染和填充來操作區域
moveTo&lineTo
moveTo會擡起畫筆,lineTo不會繼續畫
<script>
window.onload = function(){
var canvas = document.getElementById('test')
if(canvas.getContext){
var ctx = canvas.getContext("2d");//模式 2d
ctx.strokeStyle = 'green'
ctx.fillStyle = 'pink'
ctx.lineWidth = 4
ctx.moveTo(50,50)//起始點
ctx.lineTo(50,100)
ctx.lineTo(100,100)
ctx.lineTo(50,50)
ctx.closePath() //閉合路徑
ctx.stroke()//線 --》不會自動合併路徑closePath
// ctx.fill()//填充 會自動合併路徑
ctx.beginPath()//清空路徑容器
ctx.moveTo(100,100)//起始點
ctx.lineTo(150,100)
ctx.lineTo(150,150)
ctx.lineTo(100,100)
ctx.stroke()
ctx.fill()
//直接畫矩形
ctx.rect(10,10,50,50)
ctx.fill()
ctx.beginPath()//清空路徑容器
ctx.moveTo(300,300)//起始點
ctx.lineTo(400,400)
ctx.lineCap = 'round' //square 線段末端以不同的形狀結束
}
}
</script>
save&restore
棧結構,先進後出
路徑容器:每次調用路徑api時,都會往路徑容器裏做登記,調用beginPath時,清空整個路徑容器
樣式容器:沒戲調用樣式api時,都會往樣式容器中做登記,調用save時候,將容器裏的狀態壓入樣式棧,調用restore時候,將樣式棧棧頂狀態彈出到樣式容器裏,進行覆蓋
樣式棧:調用save時,將樣式容器中的狀態壓入樣式棧,調用restore時候,將樣式棧的棧頂狀態彈出到樣式容器中,進行覆蓋
一個save對應一個restore:成對出現
save:報尺寸當前的一個狀態:strokeStyle fillstyle lineWidth lineCap lineJoin
restore:彈出棧頂相關的狀態
繪製曲線
window.onload = function(){
var canvas = document.getElementById('test')
if(canvas.getContext){
var ctx = canvas.getContext("2d");//模式 2d
//圓
ctx.beginPath()
ctx.moveTo(100,100)
ctx.arc(100,100,50,0,270*Math.PI/180,true)
// x,y圓心座標, 半徑, 開始弧度,結束弧度,順逆時針
ctx.closePath()//自動合併路徑
ctx.stroke()
//圓弧
ctx.beginPath()
ctx.moveTo(50,150)
ctx.arcTo(100,100,200,200,50)//三個點確定一個圓弧
ctx.closePath()//自動合併路徑
ctx.stroke()
//二次貝塞爾
ctx.beginPath()
ctx.moveTo(50,150)
ctx.quadraticCurveTo(200,0,200,200)
ctx.closePath()//自動合併路徑
ctx.stroke()
//三次貝塞爾
ctx.beginPath()
ctx.moveTo(50,150)
ctx.bezierCurveTo(200,0,200,200,300,100)
ctx.closePath()//自動合併路徑
ctx.stroke()
}
}
變換
放大:使畫布內css像素的個數變少,單個css像素所佔據的實際物理尺寸變大
縮小:使畫布內css像素的個數變多,單個css像素所佔據的實際物理尺寸變小
<script>
window.onload = function(){
var canvas = document.getElementById('test')
if(canvas.getContext){
var ctx = canvas.getContext("2d");//模式 2d
//translate(x,y) 移動canvas原點到不同的位置
ctx.translate(100,200)//在canvas會有累加操作,相當於寫了兩次原點的位置
ctx.beginPath()
ctx.fillRect(0,0,100,100)
//rotate(angle) 旋轉的角度 順時針
ctx.rotate(45*Math.PI/180)//累加的,按照原點旋轉
ctx.fillRect(0,0,100,100)
//scale(x,y) 對形狀,位圖進行縮放
ctx.scale(.5,.2)
//css像素是一個抽像的單位
//放大:css像素的面積 區域內css像素的個數變少
//縮小:css像素的面積 區域被css像素的個數變多
}
}
</script>
變換實例
<script>
window.onload = function(){
var flag = 0
var scale = 0
var flagScale = 0
var canvas = document.getElementById('test')
if(canvas.getContext){
var ctx = canvas.getContext("2d");//模式 2d
ctx.save()
ctx.translate(150,150)//原點的位置
ctx.beginPath()
ctx.fillRect(-50,-50,100,100)
ctx.restore()
setInterval(function(){
flag++
ctx.clearRect(0,0,canvas.width,canvas.height)
ctx.save()
ctx.translate(150,150)
ctx.rotate(flag*Math.PI/180)
//放大旋轉
if(scale==100){
flagScale = -1
}else if(scale==0){
flagScale = 1
}
scale+=flagScale
ctx.scale(scale/50,scale/50)
ctx.beginPath()
ctx.fillRect(-50,-50,100,100)
ctx.restore()
})
}
}
</script>
canvas使用圖片
使用圖片確定圖片完成後纔可以操作。
<script>
window.onload = function(){
var canvas = document.getElementById('test')
if(canvas.getContext){
var ctx = canvas.getContext("2d");//模式 2d
var img = new Image();
img.src = "img/企業微信截圖_158428260222.png";
img.onload = function(){
draw();
}
function draw(){
//引入圖片
// ctx.drawImage(img,10,10,img.width,img.height)
//圖片用作背景
// var pattern = ctx.createPattern(img,'no-repeat')//repeat no-repeat repeat-x repeat-y
// ctx.fillStyle = pattern;
// ctx.fillRect(0,0,300,300)
//線性漸變
var gradient = ctx.createLinearGradient(0,0,300,300)
gradient.addColorStop(0,"red")
gradient.addColorStop(0.5,"blue")
gradient.addColorStop(1,"yellow")
ctx.fillStyle = gradient;
ctx.fillRect(0,0,300,300)
//徑向漸變
var gradient = ctx.createRadialGradient(150,150,50,50,150,150)
gradient.addColorStop(0,"red")
gradient.addColorStop(0.5,"blue")
gradient.addColorStop(1,"yellow")
ctx.fillStyle = gradient;
ctx.fillRect(0,0,300,300)
}
}
}
</script>
使用圖片做一個飛鳥相關的動畫
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
}
body{
background-color:burlywood;
}
#test{
background-color:white;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
margin: auto;
}
</style>
</head>
<body>
<canvas id="test" width="300" height="300"></canvas>
</body>
<script>
window.onload = function(){
var canvas = document.getElementById('test')
canvas.width = document.documentElement.clientWidth//設置畫布大小
canvas.height = document.documentElement.clientHeight
if(canvas.getContext){
var ctx = canvas.getContext('2d')
var flag = 0//更改圖片
var value = 0//刷新圖片出現的位置
setInterval(function(){
ctx.clearRect(0,0,canvas.width,canvas.height)//每次清空前面的圖片
value+=10
flag++;
if(flag==9){
flag=1
}
var img = new Image()//引入圖片
img.src = "img/q_r"+(flag)+".jpg"
img.onload = function(){
draw(this)//加載完成以後畫圖
}
},100)
function draw(img){
ctx.drawImage(img,value,0)//圖片和要放的位置
}
}
}
</script>
</html>
文本繪製
font屬性在指定時,必須要有大小和字體(只有一種字體,sans-serif)
right center left 文本居中左對齊右對齊 center的時候文本的居中是在fillText所給的值,一般在x的右邊一半在x的左邊
ctx.textAlign = 'center'
文本的水平垂直居中操作 fillText設置元素的(畫布尺寸-元素尺寸)/2
<script type="text/javascript">
window.οnlοad=function(){
var canvas =document.getElementById("test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.font = "60px sans-serif"//只有一種字體
ctx.fillStyle = 'green'
//right center left 文本居中左對齊右對齊 center的時候文本的居中是在fillText所給的值,一般在x的右邊一半在x的左邊
ctx.textAlign = 'center'
//文本的基線 top middle bottom
ctx.textBaseline = 'top'
ctx.fillText('ss',100,111)
ctx.strokeText('ss',200,200)
var obj =ctx.measureText('ss')//返回一個包含文本尺寸的信息對象 ,必須包含一個參數
//文本的水平垂直居中
}
}
</script>
像素操作
直接通過imageDate對象操縱像素數據,直接讀取或將數據數組寫入該對象中
imageDate:
width:橫向像素點的個數 height:縱向像素點的個數
data:數組,每一個像素點的rgba信息 --->canvas透明度0-->255
<script type="text/javascript">
window.οnlοad=function(){
var canvas =document.getElementById("test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.fillRect(0,0,100,100)
//40000個像素點,
var imageDate = ctx.getImageDate(0,0,100,100)//拿到區域內的信息
for(var i=0;i<imageDate.data.length;i++){
imageDate.data[4*i+3] = 100//改變透明度
}
ctx.putImageDate(imageDate,0,0)
//創建一個新的ImageDate對象
ctx.createImageDate(100,100)//默認創建的是一個rgba(0,0,0,0)黑色
}
}
</script>
單像素操作
<script type="text/javascript">
window.οnlοad=function(){
var canvas =document.getElementById("test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.save()
ctx.fillStyle = "green"
ctx.beginPath()
ctx.fillRect(0,0,100,100)
ctx.restore()
var ImageDate = ctx.getImageData(0,0,canvas.width,canvas.height)
var color = getPxInfo(ImageDate,12,12)
console.log(color)
//改變一行像素的顏色
for(var i = 0;i<ImageDate.width;i++){
setPxInfo(ImageDate,i,45,[0,0,0,255])//
}
ctx.putImageData(ImageDate,0,0)
//知道偏移量改變單個像素
}
function getPxInfo(ImageDate,x,y){
var color = [];
var data = ImageDate.data;
var w = ImageDate.width
var h = ImageDate.height
color[0] = data[(y*w+x)*4+0]
color[1] = data[(y*w+x)*4+1]
color[2] = data[(y*w+x)*4+2]
color[3] = data[(y*w+x)*4+3]
return color;
}
function setPxInfo(ImageDate,x,y){
var color = [];
var data = ImageDate.data;
var w = ImageDate.width
var h = ImageDate.height
data[(y*w+x)*4+0] = color[0]
data[(y*w+x)*4+1] = color[1]
data[(y*w+x)*4+2] = color[2]
data[(y*w+x)*4+3] = color[3]
}
}
</script>
全局透明度設置
globalAlpha = (0-1)
合成
ctx.globalCompositeOperation = 'source-over'
source-in只留下源於目標重疊的部分(源的那一部分)
source-out只留下源超過目標的部分
source-atop 砍掉源溢出的部分
destination-over 目標在上面
destination-in 只留下源於目標重疊的部分(目標的那一部分)
destination-out:只留下超過源的部分
destination-atop:砍掉目標溢出的部分
<script type="text/javascript">
window.onload = function(){
var canvas = document.getElementById('test')
if(canvas.getContext){
var ctx = canvas.getContext('2d')
//ctx.globalCompositeOperation = 'source-over'//源在上面
ctx.fillStyle = 'pink'
//ctx.globalAlpha = 0.5;//全局透明度設置
ctx.fillRect(0,0,100,100)
ctx.globalCompositeOperation = 'source-in'
ctx.fillStyle = 'green'
ctx.fillRect(50,50,100,100)
}
}
</script>
others
1.將畫布導出爲圖像
canvas.toDataURL();
2.給canvas加事件
ctx.isPointInPath(x,y)
<script type="text/javascript">
window.οnlοad=function(){
var canvas =document.getElementById("test");
//var result = canvas.toDataURL();
if(canvas.getContext){
var ctx = canvas.getContext("2d")
ctx.arc(100,100,50,0,360*Math.PI/180)
ctx.fill()
ctx.beginPath()
ctx.arc(200,200,50,0,360*Math.PI/180)
ctx.fill()
canvas.onclick = function(ev){
ev = ev||event //解決兼容問題
var x = ev.clientX - canvas.offsetLeft//獲取鼠標的座標
var y = ev.clientY - canvas.offsetTop
if(ctx.isPointInPath(x,y)){
alert(123)
}
}
}
}
</script>