Day2
今日份内容:canvas画布——用于在网页上绘制图形。
HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像。
画布是一个矩形区域,可以控制其每一像素。
canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。
canvas
- 绘图原理
- canvas元素及坐标系
- 曲线的绘制
- 形状与文本的绘制
- 渐变
内容
字体、图形、线条、柱状图、渐变、像素、风车
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>this is canvas</title>
</head>
<body>
<style type="text/css">
canvas{
display: block;
border: 1 solid #A4A4A4;
border-radius: 5;
box-shadow: 1 2 #555555;
}
mycvs{
display: block;
}
</style>
<div class="mycvs">
<canvas id="myCanvas" width="300px" height="200px"></canvas>
</div>
<div class="mycvs">
<canvas id="myCanvas1" width="300px" height="200px"></canvas>
</div>
<div class="mycvs">
<canvas id="myCanvas2" width="200px" height="150px"></canvas>
</div>
<div class="mycvs">
<canvas id="myCanvas3" width="300" height="200"></canvas>
</div>
<div class="mycvs">
<canvas id="myCanvas4" width="320" height="100"></canvas>
</div>
<div class="mycvs">
<canvas id="myCanvas5" width="320" height="150"></canvas>
</div>
<div class="mycvs">
<canvas id="myCanvas6" width="440" height="220"></canvas>
</div>
<div class="mycvs">
<canvas id="myCanvas7" width="300" height="220"></canvas>
</div>
<div class="mycvs">
<canvas id="myCanvas9" width="240px" height="120px"></canvas>
</div>
<script>
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d")
context.strokeStyle = "#cc8866";
context.lineWidth = 6;
context.strokeRect(30,30,150,100);
</script>
<!-- 设置渐变字体 -->
<script type="text/javascript">
var c = document.getElementById("myCanvas1");
var ctx = c.getContext("2d");
//设置字体大小样式
ctx.font = "60px Verdana";
//创建渐变
//创建线性渐变对象
var gradient = ctx.createLinearGradient(0,0,c.width,0);
//颜色渐变结束位置
gradient.addColorStop("0","magenta");
gradient.addColorStop("0.5","blue");
//用渐变色填充
gradient.addColorStop("1.0","red");
//设置返回笔触的颜色,渐变或模式
ctx.strokeStyle = gradient;
//绘制文本(文本,开始x坐标,开始y坐标。最大文本宽度可选);
ctx.strokeText("Big smile!",10,70);
</script>
<script>
var canvas = document.getElementById("myCanvas2");
var context = canvas.getContext("2d");
context.fillStyle = "#cc8866";
context.fillRect("0,0,canvas.width,canvas.height");
var url = canvas.toDataURL();
var newImg = document.createElement("img");
newImg.src = url;
document.body.appendChild(newImg);
</script>
<!-- 绘制矩形 -->
<script type="text/javascript">
var canvas = document.getElementById("myCanvas3");
var context = canvas.getContext("2d");
var x = 70 , y = 20;
for (var i = 0; i < 6; i++) {
for (var j = 0 ; j < 6 ; j++){
context.fillStyle = 'rgb('+Math.floor(255-42.5*i)+','+Math.floor(255-42.5*j)+',100)';
context.fillRect(x+j*25,y+i*25,24,24);
}
}
</script>
<!-- 绘制文本 -->
<script type="text/javascript">
var c = document.getElementById("myCanvas4");
var ctx = c.getContext("2d");
var txt = "Cuckoo-Online";
var x = 20,y = 20,height = 55;
ctx.fillStyle = "lightgray";
ctx.font = height + "px Giddyup Std";
var mTxt = ctx.measureText(txt);
//绘制文字背景区域
ctx.fillRect(x,y,mTxt.width,height);
//设置画笔颜色
ctx.strokeStyle = '#662266';
//设置画笔大小
ctx.lineWidth = 2;
ctx.lineJoin = "bevel";
ctx.textBaseline = "top";
ctx.strokeText(txt,x,y);
</script>
<!-- 绘制路径 -->
<script type="text/javascript">
var canvas = document.getElementById("myCanvas5");
var context = canvas.getContext("2d");
var y = 30;
var lineCaps = ["round","butt","square"];
context.strokeStyle = "darkgreen";
for (var i = 0; i < lineCaps.length; i++) {
context.lineWidth = 15;
context.lineCap = lineCaps[i]
//起始一条路径
context.beginPath();
//将路径移至指定点,不创建线条
context.moveTo(50,y+i*40);
//添加一个新点,然后在画布中创建从该点到最后指定点的线条
context.lineTo(250,y+i*40);
//绘制已定义的路径
context.stroke();
//创建从当前点回到起始点的路径
//context.closePath();
}
</script>
<script type="text/javascript">
var canvas = document.getElementById("myCanvas6");
var context = canvas.getContext("2d");
var data = [80,60,90,40,180,80,120,150,60,20];
var fillStyle = ["#ffb90f","#ff69b4","#8470ff","#98fb98","#848484"];
var width = 20;
var margin = 20;
var start = 20;
var base = 200;
context.strokeStyle = '#662266';
context.lineWidth = 2;
for(var i in data){
if(i<data.length/2){
context.fillStyle = fillStyle[i];
context.save();
}else{
context.restore();
}
context.beginPath();
context.rect(start + i * (width + margin) , base , width , -data[i]);
context.fill();
context.stroke();
context.fillText(data[i],start + i * (width + margin) , base , width , -data[i]-10);
context.closePath();
}
context.moveTo(start-10 , base+3);
context.lineTo(start + (width+margin)*data.length,base+3);
context.stroke();
</script>
<script type="text/javascript">
var canvas = document.getElementById("myCanvas7");
var context = canvas.getContext("2d");
drawScreen();
function drawScreen(){
var x = canvas.width/2;
var y = canvas.height/2;
var radius = 75;
var offset = 120;
//裁剪的区域以(x,y)为中心的半径为75的圆
context.save();
context.beginPath();
context.arc(x,y,radius,0,2*Math.PI,false);
context.clip();
//先画一个蓝色的弧,超过裁剪的部分不显示
context.beginPath();
context.arc(x - offset * 4 / 6 , y - offset * 2 / 6 , radius , 0 , 2 * Math.PI , false);
context.fillStyle = '#b4cdcd'
context.fill();
//画一个黄色的圆弧,超过裁剪的部分不显示
context.beginPath();
context.arc(x+offset*2/3,y-offset/3,radius,0,2*Math.PI,false);
context.fillStyle = '#ee9a00';
context.fill();
//画一个红色的圆弧,超过裁剪的部分不显示
context.beginPath();
context.arc(x,y+offset*7/9,radius,0,2*Math.PI,false);
context.fillStyle = 'red';
context.fill();
context.restore();
context.beginPath();
context.arc(x,y,radius,0,2*Math.PI,false);
context.lineWidth = '#698b22';
context.stroke();
}
</script>
<!-- 绘制图像 -->
<!-- <canvas id="myCanvas8" width="570px" height="220px"></canvas> -->
<script type="text/javascript">
var width = 100;
var height = 130;
var canvas = document.getElementById("myCanvas8");
var getContext = canvas.getContext("2d");
var img = new Image();
context.fillStyle = "#8b4513";
context.font = "20px 楷体";
img.src = "images4/girl-little.jpg";
//绘制一幅图像
img.onload = function(){
context.drawImage(img,10,10);
context.fillText("原图",50,205);
//图像整体缩小
context.drawImage(img,140,10,80,120);
context.fillText("整体缩小",140,160);
//从原图中进行裁剪,等比例绘制
context.drawImage(img,10,10,width,height,230,10,width,height);
context.fillText("等比例裁剪",230,170);
//从原图中进行裁剪,1.3倍放大
context.drawImage(img,10,10,width,height,340,10,width*1.3,height*1.3);
context.fillText("裁剪放大",363,200);
//从原图中裁剪,0.8倍缩小
context.drawImage(img,10,10,width,height,480,10,width*0.8,height*0.8);
context.fillText("裁剪缩小",480,140);
};
</script>
<!-- 像素处理 -->
<script type="text/javascript">
var canvas = document.getElementById("myCanvas9");
var context = canvas.getContext("2d");
//创建一个新的空白的 imageData对象
var imageData = context.createImageData(100,100);
for(var i=0;i<imageData.data.length;i++){
imageData.data[i] = Math.floor(Math.random()*255);
}
var imageData2 = context.createImageData(imageData);
//绘制边框
context.strokeStyle = '#33001b';
context.lineWidth = 2;
context.strokeRect(6,6,imageData.width+4,ImageData.height+4);
context.strokeRect(imageData.width+20,6,imageData2.width+4,imageData2.height+4);
//将imageData数据绘制到画布中
context.putImageData(imageData,8,8);
context.putImageData(imageData2,122,8);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>this is canvas</title>
</head>
<body>
<style type="text/css">
canvas {
display: flex;
border: 1 solid #A4A4A4;
border-radius: 5;
box-shadow: 1 2 #555555;
}
.button{
width: 200px;
height: 30px;
background-color: blanchedalmond;
border-radius: 10px;
font-style: inherit;
}
input{
padding: 10px;
}
</style>
<div id="b1">
<canvas id="myCanvas" width="702" height="150"></canvas>
<input id="yuantu" type="button" value="原图" onclick="showNormalImage()" />
</div>
<div id="b4">
<div id="b2">
<input type="button" value="红色通道" onclick="showChannel('red',100)" />
<input type="range" id="redRange" min="0" max="100" step="1" value="100"
oninput="showChannel('red',this.value)" />
</div>
<div id="b2">
<input type="button" value="绿色通道" onclick="showChannel('green',100)" />
<input type="range" id="greenRange" min="0" max="100" step="1" value="100"
oninput="showChannel('green',this.value)" />
</div>
<div id="b2">
<input type="button" value="蓝色通道" onclick="showChannel('blue',100)" />
<input type="range" id="blueRange" min="0" max="100" step="1" value="100"
oninput="showChannel('blue',this.value)" />
</div>
<div id="b2">
<input type="button" value="半透明" onclick="showChannel('transparent',100)" />
<input type="range" id="transparentRange" min="0" max="100" step="1" value="100"
oninput="showChannel('transparent',this.value)" />
</div>
</div>
<div id="b3">
<input type="button" value="反向显示" onclick="showChannel('reverse',100)" />
<input type="button" value="水印效果" onclick="showChannel('watermark',100)" />
<input type="button" value="清空画布" onclick="clearCanvas()" />
</div>
<script type="text/javascript">
function showNormalImage() {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.clearRect(0, 0, 100, 150);
var img = new Image();
img.src = 'images4/Claire-little.jpg'
img.onload = function() {
context.drawImage(img, 0, 0);
}
}
function showChannel(channel, percentage) {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var x = 0,
y = 0;
var img = new Image();
img.src = "images4/Claire-little.jpg";
var quantity = 255;
if (percentage != "") {
quantity = percentage * 255 / 100;
}
img.onload = function() {
context.drawImage(img, 0, 0);
var imageData = context.getImageData(0, 0, img.width, img.height);
var num = imageData.data.length;
for (var i = 0; i < num; i = i + 4) {
if (channel == 'red') {
imageData.data[i + 0] = quantity;
x = 100;
} else if (channel == 'green') {
imageData.data[i + 1] = quantity;
x = 200;
} else if (channel == 'blue') {
imageData.data[i + 2] = quantity;
x = 300;
} else if (channel == 'transparent') {
imageData.data[i + 3] = quantity;
x = 400;
} else if (channel == 'reverse') {
imageData.data[i + 0] = 255 - imageData.data[i + 0];
imageData.data[i + 1] = 255 - imageData.data[i + 1];
imageData.data[i + 2] = 255 - imageData.data[i + 2];
x = 500;
}
}
context.putImageData(imageData, x, y);
if (channel == 'watermark') {
context.putImageData(imageData, 600, y);
context.fillStyle = "#33001b";
context.font = "45px Giddyup Std";
context.textBaseline = "top";
context.fillText("Claire", 610, y + 90)
}
};
}
function clearCanvas() {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.clearRect(0, 0, canvas.width, canvas.height);
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>图形渐变</title>
</head>
<body>
<style type="text/css">
canvas{
display: block;
border: 1 solid #A4A4A4;
border-radius: 5;
box-shadow: 1 2 #555555;
}
</style>
<canvas id="myCanvas" width="230px" height="230px"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("myCanvas");
//风车叶子颜色,颜色的种类决定风车叶子数量
var color = ["#ff0000","#eeee00","#0000ff","#00ff00","#a020f0","#adff2f"];
//整个风车半径
var radius = 50;
//风车叶子半径
var wheelRadius = 50;
//PI/2分成几份
var part = 50;
//获取上下文
var context = canvas.getContext("2d");
//叶子数量
var num = color.length;
//绘图区域中心
var center = {x:canvas.width/2,y:canvas.height/2};
//叶子原点位置
var point;
//绘制叶子的开始角
var start = 0;
var angle = 0;
//绘制叶子结束角
var end = Math.PI;
//两个相邻叶子之间角度
var offset = Math.PI*(360/num)/180;
//每次旋转角度
rotateAngle = offset/part;
function drawWindmill(){
context.clearRect(0,0,canvas.width,canvas.height);
for(var i = 0;i < num; i++){
//开始绘制叶子
context.beginPath();
//创建径向渐变
var wheelGradient = context.createRadialGradient(center.x,center.y,100,center.x,center.y,0);
//起始颜色
wheelGradient.addColorStop(0,color[i]);
//结束颜色
wheelGradient.addColorStop(1,"#000");
//填充渐变样式
context.fillStyle = wheelGradient;
//叶子圆心位置
point = {
x:center.x+Math.cos(offset*i+angle)*radius,
y:center.y+Math.sin(offset*i+angle)*radius,
};
//绘制叶子开始角
var x = start + offset * i;
//绘制叶子结束角
var y = end + offset * i;
//绘制
context.arc(point.x,point.y,wheelRadius,x,y,false);
//填充
context.fill();
//结束绘制
context.closePath();
}
context.beginPath();
var dotGradient = context.createRadialGradient(center.x,center.y,0,center.x,center.y,40);
dotGradient.addColorStop(0,"#fff");
dotGradient.addColorStop(1,"#666");
context.fillStyle = dotGradient;
context.arc(center.x,center.y,25,0,2*Math.PI,false);
context.fill();
context.closePath();
angle += rotateAngle;
start = angle;
end = Math.PI + angle;
requestAnimationFrame(drawWindmill);
}
drawWindmill();
</script>
</body>
</html>
结果
PS
还有一些曲线绘制出来也挺好玩,这里就省略咯。