Task1(svg小练习)
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<rect x="20" y="20" width="250" height="150"
style="fill:blue;stroke:pink;stroke-width:5;
fill-opacity:0.1;stroke-opacity:0.9"/>
<circle cx="350" cy="50" r="40" stroke="black"
stroke-width="2" fill="yellow"/>
<line x1="0" y1="0" x2="500" y2="300"
style="stroke:rgb(99,99,99);stroke-width:2"/>
<polyline points="100,600 100,450 50,450 120,250 200,450 150,450 150,600"
style="fill:green;stroke:black;stroke-width:2"/>
<g transform="translate(100,100)">
<text id="TextElement" x="0" y="0" style="font-family:Verdana;font-size:50"> It's SVG!
<animateMotion path="M 0 0 L 200 200" dur="5s" fill="freeze"/>
</text>
</g>
</svg>
Task2(柱状图)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>IFE ECMAScript</title>
</head>
<body>
<div id="bar-wrapper">
</div>
<script type="text/javascript" src="bar.js"></script>
<script>
var data = [120, 100, 140, 160, 180, 185, 190, 210, 230, 245, 255, 270];
var bar = document.getElementById("bar-wrapper");
bar.innerHTML = getBar(data);
</script>
</body>
</html>
bar.js
function getBar(data) {
// 定义好柱状图绘制区域的高度,宽度,轴的高度,宽度
var w = 550,
h = 350,
axisX = 500,
axisY = 300,
startX = 25,
startY = 325;
// 定义好每一个柱子的宽度及柱子的间隔宽度
var barWidth = 32,
interval = 9;
// 定义好柱子颜色,轴的颜色
var barColor = "#0DAFF4",
axisColor = "rgb(0,99,99)";
// 拿到柱状图中的最大值Max
var max = data[0];
for (var i in data) {
if (data[i] > max) {
max = data[i];
}
}
// 根据Max和你用来绘制柱状图图像区域的高度,进行一个数据和像素的折算比例
var percent = 1;
var svgStart = '<svg width=' + w + ' height=' + h + ' version="1.1" xmlns="http://www.w3.org/2000/svg">';
var svgEnd = '</svg>';
// 绘制横轴及纵轴
var row = "<line x1=" + startX + " y1=" + startY + " x2=" + (startX + axisX) + " y2=" + startY + ' style="stroke:rgb(0,99,99);stroke-width:1"/>';
var col = "<line x1=" + startX + " y1=" + startY + " x2=" + startX + " y2=" + (startY - axisY) + ' style="stroke:rgb(0,99,99);stroke-width:1"/>';
// 遍历数据,计算将要绘制柱子的高度和位置,绘制每一个柱子
var svgT = svgStart + row + col;
for (let i = 0; i < data.length; i++) {
let rectStartX = startX + interval * (i + 1) + barWidth * i;
let rectStartY = startY - data[i];
var bar = "<rect x=" + rectStartX + " y=" + rectStartY + " width=" + barWidth + " height=" + data[i] + ' style="fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)"/>';
svgT += bar;
}
svgT += svgEnd;
return svgT;
}
Task3(Canvas小练习)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>IFE ECMAScript</title>
<style type="text/css">
canvas {
border: 1px solid black;
}
</style>
</head>
<body onload="draw()">
<canvas id="tutorial" width="300" height="150"></canvas>
<canvas id="tutorial2" width="300" height="150"></canvas>
<canvas id="tutorial3" width="300" height="150"></canvas>
<canvas id="tutorial4" width="300" height="150"></canvas>
<canvas id="tutorial5" width="300" height="150"></canvas>
<canvas id="tutorial6" width="300" height="150"></canvas>
<script type="text/javascript">
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.strokeRect(5, 5, 50, 50);
}
var canvas2 = document.getElementById('tutorial2');
if (canvas2.getContext) {
var ctx = canvas2.getContext('2d');
ctx.beginPath();
ctx.moveTo(25, 25);
ctx.lineTo(250, 125);
ctx.closePath();
ctx.strokeStyle = "blue";
ctx.stroke();
}
var canvas3 = document.getElementById('tutorial3');
if (canvas3.getContext) {
var ctx = canvas3.getContext('2d');
ctx.beginPath();
ctx.arc(150, 75, 50, 0, Math.PI * 2);
ctx.closePath();
ctx.fillStyle = "orange";
ctx.fill();
}
var canvas4 = document.getElementById('tutorial4');
if (canvas4.getContext) {
var ctx = canvas4.getContext('2d');
ctx.font = "32px consals";
ctx.fillText("Hello world", 10, 50);
}
var canvas6 = document.getElementById('tutorial6');
if (canvas2.getContext) {
var ctx = canvas6.getContext('2d');
ctx.beginPath();
ctx.lineWidth = 4;
ctx.moveTo(225, 130);
ctx.lineTo(75, 130);
ctx.quadraticCurveTo(20, 110, 85, 75);
ctx.quadraticCurveTo(90, 25, 135, 35);
ctx.quadraticCurveTo(150, 5, 185, 25);
ctx.quadraticCurveTo(230, 20, 240, 80);
ctx.quadraticCurveTo(275, 105, 225, 130);
ctx.closePath();
ctx.strokeStyle = "#000000";
ctx.stroke();
}
}
function clock() {
var now = new Date();
var ctx = document.getElementById('tutorial5').getContext('2d');
ctx.save();
ctx.clearRect(0, 0, 150, 150);
ctx.translate(75, 75);
ctx.scale(0.4, 0.4);
ctx.rotate(-Math.PI / 2);
ctx.strokeStyle = "black";
ctx.fillStyle = "white";
ctx.lineWidth = 8;
ctx.lineCap = "round";
// Hour marks
ctx.save();
for (var i = 0; i < 12; i++) {
ctx.beginPath();
ctx.rotate(Math.PI / 6);
ctx.moveTo(100, 0);
ctx.lineTo(120, 0);
ctx.stroke();
}
ctx.restore();
// Minute marks
ctx.save();
ctx.lineWidth = 5;
for (i = 0; i < 60; i++) {
if (i % 5 != 0) {
ctx.beginPath();
ctx.moveTo(117, 0);
ctx.lineTo(120, 0);
ctx.stroke();
}
ctx.rotate(Math.PI / 30);
}
ctx.restore();
var sec = now.getSeconds();
var min = now.getMinutes();
var hr = now.getHours();
hr = hr >= 12 ? hr - 12 : hr;
ctx.fillStyle = "black";
// write Hours
ctx.save();
ctx.rotate(hr * (Math.PI / 6) + (Math.PI / 360) * min + (Math.PI / 21600) * sec)
ctx.lineWidth = 14;
ctx.beginPath();
ctx.moveTo(-20, 0);
ctx.lineTo(80, 0);
ctx.stroke();
ctx.restore();
// write Minutes
ctx.save();
ctx.rotate((Math.PI / 30) * min + (Math.PI / 1800) * sec)
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(-28, 0);
ctx.lineTo(112, 0);
ctx.stroke();
ctx.restore();
// Write seconds
ctx.save();
ctx.rotate(sec * Math.PI / 30);
ctx.strokeStyle = "#D40000";
ctx.fillStyle = "#D40000";
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(-30, 0);
ctx.lineTo(83, 0);
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, 10, 0, Math.PI * 2, true);
ctx.fill();
ctx.beginPath();
ctx.arc(95, 0, 10, 0, Math.PI * 2, true);
ctx.stroke();
ctx.fillStyle = "rgba(0,0,0,0)";
ctx.arc(0, 0, 3, 0, Math.PI * 2, true);
ctx.fill();
ctx.restore();
ctx.beginPath();
ctx.lineWidth = 14;
ctx.strokeStyle = '#325FA2';
ctx.arc(0, 0, 142, 0, Math.PI * 2, true);
ctx.stroke();
ctx.restore();
window.requestAnimationFrame(clock);
}
window.requestAnimationFrame(clock);
</script>
</body>
</html>
Task4(折线图)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>IFE ECMAScript</title>
<style type="text/css">
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<div id="line-wrapper">
<canvas id="canvas"></canvas>
</div>
<script type="text/javascript" src="line.js"></script>
<script>
var data = [120, 100, 140, 160, 180, 185, 190, 210, 230, 245, 255, 270];
var line = document.getElementById("line-wrapper");
getLine(data);
</script>
</body>
</html>
line.js
function getLine(data) {
//定义好折线图绘制区域的高度,宽度,轴的高度,宽度
var w = 550,
h = 350,
axisX = 500,
axisY = 300,
startX = 10,
startY = 10;
//定义好每一个数据点的直径,颜色,线的颜色,宽度
var pDiameter = 5,
pColor = "#000000",
lColor = "#37A2DA",
lWidth = 2;
//定义好每两个数据点之间的横向间隔距离
var interval = 40;
//拿到折线图中的最大值Max
var max = data[0];
for (var i in data) {
if (data[i] > max) {
max = data[i];
}
}
//根据Max和你用来绘制折线图图像区域的高度, 进行一个数据和像素的折算比例
var pencent = 1;
//绘制横轴及纵轴
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
canvas.setAttribute("height", h);
canvas.setAttribute("width", w);
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(startX, startY + axisY);
ctx.lineTo(startX + axisX, startY + axisY);
ctx.strokeStyle = pColor;
ctx.stroke();
//遍历数据,计算将要绘制数据点的坐标,绘制数据点
ctx.moveTo(70, 350 - data[0]);
ctx.beginPath();
for (let i = 0; i < data.length; i++) {
let x = 15 + interval * (i + 1);
let y = axisY - data[i];
ctx.lineTo(x, y);
ctx.arc(x, y, pDiameter / 2, 0, Math.PI * 2);
ctx.strokeStyle = lColor;
ctx.stroke();
}
}
这一节下面还有几个task,包括让图表数据可变、绘制多条折线图、绘制多个柱状图,但是我没有继续做。原因是,我感觉接下来的练习已经偏离了练习svg和canvas的初衷。我们不必要去重复造轮子,将来画图表肯定是要用框架进行的。svg和canvas这两个元素,我们只要理解并掌握它们的原理和用法即可,再用它们做更多复杂的东西也不现实。