• 【canvas】了解canvas,并实现会议预定记录钟表盘、页面水印


      初识canvas

    Canvas 有什么用

    Canvas 允许使用直线、曲线、矩形、圆形等基本图形绘制出复杂的图形

    Canvas 可以加载图像,并进行各种处理,如裁剪、缩放、旋转等操作

    Canvas 可以通过 JavaScript 控制,所以你可以利用帧动画原理,在画布上连续绘制图形,从而实现流畅的动画效果。

    Canvas 提供了强大的绘图能力,使得将复杂的数据以图表或图形的方式展示变得更加容易。你可以绘制柱状图、折线图、饼状图等,以直观的方式展示数据

    canvas 绘图基本步骤:

    • 建立canvas 画布
     <canvas id="canvas"></canvas>
    • 通过canvas 画布获取上下文对象

    上下文对象可以理解为画笔,画布建好了,然后再准备好画笔 是不是就可以开画拉

    1. const canvas = document.querySelector('#canvas')
    2. canvas.height = window.innerHeight
    3. canvas.width = window.innerWidth
    4. const ctx = canvas.getContext(‘2d’)
    • 设置画笔颜色与图形形状
    1. ctx.fillStyle = 'red'
    2. ctx.fillRect(0, 0, 500, 500)

    就完成一个最简单的绘制:

    使用用canvas绘制一个机器人头像:

    1. "robot" width="200" height="200">
    2. <script>
    3. const canvas = document.getElementById('robot');
    4. const ctx = canvas.getContext('2d');
    5. //fillStyle=>设置填充区域的颜色
    6. ctx.fillStyle = 'gray';
    7. //strokeStyle=>设置描边的颜色
    8. ctx.strokeStyle = 'black';
    9. //lineWidth=>设置描边的宽度
    10. ctx.lineWidth = 2;
    11. // 在Canvas绘图中,每个新的路径(line、rect、arc等)都会自动连接到之前绘制的路径上。如果希望绘制一个新的路径,就需要使用beginPath()方法来开启一个新路径
    12. ctx.beginPath();
    13. // 以 (x, y) 为圆心,半径为 r,从 startAngle 开始,到 endAngle 结束,画一个弧形
    14. ctx.arc(100, 100, 50, 0, Math.PI * 2);
    15. console.log(Math.PI) //3.1415926
    16. //对路径进行填充。
    17. ctx.fill();
    18. //对路径进行描边。
    19. ctx.stroke();
    20. // 画眼睛
    21. ctx.fillStyle = 'white';
    22. ctx.beginPath();
    23. ctx.arc(75, 70, 10, 0, Math.PI * 2);
    24. ctx.arc(125, 70, 10, 0, Math.PI * 2);
    25. ctx.fill();
    26. // 画瞳孔
    27. ctx.fillStyle = 'black';
    28. ctx.beginPath();
    29. ctx.arc(75, 70, 3, 0, Math.PI * 2);
    30. ctx.arc(125, 70, 3, 0, Math.PI * 2);
    31. ctx.fill();
    32. // 画嘴巴
    33. ctx.beginPath();
    34. ctx.moveTo(70, 130);
    35. ctx.bezierCurveTo(70, 140, 130, 140, 130, 130);
    36. ctx.stroke();
    37. // 画腮红
    38. ctx.fillStyle = 'pink';
    39. ctx.beginPath();
    40. ctx.arc(60, 110, 10, 0, Math.PI * 2);
    41. ctx.arc(140, 110, 10, 0, Math.PI * 2);
    42. ctx.fill();
    43. script>

    再识canvas

     W3C 坐标系

    canvas中的路径

    beginPath(): 这个方法用于开始一个新的路径,相当于重置了路径的起点和样式。

    closePath(): 这个方法将路径的最后一个点与路径起点连接,形成封闭的图形。

    moveTo(50, 100):起点坐标 (x, y)

    lineTo(200, 50):下一个点的坐标 (x, y)

    stroke(): 这个方法用于描边路径,将上面的坐标用一条线连接起来

    fill(): 这个方法用于填充路径所包围的区域,采用当前路径样式的设置(例如填充的颜色)

    样式 

    lineWidth:线的粗细

    strokeStyle:线的颜色

    lineCap:线帽:默认: butt; 圆形: round; 方形: square

    详细可看:Canvas 从入门到劝朋友放弃(图解版)✨ - 知乎

     效果图:

    创建一个动态的时间

    1. function updateTime() {
    2. var now = new Date();
    3. var today = now.toDateString();
    4. var time = now.toLocaleTimeString();
    5. var hours = now.getHours();
    6. var minutes = now.getMinutes();
    7. var seconds = now.getSeconds();
    8. var minutesString = minutes.toString().padStart(2, '0')
    9. var secondsString = seconds.toString().padStart(2, '0');
    10. var timeString = hours + ":" + minutesString + ":" + secondsString;
    11. $("h1").text(timeString);
    12. }
    13. updateTime()
    14. setInterval(updateTime, 1000);

    var minutesString = minutes.toString().padStart(2, '0')

    这段代码的作用是将分钟数和秒数转换为字符串,并在字符串长度不足2位时,在字符串前面填充0 

     有会议的时间段 绘制选中状态

    1. var canvas = document.getElementById("canvas");
    2. var ctx = canvas.getContext("2d");
    3. // 线条宽度、线条末端样式、阴影模糊度
    4. ctx.lineWidth = 15;
    5. ctx.lineCap = "round";
    6. ctx.shadowBlur = 15;
    7. // 将角度值转换为弧度值
    8. function degToRad(degree) {
    9. var factor = Math.PI / 180;
    10. return degree * factor;
    11. }
    12. // 转换数值 360度转换成24份,并修正从0点开始
    13. function convertNum(num) {
    14. return degToRad(num * 15 - 90);
    15. }
    16. function draw() {
    17. ctx.strokeStyle = "#42dfbf";
    18. ctx.shadowColor = '#95e0d1';
    19. // 创建了一个径向渐变对象
    20. gradient = ctx.createRadialGradient(100, 100, 50, 100, 100, 150);
    21. ctx.fillStyle = gradient;
    22. ctx.fillRect(0, 0, 400, 400);
    23. // 0点到3点
    24. // beginPath 开始一个新的绘图路径
    25. ctx.beginPath();
    26. // arc 方法绘制了一个弧线
    27. ctx.arc(200, 200, 170, convertNum(0), convertNum(4));
    28. // stroke 方法绘制出刻度线
    29. ctx.stroke();
    30. // 7到8
    31. ctx.beginPath();
    32. ctx.arc(200, 200, 170, convertNum(7), convertNum(8));
    33. ctx.stroke();
    34. // 14-16
    35. ctx.beginPath();
    36. ctx.arc(200, 200, 170, convertNum(14), convertNum(16));
    37. ctx.stroke();
    38. }
    39. draw();

    绘制时间刻度,固定刻度显示时间,其他显示原点

    1. var canvas = document.getElementById("canvas");
    2. var ctx = canvas.getContext("2d");
    3. // 线条宽度、线条末端样式、阴影模糊度
    4. ctx.lineWidth = 15;
    5. ctx.lineCap = "round";
    6. ctx.shadowBlur = 15;
    7. // 将角度值转换为弧度值
    8. function degToRad(degree) {
    9. var factor = Math.PI / 180;
    10. return degree * factor;
    11. }
    12. // 绘制表盘刻度线
    13. function drawClockFace() {
    14. ctx.shadowColor = '#40b7c6';
    15. ctx.strokeStyle = "#90bdc3";
    16. for (var i = 0; i < 24; i++) {
    17. var angle = degToRad(i * 15 - 90);
    18. ctx.beginPath();
    19. ctx.arc(200, 200, 170, angle, angle + degToRad(0.5));
    20. if (i % 3 === 0) {
    21. // 绘制文本
    22. ctx.save();
    23. ctx.translate(200, 200); // 将坐标原点移动到表盘中心
    24. ctx.rotate(angle + Math.PI / 2); // 旋转文本使其与刻度对齐
    25. ctx.textAlign = "center";
    26. ctx.font = "bold 20px Arial";
    27. ctx.fillStyle = "#fff";
    28. ctx.fillText(i.toString(), 0, -163); // 在指定位置绘制文本
    29. ctx.restore();
    30. } else {
    31. // 绘制圆点
    32. ctx.stroke();
    33. }
    34. }
    35. }
    36. drawClockFace();

    完整代码: 

    1. html>
    2. <html lang="zh-CN">
    3. <head>
    4. <meta charset="UTF-8" />
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    6. <title>Documenttitle>
    7. head>
    8. <style>
    9. body {
    10. background-color: gray;
    11. }
    12. .content {
    13. position: relative;
    14. display: flex;
    15. justify-content: center;
    16. }
    17. h1 {
    18. font-family: helvetica;
    19. font-size: 2.5rem;
    20. color: black;
    21. position: absolute;
    22. top: 38%;
    23. z-index: -1;
    24. }
    25. #canvas {
    26. display: block;
    27. margin: 5vh auto;
    28. border-radius: 50%;
    29. box-shadow: 0 5px 14px black;
    30. }
    31. style>
    32. <body>
    33. <div class="content">
    34. <h1>h1>
    35. <canvas id="canvas" width="400" height="400">canvas>
    36. div>
    37. body>
    38. <script src="https://cdn.staticfile.org/jquery/3.7.1/jquery.js">script>
    39. <script>
    40. var canvas = document.getElementById("canvas");
    41. var ctx = canvas.getContext("2d");
    42. // 线条宽度、线条末端样式、阴影模糊度
    43. ctx.lineWidth = 15;
    44. ctx.lineCap = "round";
    45. ctx.shadowBlur = 15;
    46. // 将角度值转换为弧度值
    47. function degToRad(degree) {
    48. var factor = Math.PI / 180;
    49. return degree * factor;
    50. }
    51. // 绘制表盘刻度线
    52. function drawClockFace() {
    53. ctx.shadowColor = '#40b7c6';
    54. ctx.strokeStyle = "#90bdc3";
    55. for (var i = 0; i < 24; i++) {
    56. var angle = degToRad(i * 15 - 90);
    57. ctx.beginPath();
    58. ctx.arc(200, 200, 170, angle, angle + degToRad(0.5));
    59. if (i % 3 === 0) {
    60. // 绘制文本
    61. ctx.save();
    62. ctx.translate(200, 200); // 将坐标原点移动到表盘中心
    63. ctx.rotate(angle + Math.PI / 2); // 旋转文本使其与刻度对齐
    64. ctx.textAlign = "center";
    65. ctx.font = "bold 20px Arial";
    66. ctx.fillStyle = "#fff";
    67. ctx.fillText(i.toString(), 0, -163); // 在指定位置绘制文本
    68. ctx.restore();
    69. } else {
    70. // 绘制圆点
    71. ctx.stroke();
    72. }
    73. }
    74. }
    75. draw();
    76. drawClockFace();
    77. // 转换数值 360度转换成24份,并修正从0点开始
    78. function convertNum(num) {
    79. return degToRad(num * 15 - 90);
    80. }
    81. function draw() {
    82. ctx.strokeStyle = "#42dfbf";
    83. ctx.shadowColor = '#95e0d1';
    84. function updateTime() {
    85. var now = new Date();
    86. var today = now.toDateString();
    87. var time = now.toLocaleTimeString();
    88. var hours = now.getHours();
    89. var minutes = now.getMinutes();
    90. var seconds = now.getSeconds();
    91. var minutesString = minutes.toString().padStart(2, '0')
    92. var secondsString = seconds.toString().padStart(2, '0');
    93. var timeString = hours + ":" + minutesString + ":" + secondsString;
    94. $("h1").text(timeString);
    95. }
    96. updateTime()
    97. setInterval(updateTime, 1000);
    98. // 创建了一个径向渐变对象
    99. gradient = ctx.createRadialGradient(100, 100, 50, 100, 100, 150);
    100. ctx.fillStyle = gradient;
    101. ctx.fillRect(0, 0, 400, 400);
    102. // 0点到3点
    103. // beginPath 开始一个新的绘图路径
    104. ctx.beginPath();
    105. // arc 方法绘制了一个弧线
    106. ctx.arc(200, 200, 170, convertNum(0), convertNum(4));
    107. // stroke 方法绘制出刻度线
    108. ctx.stroke();
    109. // 7到8
    110. ctx.beginPath();
    111. ctx.arc(200, 200, 170, convertNum(7), convertNum(8));
    112. ctx.stroke();
    113. // 14-16
    114. ctx.beginPath();
    115. ctx.arc(200, 200, 170, convertNum(14), convertNum(16));
    116. ctx.stroke();
    117. }
    118. script>
    119. html>

    动态添加水印 

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    6. <title>Documenttitle>
    7. head>
    8. <body>
    9. <div id="content" style="width: 400px;height: 400px;background-color: antiquewhite;">
    10. 你好
    11. div>
    12. <script>
    13. /**
    14. * 动态添加水印
    15. * @param {String} str 水印内容
    16. */
    17. function addWaterMark(str) {
    18. const body = document.getElementById('content');
    19. const canvas = document.createElement('canvas');
    20. body.appendChild(canvas);
    21. canvas.width = 200;
    22. canvas.height = 200;
    23. canvas.style.display = 'none';
    24. var cans = canvas.getContext('2d');
    25. cans.rotate((-20 * Math.PI) / 180);
    26. cans.font = '12px Microsoft JhengHei';
    27. cans.fillStyle = 'rgba(17, 17, 17, 1)';
    28. cans.textAlign = 'left';
    29. cans.textBaseline = 'Middle';
    30. // 表示在 上绘制一段文本,起始位置为左上角的 (30, 105),并且文本的最大宽度限制为 200。水印的文本内容将会从 (30, 105) 开始,并在指定的最大宽度内绘制
    31. cans.fillText(str, 0, 130, 200);
    32. body.style.backgroundImage = 'url(' + canvas.toDataURL('image/png') + ')';
    33. }
    34. addWaterMark("阿晨出品 必然精品")
    35. script>
    36. body>
    37. html>

  • 相关阅读:
    10.1作业
    短视频矩阵系统源代码开发搭建分享--代码开源SaaS
    【基础篇】三、SpringBoot基础配置
    【数据结构】二叉树详解
    Vue 监听store数据变化
    Qt Quick Controls 2如何自定义样式
    Unity碰撞检测(3D和2D)
    【ArcGIS】基于DEM/LUCC等数据统计得到各集水区流域特征
    谈谈讲清楚这件事的重要性
    关于使用GB28181协议实现与大华摄像机的语音对讲功能小记
  • 原文地址:https://blog.csdn.net/weixin_52479803/article/details/134504888