HTML5 canvas绘图基础(电子名片生成器源码)

创建canvas

  <canvas id="myCanvas" class="canvas">
您的浏览器不支持canvas
</canvas>

基础设置

    <script type="text/javascript">
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
canvas.width=100;
canvas.height=100;
</script>

画直线
moveTo(x1, y1)
lineTo(x2, y2)

    ctx.moveTo(0, 0);
ctx.lineTo(100, 100);
ctx.stroke();

画圆形
ctx.arc(x,y,radius,0,2*Math.PI,true)

    ctx.beginPath();
ctx.arc(300,300,50,0,2*Math.PI,true);
ctx.strokeStyle = '#000';
ctx.stroke();

画矩形
ctx.strokeRect(x1, y1,x2, y2)

    ctx.strokeRect(300,100,200,100);

beginPath()开始一条新路径
closePath()使当前路径闭合
不是成对出现的

      ctx.beginPath();
ctx.moveTo(300, 0);
ctx.lineTo(200, 100);
ctx.lineTo(200, 200);
ctx.closePath();
ctx.strokeStyle = '#0F0';
ctx.stroke();

设置样式

      ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.lineTo(100,200);
ctx.closePath();
//lineWidth 设置描边的线宽
ctx.lineWidth = 10;
//strokeStyle 设置描边样式
ctx.strokeStyle = "#F00";
ctx.stroke();
//fillStyle 设置填充样式
ctx.fillStyle = "rgba(0,255,0,0.5)";
ctx.fill();

绘制矩形与样式同步

      ctx.strokeRect(100,200,100,100);
ctx.fillRect(100,200,100,100);

保存和恢复上下文环境,一般成对出现
save 保存当前绘画环境,包括变换和样式
restore 恢复当前绘画环境,包括变换和样式

   ctx.save();
ctx.restore();

图形变换

      //translate 平移变换
ctx.translate(0,100);
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.stroke(); //rotate 旋转变换
ctx.rotate(Math.PI/4);
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.lineWidth = 5;
ctx.strokeStyle = "#F00";
ctx.stroke(); //scale 缩放变换
ctx.scale(1,0.5);
ctx.fillRect(0,-100,100,100);

线性渐变

        var linearGradient = ctx.createLinearGradient(0, 0, 200, 0);
//给渐变添加颜色
linearGradient.addColorStop(0, 'rgb(255,0,0)');
linearGradient.addColorStop(0.3, 'rgb(0,255,0)');
linearGradient.addColorStop(1, 'rgb(0,0,255)');
//设置渐变作为样式
ctx.fillStyle = linearGradient;
ctx.fillRect(0, 0, 200, 200);

径向渐变

        var radialGradient = ctx.createRadialGradient(400, 50, 0, 400, 150, 100);
radialGradient.addColorStop(0, 'rgb(255,255,0)');
radialGradient.addColorStop(1, 'rgb(0,0,0)');
ctx.fillStyle = radialGradient;
ctx.beginPath();
ctx.arc(400, 150, 100, 0, Math.PI * 2, true);
ctx.fill();

文字

字体若设置了居中,圆心会在文字的中间位置,所以圆心还是要根据画布大小和文字的宽度进行设置。

        var str = "hello world";
//设置文本样式,比如大小,字体
ctx.font = "50px sans-serif";
//水平对其设置,left center right
ctx.textAlign = "center";
//垂直对齐设置,top middle bottom
ctx.textBaseline = "top";
//填充文本
ctx.fillText(str,300,0);
//描边文本
ctx.strokeText(str,0,200);
//获取文本宽度
var width = ctx.measureText(str).width;
console.log(width);

图片

        ctx.fillRect(0, 0, canvas.width, canvas.height);
var img = new Image();
img.src = "logo.png";
//一定要在图像加载完成后的回调中绘制图像
img.onload = function () {
//在(0,0)点处绘制img图像
// ctx.drawImage(img, 0, 0);
//在(0,0)点处绘制img图像,缩放成256*80
// ctx.drawImage(img, 0, 0, 256, 80);
//获取img图像的(0,0)点处的40*40区域,绘制在(100,100)点处,缩放成80*80
ctx.drawImage(img, 0, 0, 40, 40, 100, 100, 80, 80);
}

创建图像画刷ctx.createPattern(image, type)

        ctx.fillRect(0, 0, canvas.width, canvas.height);
