亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > HTML5 > 正文

Canvas實現貝賽爾曲線軌跡動畫的示例代碼

2024-09-05 07:22:51
字體:
來源:轉載
供稿:網友

最近實現的下圖的效果,跟大家分享一下

假如我們要畫下圖曲線的動畫

如果每次都畫一條短線連接起來,如下圖被分成五段

再看十段

要是被分的段數足夠多時每次畫一段就很像曲線軌跡了

二次貝賽爾曲線

/** * 二次貝塞爾曲線動畫 * @param  {Array<number>} start 起點坐標 * @param  {Array<number>} 曲度點坐標(也就是轉彎的點,不是準確的坐標,只是大致的方向) * @param  {Array<number>} end 終點坐標 * @param  {number} percent 繪制百分比(0-100) */   function drawCurvePath(start, point, end, percent){            ctx.beginPath();    //開始畫線            ctx.moveTo(start[0], start[1]);   //畫筆移動到起點            for (var t = 0; t <= percent / 100; t += 0.005) {                //獲取每個時間點的坐標                var x = quadraticBezier(start[0], point[0], end[0], t);                   var y = quadraticBezier(start[1], point[1], end[1], t);                ctx.lineTo(x, y);   //畫出上個時間點到當前時間點的直線            }             ctx.stroke();   //描邊        }                /** * 二次貝塞爾曲線方程 * @param  {Array<number>} start 起點 * @param  {Array<number>} 曲度點 * @param  {Array<number>} end 終點 * @param  {number} 繪制進度(0-1) */     function quadraticBezier(p0, p1, p2, t) {            var k = 1 - t;            return k * k * p0 + 2 * (1 - t) * t * p1 + t * t * p2;         }

更加詳細的貝塞爾曲線內容請參考這篇博客

放入完整的代碼中

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <meta http-equiv="X-UA-Compatible" content="ie=edge">    <title>二次貝塞爾曲線動畫</title>    <style>         body {            background: #0f1632;        }        #canvas {            border: 1px solid #ccc;        }         #img {            display: none;             <!--img直接隱藏就行,后面會直接引用-->        }            </style></head><body>    <canvas id="canvas" width="1500" height="750"></canvas>    <img id="img" src="https://s3.imgsha.com/2019/04/22/light.png">        <script>        var ctx = document.getElementById('canvas').getContext('2d');        var img = document.getElementById('img');        var percent = 0;        var data = {                start: [400, 200],                point: [300, 100],                end: [100, 400],                department: '數據1',                value: 4321            }                    function init(){            percent = 0;  //每次重置進程            draw();        }        function draw(){            ctx.clearRect(0, 0, 1500, 750);  //每次清除畫布            ctx.strokeStyle = '#ffffff';    //設置線條樣式                        drawCurvePath(data.start, data.point, data.end, percent);                       percent += 0.8; //進程增加,這個控制動畫速度                         if (percent <= 100) { //沒有畫完接著調用,畫完的話重置進度                requestAnimationFrame(draw);            }else{                init()            }        }        function drawCurvePath(start, point, end, percent)            //...        }        function quadraticBezier(p0, p1, p2, t) {            //...        }    </script></body></html>

動畫就出來了

之前說了 drawCurvePath(start, point, end, percent)函數中point這個參數不是具體曲度的點,只是一個大致的方向

再開看一下 point改為[200,200]的情況

添加漸變

如果想實現墜落的效果,由高到低由遠及近需要給線條加一個漸變的效果

/** * 創建線性漸變 * @param  {Array<number>} start 起點 * @param  {Array<number>} 曲度點 * @param  {Array<number>} end 終點 * @param  {number} 繪制進度(0-1) */function createLinearGradient(start,end,startColor,endColor){  var lineGradient = ctx.createLinearGradient(...start, ...end);                lineGradient.addColorStop(0, startColor);                // lineGradient.addColorStop(0.3, '#fff');                lineGradient.addColorStop(1, endColor);  return lineGradient}//draw函數需要做些調整function draw(){    //ctx.strokeStyle = '#ffffff';      ctx.strokeStyle = createLinearGradient(data.start,                                             data.end,                                             'rgba(255,255,255,.2)',                                             '#fff'                                             );     //...}

canvas漸變詳情請參考MDN

頭部光暈

添加頭部光暈需要畫一個圓,并設置徑向漸變,利用drawCurvePath函數獲取x,y并重置圓的位置

function createHeadLight(x,y){  ctx.beginPath();  //創建徑向漸變  var radialGradient = ctx.createRadialGradient(x, y, 0, x, y, 20);        radialGradient.addColorStop(0, "rgba(255,255,255,1)");        radialGradient.addColorStop(.2, "rgba(255,255,255,.8)");        radialGradient.addColorStop(1, "transparent");                ctx.fillStyle = radialGradient;        //畫圓        ctx.arc(x, y, 20, 0, 2 * Math.PI, false);        ctx.fill();}//drawCurvePath函數需要做些調整function drawCurvePath(start, point, end, percent){        //...         ctx.stroke();   //描邊         createHeadLight(x,y) //和畫線頻率一樣畫圓    }

繪制圓arc參數詳情參考MDN

添加文本

添加文本和添加頭部光暈很相似,都是利用drawCurvePath函數獲取x,y并重置文本塊的位置

/** * 創建文本 * @param  {String} 部門數據 * @param  {Number} 數據 * @param  {Number} x軸坐標 * @param  {Number} y軸坐標 */function drawText(department, value, x, y) {            ctx.fillStyle = '#fff'            ctx.font = "22px 微軟雅黑";            ctx.fillText(department, x + 30, y + 20);  //為了使文本在光暈右下角x,y軸需要偏移一些距離            var width = ctx.measureText(value).width;   //獲取文本的寬度            ctx.fillStyle = createLinearGradient([x + 30, 0],   //文本漸變x軸的渲染范圍是[x+30,x+30+文本的寬度],                                                  [x + 30 + width, 0],       //這里y取0,是因為沒找到獲取文本高的api,寫0也是可以的                                                 '#fffd00',                                                 '#ff6d00'                                                 );            ctx.fillText(value.toLocaleString(), x + 30, y + 50);            }    //drawCurvePath函數需要做些調整 function drawCurvePath(start, point, end, percent, department, value) {           //...           createHeadLight(x,y)           drawText(department, value, x, y)        }

動畫完成后結束位置添加文本和圖片

動畫完成后添加文本和圖片需要注意下,曲線動畫完成后需要立即清理畫布,然后添加文本和圖片

/** * 創建圖片 * @param  {Number} x軸坐標 * @param  {Number} y軸坐標 */function drawImg(x, y) {        ctx.drawImage(img, x - img.width / 2, y - img.height);    }//draw 函數需要做些調整draw(){    //...         if (percent <= 100) {                requestAnimationFrame(draw);            }else{            ctx.clearRect(0, 0, 1500, 750);   //曲線動畫完立即清除畫布                drawText(data.department,   //渲染文本                         data.value,                          data.end[0],                          data.end[1])                drawImg(data.end[0], data.end[1])   //渲染圖片                  setTimeout(function(){    //2000ms后重繪                     init()                  },2000)            }    }

結束

本篇示例完整代碼

文章首圖示例完整代碼

參考文章:用canvas繪制一個曲線動畫——深入理解貝塞爾曲線

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品福利免费在线观看| 国产精品永久在线| 成人黄色在线播放| 久久久久国产精品一区| 成人伊人精品色xxxx视频| 久久在精品线影院精品国产| 国产精品美女主播| 2020欧美日韩在线视频| 成人久久18免费网站图片| 日本久久久久久| 欧美性xxxx极品高清hd直播| 亚洲精品一区av在线播放| 欧美日本国产在线| 欧美性猛交99久久久久99按摩| 亚洲成av人影院在线观看| 高跟丝袜一区二区三区| 日韩在线视频网| 日本乱人伦a精品| 国产脚交av在线一区二区| 一区二区三区精品99久久| 久久全国免费视频| 久久久国产成人精品| 久久久精品999| 国产美女精品视频免费观看| 韩剧1988在线观看免费完整版| 亚洲女人天堂成人av在线| 国产丝袜高跟一区| 亚洲最新视频在线| 亚洲欧美国产高清va在线播| 日韩av不卡在线| 亚洲综合中文字幕在线观看| 精品视频一区在线视频| 97视频免费在线观看| 亚洲网站视频福利| 日韩免费av在线| 亚洲男人av在线| 色婷婷亚洲mv天堂mv在影片| 成人黄色av网| 日韩高清电影免费观看完整| 日韩电影中文字幕| 日韩在线中文视频| 亚洲国产另类 国产精品国产免费| 国产亚洲精品日韩| 亚洲激情视频在线| 欧美人与性动交a欧美精品| 午夜精品久久久99热福利| 国产精品视频精品| 欧美在线不卡区| 成人午夜激情免费视频| 久久综合免费视频影院| 久久精品夜夜夜夜夜久久| 亚洲国产天堂久久综合| 欧美成人高清视频| 一区二区成人av| 国产亚洲一区二区精品| 欧美精品久久久久久久久久| 色偷偷9999www| 成人激情在线观看| 欧美一级视频免费在线观看| 国产一区二区在线免费视频| 国产一区二区三区丝袜| 日韩a**站在线观看| 国产成人精品日本亚洲| 欧美xxxx18性欧美| 欧美日韩国产色| 不用播放器成人网| 国产精品91久久久久久| 亚州av一区二区| 911国产网站尤物在线观看| 国产欧美一区二区三区久久人妖| 国产成人精品国内自产拍免费看| 国产成人综合一区二区三区| 欧美性高潮床叫视频| 色综合久久天天综线观看| 国模视频一区二区三区| 日韩视频永久免费观看| 欧美激情亚洲激情| 欧美日韩在线视频观看| 久久综合国产精品台湾中文娱乐网| 成人精品视频久久久久| 成人97在线观看视频| 日韩亚洲成人av在线| 精品自拍视频在线观看| 国产日韩欧美视频在线| www.亚洲人.com| 精品香蕉在线观看视频一| 成人精品视频久久久久| 亚洲石原莉奈一区二区在线观看| 中文字幕在线视频日韩| 国模极品一区二区三区| 911国产网站尤物在线观看| 国模极品一区二区三区| 亚洲精品成人免费| 欧美精品一二区| 欧美精品在线视频观看| 91精品国产沙发| 亚洲国产精品99久久| 国产91精品不卡视频| 国产日产亚洲精品| 国产亚洲精品久久久优势| 91精品国产777在线观看| 国产视频在线观看一区二区| 日本91av在线播放| 久久夜色精品国产亚洲aⅴ| 97久久超碰福利国产精品…| 日韩成人网免费视频| 超薄丝袜一区二区| 成人av资源在线播放| 国产网站欧美日韩免费精品在线观看| 亚洲电影免费观看高清完整版在线观看| 国产精品视频久久| 国产精品一区二区av影院萌芽| 日韩中文字幕在线| 狠狠操狠狠色综合网| 精品精品国产国产自在线| 91黑丝高跟在线| 欧美午夜视频一区二区| 最近2019免费中文字幕视频三| 国产精品一区二区久久久| 亚洲综合最新在线| 久久成人这里只有精品| 草民午夜欧美限制a级福利片| 亚洲va电影大全| 亚洲日韩中文字幕在线播放| 国产91精品高潮白浆喷水| 欧美日韩国产在线播放| 久久久日本电影| 亚洲精品aⅴ中文字幕乱码| 黑人巨大精品欧美一区二区免费| 亚洲开心激情网| 91在线视频一区| 理论片在线不卡免费观看| 日韩免费电影在线观看| 国产精品久久久久久久久久久久| 久久精品视频在线播放| 日韩精品小视频| 亚洲图片欧美日产| 国产成人高清激情视频在线观看| 日韩欧美有码在线| 91色在线观看| 欧美日韩激情视频8区| 日韩欧美国产激情| 国产精品在线看| 欧美丝袜第一区| 亚洲欧洲激情在线| 国模精品系列视频| 久久精品国产v日韩v亚洲| 欧美极品欧美精品欧美视频| 中文字幕欧美亚洲| 国产精品美女在线| 国产自产女人91一区在线观看| 精品夜色国产国偷在线| 久久成人精品电影| 国产精品视频网| 九九热这里只有精品6| 亚洲天堂精品在线| 欧美国产精品人人做人人爱| 91亚洲国产成人精品性色| 国产精品专区一| 国产欧美一区二区三区久久人妖| 岛国av在线不卡| 国产精品日韩欧美| 色播久久人人爽人人爽人人片视av| 国产精品久久久久不卡|