当前位置: 首页 > 文档资料 > HTML5 Canvas 实战 >

2.10 创建自定义图形:绘制扑克牌花色

优质
小牛编辑
127浏览
2023-12-01

如果皇家同花顺会让你兴奋不已,本节就是为你而写。本节,我们将创建一个组函数,用来绘制一套扑克牌中的黑桃、红桃、梅花、方块。

绘制扑克牌花色
图2-11 绘制扑克牌花色

绘制步骤

按照以下步骤,绘制一套扑克牌中的黑桃、红桃、梅花、方块:

1. 定义drawSpade()函数,该函数通过绘制四条贝塞尔曲线、两条二次曲线、一条直线,来绘制黑桃:

function drawSpade(context, x, y, width, height){
  context.save();
  var bottomWidth  = width  *  0.7;
  var topHeight    = height  *  0.7; 
  var bottomHeight = height  *  0.3;
  context.beginPath();
  context.moveTo(x, y);
  //黑桃的左上部分
  context.bezierCurveTo(
    x, y  + topHeight  /  2,  // control point  1
    x  - width  /  2, y  + topHeight  /  2,  // control point  2
    x  - width  /  2, y  + topHeight  // end point
  );
  //黑桃的左下部分
  context.bezierCurveTo(
    x  - width  /  2, y  + topHeight  *  1.3,  // control point  1
    x, y  + topHeight  *  1.3,  // control point  2 
    x, y  + topHeight  // end point
  );
  //黑桃的右下部分
  context.bezierCurveTo(
    x, y  + topHeight  *  1.3,  // control point  1
    x  + width  /  2, y  + topHeight  *  1.3,  // control point  2
    x  + width  /  2, y  + topHeight  // end point
   );
  //黑桃的右上部分
  context.bezierCurveTo(
    x  + width  /  2, y  + topHeight  /  2,  // control point  1
    x, y  + topHeight  /  2,  // control point  2 
    x, y  // end point
  );
  context.closePath();
  context.fill();
  //黑桃的底部
  context.beginPath();
  context.moveTo(x, y  + topHeight); 
  context.quadraticCurveTo(
    x, y  + topHeight  + bottomHeight,  // control point
    x  - bottomWidth  /  2, y  + topHeight  + bottomHeight  // end point
  );
  context.lineTo(x  + bottomWidth  /  2, y  + topHeight  + bottomHeight);
  context.quadraticCurveTo(
    x, y  + topHeight  + bottomHeight,  // control point
    x, y  + topHeight  // end point
  );
  context.closePath();
  context.fillStyle  = "black"; 
  context.fill();
  context.restore();
}

2. 定义drawHeart ()函数,该函数通过绘制四条贝塞尔曲线,来绘制红桃:

​
function drawHeart(context, x, y, width, height){
  context.save();
  context.beginPath();
  var topCurveHeight  = height  *  0.3;
  context.moveTo(x, y  + topCurveHeight);
  //左上侧的曲线
  context.bezierCurveTo(
    x, y,
    x  - width  /  2, y,
    x  - width  /  2, y  + topCurveHeight
  );
  //左下侧的曲线
  context.bezierCurveTo(
    x  - width  /  2, y  +  (height  + topCurveHeight)  /  2, x, y  +  (height  + topCurveHeight)  /  2, 
    x, y  + height
  );
  //右下侧的曲线
  context.bezierCurveTo(
    x, y  +  (height  + topCurveHeight)  /  2,
    x  + width  /  2, y  +  (height  + topCurveHeight)  /  2, x  + width  /  2, y  + topCurveHeight
  );
  //右上侧的曲线
  context.bezierCurveTo(
    x  + width  /  2, y,
    x, y,
    x, y  + topCurveHeight
  );
  context.closePath();
  context.fillStyle  = "red";
  context.fill();
  context.restore();
}
​

3. 定义drawClub ()函数,该函数通过绘制四个圆、两条二次曲线、一条直线,来绘制梅花:

function drawClub(context, x, y, width, height){
  context.save();
  var circleRadius  = width  *  0.3; 
  var bottomWidth   = width  *  0.5; 
  var bottomHeight  = height  *  0.35; 
  context.fillStyle = "black";
  // 顶部的圆
  context.beginPath();
  context.arc(
    x, y  + circleRadius  +  (height  *  0.05),
    circleRadius,  0,  2  * Math.PI, false
  );
  context.fill();
  //右下侧的圆
  context.beginPath();
  context.arc(
    x  + circleRadius, y  +  (height  *  0.6),
    circleRadius,  0,  2  * Math.PI, false
  );
  context.fill();
  //左下侧的圆
  context.beginPath();
  context.arc(
    x  - circleRadius, y  +  (height  *  0.6),
    circleRadius,  0,  2  * Math.PI, false
  );
  context.fill();
  //中央的填充圆
  context.beginPath();
  context.arc(
    x, y  +  (height  *  0.5),
    circleRadius  /  2,  0,  2  * Math.PI, false
  );
  context.fill();
  //梅花的底部
  context.moveTo(x, y  +  (height  *  0.6)); 
  context.quadraticCurveTo(
    x, y  + height,
    x  - bottomWidth  /  2, y  + height
  );
  context.lineTo(x  + bottomWidth  /  2, y  + height);
  context.quadraticCurveTo(
    x, y  + height,
    x, y  + (height  *  0.6)
  );
  context.closePath();
  context.fill();
  context.restore();
}

4. 定义drawDiamond ()函数,该函数通过绘制四条直线,来绘制方块:

function drawDiamond(context, x, y, width, height){
  context.save();
  context.beginPath();
  context.moveTo(x, y);
  //左上侧的边
  context.lineTo(x  - width  /  2, y  + height  /  2);
  //左下侧的边
  context.lineTo(x, y  + height);
  //右下侧的边
   context.lineTo(x  + width  /  2, y  + height  /  2);
  //闭合路径,自动创建右上侧的边
  context.closePath();
  context.fillStyle  = "red"; context.fill();
  context.restore();
}

5. 页面加载完成后,定义画布上下文,再调用四个绘制函数来渲染一个黑桃、一个红桃、一个梅花、一个方块:

window.onload  = function(){
  var canvas  = document.getElementById("myCanvas"); 
  var context = canvas.getContext("2d");
  drawSpade(context, canvas.width  *  0.2,  70,  75,  100);
  drawHeart(context, canvas.width  *  0.4,  70,  75,  100); 
  drawClub(context, canvas.width  *  0.6,  70,  75,  100);
  drawDiamond(context, canvas.width  *  0.8,  70,  75,  100); 
};

6. 在HTML文档的body部分嵌入canvas标签:

<canvas id="myCanvas" width="600" height="250" style="border:1px solid black;">
</canvas>

工作原理

本节演示如何通过组合HTML5画布提供的四类子路径(直线、圆弧、二次曲线、贝塞尔曲线),来绘制任意图形。

绘制黑桃,我们可以连接四条贝塞尔曲线形式其顶部,使用两条二次曲线和一条直线形成其底部。绘制红桃,跟绘制黑桃时几乎相同的方法连接四条贝塞尔曲线,不同点在底部而不是顶部。绘制梅花,可以通过三个圆来绘制顶部,跟黑桃相似,使用两条二次曲线和一条直线形成底部。最后,绘制方块,只需简单的连接四条直线即可。