var img = new Image();
img.src = "logo.png";
img.onload = function () {
//创建图像画刷,no-repeat,repeat-x,repeat-y,repeat
var pattern = ctx.createPattern(img, "repeat");
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}

阴影绘制

        //阴影的X偏移
ctx.shadowOffsetX = 10;
//阴影的Y偏移
ctx.shadowOffsetY = 10;
//阴影的颜色
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
//阴影的模糊度
ctx.shadowBlur = 10;
ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
ctx.fillRect(100, 100, 100, 100); ctx.font = "50px sans-serif";
ctx.fillText("我是小可爱",200,100);

区域剪辑

    //保存当前环境
ctx.save();
ctx.arc(300, 100, 200, 0, Math.PI*2, true);
//进行区域剪辑
ctx.clip();
ctx.fillStyle = "#F00";
ctx.fillRect(100, 100, 200, 200);
//恢复环境,释放了剪辑区域的作用
ctx.restore();

绘制曲线ctx.arc(x, y, startAngle, endAngle ,Math.PI*2, true)
最后一个参数代表是否是逆时针方向

        //绘制圆弧
ctx.arc(100, 100, 50, 0 ,Math.PI*2, true);
ctx.fill(); //二次样条曲线ctx.quadraticCurveTo(qcpx,qcpy,qx,qy)
ctx.beginPath();
ctx.moveTo(100,355);
ctx.quadraticCurveTo(265,145,380,349);
ctx.fill(); //贝塞尔曲线ctx.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y)
ctx.beginPath();
ctx.moveTo(175,375);
ctx.bezierCurveTo(297,182,468,252,517,380);
ctx.fill();

canvas绘制曲线生成工具
两次贝塞尔曲线:
http://blogs.sitepointstatic.com/examples/tech/canvas-curves/quadratic-curve.html
三次贝塞尔曲线:
http://blogs.sitepointstatic.com/examples/tech/canvas-curves/bezier-curve.html


动画

ctx.clearRect(x, y, width, height) 清除区域,用于重新绘制

        var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var posx = 0, posy = 0, dir = 1, isMouseInRect = false; // 确定动画范围
canvas.onmousemove = function(e){
var mouseX = e.offsetX;
var mouseY = e.offsetY;
if(mouseX > posx && mouseY <posx +50 && mouseY > posy && mouseY < posy+ 50){
isMouseInRect = true;
}else{
isMouseInRect = false;
}
} // 开始动画
setInterval(function() {
if(!isMouseInRect){
posx += 10 * dir;
}
//clearRect清空画布的一个矩形区域
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(posx, posy, 50, 50);
if(posx + 50 >= canvas.width){
dir = -1;
}else if(posx <= 0){
dir = 1;
}
},100);

离屏技术
把canvas(sx,sy)处宽sw,高sy的区域,绘制到(dx,dy)处,并缩放为宽dx,高dh
ctx.drawImage(canvas,sx,sy,sw,sh,dx,dy,dw,dh)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>canvas</title>
<style type="text/css">
canvas {
border: 1px solid red;
}
#offCanvas{
display: none;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="600px" height="400px">
您的浏览器不支持canvas
</canvas>
<!--创建离屏Canvas-->
<canvas id="offCanvas" width="600px" height="400px">
您的浏览器不支持canvas
</canvas>
<script type="text/javascript">
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d'); var offCanvas = document.getElementById('offCanvas');
var offCtx = offCanvas.getContext('2d'); var posx = 0, posy = 0, dir = 1, isMouseInRect = false; //把一些复杂的绘画操作,画在离屏Canvas上面
var drawALot = function(){
for(var k=0; k<20; k++){
for(var i=0;i<canvas.width;i+=10){
for(var j=0;j<canvas.height;j+=10){
offCtx.beginPath();
offCtx.arc(i,j,5,0,2*Math.PI,true);
offCtx.stroke();
}
}
}
} canvas.onmousemove = function(e){
var mouseX = e.offsetX;
var mouseY = e.offsetY;
if(mouseX > posx && mouseY <posx +50 && mouseY > posy && mouseY < posy + 50){
isMouseInRect = true;
}else{
isMouseInRect = false;
}
} setInterval(function() {
if(!isMouseInRect){
posx += 10 * dir;
}
//clearRect清空画布的一个矩形区域
ctx.clearRect(0, 0, canvas.width, canvas.height);
// drawALot();
//真正要用到复杂的绘画的时候,直接从离屏Canvas上拷贝过来
ctx.drawImage(offCanvas,0,0,offCanvas.width, offCanvas.height,0,0, canvas.width, canvas.height);
ctx.fillRect(posx, posy, 50, 50);
if(posx + 50 >= canvas.width){
dir = -1;
}else if(posx <= 0){
dir = 1;
}
},100); drawALot();
</script>
</body>
</html>

