Openlayers基础教程|从前端框架到GIS开发系列课程(25)Canvas结合openlayers绘制画、实现动画效果

Arc绘制圆 

绘制弧线 

arc(x, y, r, startAngle, endAngle, anticlockwise): 以(x, y) 为圆心,以r 为半径,从 startAngle 弧度开始到endAngle弧 度结束。

anticlosewise 是布尔值,true 表示逆时针,false 表示顺时针(默认是顺时针)。

注意:

这里的度数都是弧度。

0 弧度是指的 x 轴正方向。

radians=(Math.PI/180)*degrees //角度转换成弧度

下面我们来尝试绘制圆

绘制圆

image.png

1.1设置canvas元素

  <canvas id="canvas" width="200" height="200"></canvas>    <script>

1.2获取canvas画布

 /* 获取canvas画布 */        const canvas = document.getElementById("canvas");

1.3获取绘制对象

  /* getContext获取绘制对象 */        const ctx = canvas.getContext("2d");

1.4设置圆的参数

  /* arc(x,y,radius,startAngle,endAngle) */        ctx.arc(50, 50, 50, 0, Math.PI * 2);        ctx.closePath();        ctx.stroke();

完整代码示例:

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title></head><body>    <canvas id="canvas" width="200" height="200"></canvas>    <script>        /* 获取canvas画布 */        const canvas = document.getElementById("canvas");        /* getContext获取绘制对象 */        const ctx = canvas.getContext("2d");        ctx.beginPath();        /* arc(x,y,radius,startAngle,endAngle) */        ctx.arc(50, 50, 50, 0, Math.PI * 2);        ctx.closePath();        ctx.stroke();    </script></body></html>

绘制两个圆

image.png

2.1 第一个圆:

 /* 第一个圆 */        ctx.beginPath();        ctx.arc(200, 200, 100, 0, Math.PI * 2);        ctx.closePath();        ctx.fillStyle = "#ff2d51";        ctx.fill();

2.2 第二个圆

 /* 第二个圆 */        ctx.beginPath();        ctx.arc(200, 200, 50, 0, Math.PI * 2);        ctx.closePath();        ctx.fillStyle = "#333";        ctx.fill();

完整代码示例:

​​

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title></head><body>    <canvas id="canvas" width="400" height="400"></canvas>    <script>        /* 100 50 */        const canvas = document.getElementById("canvas");        const ctx = canvas.getContext("2d");        /* 第一个圆 */        ctx.beginPath();        ctx.arc(200, 200, 100, 0, Math.PI * 2);        ctx.closePath();        ctx.fillStyle = "#ff2d51";        ctx.fill();        /* 第二个圆 */        ctx.beginPath();        ctx.arc(200, 200, 50, 0, Math.PI * 2);        ctx.closePath();        ctx.fillStyle = "#333";        ctx.fill();    </script></body></html>

绘制动画圆

3.1 绘制动画圆

动画圆.gif

3.1.1使用setInterval实现动画圆

在 JavaScript 中,setInterval 函数用于按照指定的周期(以毫秒计)来调用一个函数或执行一个代码片段。它返回一个间隔的ID,之后可以用于 clearInterval 函数来停止执行该函数setInterval 被用来每隔20毫秒执行一次 draw 函数。这个 draw 函数负责在 canvas 上绘制一个圆形,并且动态地改变圆的半径。

主要实现步骤:
  1. var canvas = document.getElementById("canvas");获取页面上的 canvas 元素。

  2. const ctx = canvas.getContext("2d");获取 canvas 的 2D 绘图上下文。

  3. var radius = 50;初始化圆的半径为50。

  4. var increase = true;初始化一个布尔值,用来控制半径的增减。

  5. function draw() { ... }定义了一个 draw函数,该函数首先清除 canvas,然后绘制一个圆,并且根据 increase的值来增加或减少半径。

  6. setInterval(() => { draw() }, 20) 设置一个定时器,每隔20毫秒调用一次 draw 函数。

示例代码:
<body><canvasid="canvas"width="200"height="200"></canvas><script>/* canvas */var canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); var radius = 50; /*  */var increase = true; /* 100  false 50  true */functiondraw() { /*  */  ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.beginPath();   ctx.arc(100, 100, radius, 0, Math.PI * 2, false); ctx.closePath();   ctx.fillStyle = "#6528e0"  ctx.fill(); if (radius >= 100) { /* 100, */    increase = false  } elseif (radius < 50) { /* 50 */    increase = true;   } if (increase) {     radius++   } else {     radius--;   } } setInterval(() => {   draw() }, 20) </script></body>

3.2. setTimeout实现动画圆

setTimeout(draw, 20) 会在每次 draw 函数执行完毕后,再次设置一个20毫秒后执行 draw 函数的定时器。

draw 函数会以大约每20毫秒一次的频率被调用,这与 setInterval 的效果相似,但是 setTimeout 可以更精确地控制每次调用之间的时间间隔。

主要步骤:

  1. 初始化 canvas 元素和绘图上下文。

  2. 设置初始半径 radius为 50。

  3. 定义 draw函数,该函数首先清除 canvas,然后绘制一个圆,并且根据 increase的值来增加或减少半径。

  4. 在 draw函数的末尾,使用 setTimeout再次调用 draw函数,延迟时间为 20 毫秒。

  5. 调用 draw函数开始执行。 draw函数会不断被调用,每次调用都会更新圆的半径,并在 canvas 上重新绘制圆。半径会在 50 和 100 之间变化,形成一种动态效果。

代码示例:

<body><canvasid="canvas"width="200"height="200"></canvas><script>/* canvas */var canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); var radius = 50; /*  */var increase = true; /* 100  false 50  true */functiondraw() { /*  */  ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.beginPath();   ctx.arc(100, 100, radius, 0, Math.PI * 2, false); ctx.closePath();   ctx.fillStyle = "#6528e0"  ctx.fill(); if (radius >= 100) { /* 100, */    increase = false  } elseif (radius < 50) { /* 50 */    increase = true;   } if (increase)  {     radius++   } else {     radius--;   }   setTimeout(draw, 20) draw(); </script></body>

多圈动画 

图片

创建了一个 canvas 元素,并在其中绘制两个圆形:

主要步骤:

  1. 通过 document.getElementById("canvas") 获取页面上的 canvas 元素,并使用 getContext("2d") 获取其 2D 绘图上下文。
  2. 初始化变量 radius 为 60,这将用于控制较大圆的半径。
  3. 定义一个布尔变量 increase,初始值为 true,用于控制半径的增减。
  4. 定义 draw 函数,该函数执行以下操作:
    • 使用ctx.clearRect清除 canvas 上的绘制内容。
    • 使用ctx.beginPath开始一个新的路径。
    • 使用ctx.arc绘制一个圆,其位置在 canvas 中心 (100, 100),半径为radius,颜色为半透明的紫色 (#6528e080)。
    • 使用ctx.closePath结束当前路径。
    • 使用ctx.fill填充颜色。
    • 再次使用ctx.beginPathctx.arc绘制一个固定半径为 50 的圆,颜色为蓝色 (#0088ff)。
    • 检查radius的值,如果达到 100,则将increase设置为false,开始减小半径;如果小于 60,则将increase设置为true,开始增加半径。
    • 根据increase的值,增加或减少radius
    • 使用setTimeout延迟 30 毫秒后再次调用draw函数,创建动画效果。
    • 调用 draw 函数开始执行动画。

    代码示例:​​​​​​​

    <body>   <canvas id="canvas" width="200" height="200"></canvas>     <script> /* canvas */ var canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); var radius = 60; /*  */ var increase = true; /* 100  false 50  true */ function draw() {   /*  */   ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.beginPath();   ctx.arc(100, 100, radius, 0, Math.PI * 2, false); ctx.closePath();   ctx.fillStyle = "#6528e080"   ctx.fill();   /*  */   ctx.beginPath();   ctx.arc(100, 100, 50, 0, Math.PI * 2, false);   ctx.closePath();   ctx.fillStyle = "#0088ff" ctx.fill();   if (radius >= 100) {     /* 100, */     increase = false   } else if (radius < 60) { /* 50 */     increase = true;   }   if (increase) {     radius++   } else {     radius--;   }   setTimeout(draw, 30) draw(); </script>   </body> 

    Canvas结合Openlayer 

    图片

    5.1 openlayer-canvas 

    canvas  是作为样式设置给要素的。 

    这里分享的案例中使用了 OpenLayers 库来在网页上显示一个地图,并在地图上添加了两个点,其中一个点使用了动态生成的 canvas 图像作为图标。

    主要步骤如下:

    1. 引入 OpenLayers 的 CSS 和 JS 文件。
    2. 创建一个div元素,其 ID 为map,这将作为地图的容器。
    3. 初始化一个地图图层gaode,使用高德地图的瓦片服务作为地图的背景。
    4. 创建一个矢量图层layer,用于在地图上添加自定义的点。
    5. 初始化地图map,设置其显示的中心点、缩放级别,并将之前创建的图层添加到地图上。
    6. 创建一个 canvas 元素,并在其中绘制两个动态变化的圆,一个较大,一个较小,较大圆的颜色是半透明的红色,较小圆的颜色是蓝色。
    7. 使用setTimeout函数每隔 100 毫秒调用draw函数,更新 canvas 上的图像,并重新渲染地图。
    8. 创建一个 OpenLayers 的样式style,使用 canvas 作为图标。
    9. 创建两个 OpenLayers 的特征shapebeijing,分别代表地图上的两个点。
    10. 将样式应用到矢量图层 layer 上,并将两个特征添加到图层的源中。

    代码示例:

    ​​​​​​​

    var style = new ol.style.Style({   image: new ol.style.Icon({     img: canvas,     imgSize: [canvas.width, canvas.height]   }) }); <!DOCTYPE html>   <html lang="en">   <head>   <meta charset="UTF-8">   <meta http-equiv="X-UA-Compatible" content="IE=edge">   <meta name="viewport" content="width=device-width, initial-scale=1.0">   <title>Document</title>   <link rel="stylesheet" href="https://lib.baomitu.com/openlayers/4.6.5/ol.css">   <script src="https://lib.baomitu.com/openlayers/4.6.5/ol.js"></script>   </head>   <body>   <div id="map">   </div>   <script>   var gaode = new ol.layer.Tile({     title: "",     source: new ol.source.XYZ({       url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x=       {x}&y={y}&z={z}',       wrapX: false     })   }); /*  */ var layer = new ol.layer.Vector({   source: new ol.source.Vector() }) var map = new ol.Map({   target: "map",   layers: [gaode, layer],   view: new ol.View({     projection: 'EPSG:4326',     center: [114.30, 30.50],     zoom: 8   }) }) var center = [114.30, 30.50] let size = 40; var canvas = document.createElement('canvas'); canvas.width = size; canvas.height = size; var ctx = canvas.getContext('2d'); var radius = size / 4; var increase = true; function draw() {   ctx.clearRect(0, 0, size, size);   /*  */   ctx.beginPath();   ctx.arc(size / 2, size / 2, radius, 0, Math.PI * 2); ctx.closePath();   ctx.fillStyle = "#ff2d5166";   ctx.fill();   /*  */   ctx.beginPath();   ctx.arc(size / 2, size / 2, 8, 0, Math.PI * 2);   ctx.closePath();   ctx.fillStyle = "#0088ff";   ctx.fill();   if (radius > 14) {     increase = false   }   if (radius < 10) {     increase = true;   }   if (increase) {     radius++   } else {     radius--;   }   setTimeout(draw, 100)   map.render(); draw(); var style = new ol.style.Style({   image: new ol.style.Icon({     img: canvas,     imgSize: [canvas.width, canvas.height] }) }); var shape = new ol.Feature({   geometry: new ol.geom.Point(center) }); var beijing = new ol.Feature({   geometry: new ol.geom.Point([120, 40]) }) layer.setStyle(style) layer.getSource().addFeatures([shape, beijing]); </script>   </body>   </html> 

    5.2. 封装 

    代码示例:

    ​​​​​​​

    function setCanvas(map) {   let size = 40;   var canvas = document.createElement('canvas');     canvas.width = size;   canvas.height = size;   var ctx = canvas.getContext('2d');   var radius = size / 4;   var increase = true;   function draw() {     ctx.clearRect(0, 0, size, size);     /*  */     ctx.beginPath();     ctx.arc(size / 2, size / 2, radius, 0, Math.PI * 2); ctx.closePath();     ctx.fillStyle = "#ff2d5166";     ctx.fill();     /*  */     ctx.beginPath();     ctx.arc(size / 2, size / 2, 8, 0, Math.PI * 2);     ctx.closePath();     ctx.fillStyle = "#0088ff";     ctx.fill();     if (radius > 14) {       increase = false     }     if (radius < 10) {       increase = true;     }     if (increase) {       radius++     } else {       radius--;     }     setTimeout(draw, 180)     map.render();   }   draw();   return canvas; // let canvas = setCanvas(map); var style = new ol.style.Style({   image: new ol.style.Icon({     img: canvas,     imgSize: [canvas.width, canvas.height]    }) });

    为了帮助大家更快的了解GIS开发,我们还特别推出了项目教程,部分含笔记,有兴趣的可以扫码领取,备注相关课程名字:

    1.智慧校园系统项目

    2.Echarts数据可视化实战项目

    3.零基础入门WebGIS开发实例

    4.cesiume系列教程

    5.前端框架VUE3入门教程

    6.二维地图框架mapbox系列教程

    7.嘉yaogis888备注资料名称

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值