案例:电子名片生成器

HTML5 canvas绘图基础(电子名片生成器源码)

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>电子名片生成器</title>
<link href="style/style.css" rel="stylesheet" />
</head>
<body>
<div class="left-div">
<div class="line">
<input id="name" type="text" placeholder="姓名"/>
</div>
<div class="line">
<input id="address" type="text" placeholder="地址"/>
</div>
<div class="line">
<input id="job" type="text" placeholder="职业"/>
</div>
<div class="line">
<input id="slogan" type="text" placeholder="口号" />
</div>
<div class="line">
<button id="generateBtn">生成名片</button>
</div>
</div>
<div class="right-div">
<canvas id="cardCanvas">
您的浏览器不支持Canvas,请升级浏览器
</canvas>
<canvas id="animCanvas">
您的浏览器不支持Canvas,请升级浏览器
</canvas>
</div>
<script src="script/main.js"></script>
</body>
</html>

style.css

* {
margin:;
padding:;
}
html, body {
height: 100%;
}
.left-div {
width: 30%;
height: 100%;
float: left;
background: #a4a296;
}
.line {
text-align: center;
margin-top: 30px;
}
.line:first-child {
margin-top: 200px;
}
.line span {
color: white;
}
.line input {
width: 300px;
height: 30px;
border-radius: 15px;
padding-left: 15px;
outline: none;
border: none;
}
.line button {
width: 100px;
height: 30px;
outline: none;
border: none;
background: #222;
color: #DDD;
cursor: pointer;
position: relative;
border-radius: 15px;
}
.line button:hover {
background: #000;
color: #FFF;
}
.line button:active {
left: 1px;
top: 1px;
}
.right-div {
width: 70%;
height: 100%;
float: left;
background: #eee9d3;
text-align: center;
position: relative;
}
.right-div canvas {
position: absolute;
top: 200px;
left: 50%;
margin-left: -300px;
}
#cardCanvas {
display: none;
}

main.js

// 创建和设置cardCanvas,该canvas作为离屏canvas
var cardCanvas = document.getElementById('cardCanvas');
var cardCtx = cardCanvas.getContext('2d');
cardCtx.canvas.width = 600;
cardCtx.canvas.height = 100; // 加载图片
var img = new Image();
img.src = "images/logo.png";
img.onload = function() {
cardCtx.drawImage(img, 10, 10);
} var generateBtn = document.getElementById("generateBtn");
generateBtn.onclick = function() {
cardCtx.clearRect(0, 0, cardCtx.canvas.width, cardCtx.canvas.height);
// 背景的线性渐变
var linearGradient = cardCtx.createLinearGradient(0, 0, cardCtx.canvas.width, cardCtx.canvas.height);
linearGradient.addColorStop(0.5, 'rgb(0,0,0)');
linearGradient.addColorStop(1, 'rgb(133,133,133)');
cardCtx.fillStyle = linearGradient;
cardCtx.fillRect(0, 0, cardCtx.canvas.width, cardCtx.canvas.height);
// logo图像
cardCtx.drawImage(img, 10, 10);
// 获取姓名、地址、职业,绘制,并计算长度
var name = document.getElementById("name").value || "请输入姓名";
var address = document.getElementById("address").value || "请输入地址";
var job = document.getElementById("job").value || "请输入职业";
var nameWidth, addressWidth, jobWidth, maxWidth = 0;
cardCtx.font = "bold 30px sans-serif";
cardCtx.fillStyle = "#fff";
cardCtx.fillText(name, 105, 35);
nameWidth = cardCtx.measureText(name).width;
cardCtx.font = "bold 20px sans-serif";
cardCtx.fillText(address, 105, 60);
cardCtx.fillText(job, 105, 85);
addressWidth = cardCtx.measureText(address).width;
jobWidth = cardCtx.measureText(job).width;
if(maxWidth < nameWidth) {
maxWidth = nameWidth;
}
if(maxWidth < addressWidth) {
maxWidth = addressWidth;
}
if(maxWidth < jobWidth) {
maxWidth = jobWidth;
}
// 绘制口号
var slogan = document.getElementById("slogan").value || "请输入口号";
cardCtx.save();
// 做图形变换
cardCtx.rotate(-0.1);
cardCtx.translate(0, 50);
// 阴影
cardCtx.shadowOffsetX = 10;
cardCtx.shadowOffsetY = 10;
cardCtx.shadowColor = 'rgba(0, 0, 0, 0.5)';
cardCtx.shadowBlur = 1.5;
cardCtx.fillStyle = "#ddd";
// 计算口号位置
var solganWidth;
solganWidth = cardCtx.measureText(slogan).width;
var offset = (cardCtx.canvas.width - 115 - maxWidth - solganWidth) / 2;
cardCtx.fillText(slogan, 115 + maxWidth + offset, 50);
// 画曲线
cardCtx.beginPath();
cardCtx.moveTo(115 + maxWidth + offset, 70);
cardCtx.quadraticCurveTo(115 + maxWidth + offset, 50, 115 + solganWidth + maxWidth + offset, 60);
cardCtx.strokeStyle = "#ddd";
cardCtx.stroke();
cardCtx.restore();
}
// 触发click事件
generateBtn.click(); // 创建和设置animCanvas,该canvas才是真正的显示
var animCanvas = document.getElementById('animCanvas');
var animCtx = animCanvas.getContext('2d');
animCtx.canvas.width = 600;
animCtx.canvas.height = 100; var circles = [];
setInterval(function() {
// 擦出画布
animCtx.clearRect(0, 0, animCtx.canvas.width, animCtx.canvas.height);
// 把离屏canvas的内容画进来
animCtx.drawImage(cardCanvas, 0, 0, animCtx.canvas.width, animCtx.canvas.height,
0, 0, cardCtx.canvas.width, cardCtx.canvas.height);
// 绘制下落的圆形
for(var i=0; i<=10; i++) {
if(!circles[i]) {
circles[i] = {};
circles[i].radius = Math.floor(Math.random() * 5) + 1;
circles[i].y = - circles[i].radius - Math.floor(Math.random() * 10);
circles[i].x = i * 60 + Math.floor(Math.random() * 10) - 5;
circles[i].vy = Math.floor(Math.random() * 5) + 1;
}
animCtx.beginPath();
animCtx.arc(circles[i].x, circles[i].y, circles[i].radius, 0, Math.PI * 2);
animCtx.fillStyle = "rgba(255, 255, 255, 0.5)";
animCtx.fill();
circles[i].y = circles[i].y + circles[i].vy;
if(circles[i].y > animCtx.canvas.height + circles[i].radius * 2) {
circles[i] = undefined;
}
}
}, 100);

案例:山中明月风景图

HTML5 canvas绘图基础(电子名片生成器源码)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
<style>
canvas{background-color:#000;opacity:0.7}
</style>
</head>
<body>
<canvas id="canvas" width="720px" height="600px">您的浏览器不支持canvas</canvas>
<script>
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d"); // 月亮绘制
context.shadowOffsetX=10;
context.shadowOffsetY=10;
context.shadowBlur=5;
context.shadowColor='rgba(255,255,255,0.2)';
context.fillStyle='yellow';
context.arc(100,100,40,0,Math.PI*2,true);
context.fill(); // 文字绘制
context.beginPath();
var str='山高月小';
context.font='50px 宋体';
context.fillStyle='#fff';
context.shadowColor='rgba(255,255,255,0.4)';
context.fillText(str,400,200); // 山峰绘制
context.beginPath();
context.lineWidth=5;
context.strokeStyle='lightblue';
context.moveTo(14, 600);
context.quadraticCurveTo(60, 193, 123, 600);
context.stroke(); context.beginPath();
context.moveTo(298, 600);
context.bezierCurveTo(81, 193, 73, 691, 100, 600);
context.stroke(); context.beginPath();
context.moveTo(500, 600);
context.bezierCurveTo(451, 34, 273, 361, 298, 600);
context.stroke(); context.beginPath();
context.moveTo(452, 600);
context.bezierCurveTo(569, 210, 695, 426, 715, 600);
context.stroke(); </script>
</body>
</html>
上一篇:[html5] canvas 绘图:八卦图


下一篇:别再抱怨了,国内这么多优秀的Android资源你都知道吗?