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

首頁 > 開發 > HTML5 > 正文

html5 canvas 實現光線沿不規則路徑運動

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

svg讓動畫沿著不規則路徑運動

查閱svg文檔后發現,svg動畫運動有兩種實現方式,且都非常簡單,但對于100%實現設計師給出的效果有很大的距離

使用offset-path偏移路徑和offset-roate偏移角度讓元素沿著不規則路徑走

<!DOCTYPE html>	<html>	<head>		<title>offset-path/offset-roate</title>	</head>	<style type="text/css">		* {			padding: 0;			margin: 0;			box-sizing: border-box;		}		body {			background: #000;		}		.line {			width: 80px;			height: 3px;	        position: absolute;	        background: red;			offset-path: path("M10 80 L 77.5 60 L 145 80 L 280 100 L 500 80 L 600 120 L 800 80 L 950 120 L 950 200 L 930 250 L 950 300 L 950 500");	        animation: move 10s linear infinite;		}		@keyframes move {			100% {				offset-distance: 2000px;			}		}		.line1 {			position: absolute;			left: 100px;			width: 20px;			height: 20px;			border-radius: 50%;			background: red;			offset-path: path("M0,0a72.5,72.5 0 1,0 145,0a72.5,72.5 0 1,0 -145,0");	   		offset-rotate: 0deg;	   		animation: load 1.8s cubic-bezier(0.86, 0, 0.07, 1) infinite;	   		animation-delay: 0.147s;	    	animation-fill-mode: forwards;		}		@keyframes load {			from {		        offset-distance: 0;		    }		    to {		        offset-distance: 100%;		    }		}	</style>	<body>		<h2>路徑偏移</h2>		<div class="line"></div>		<svg width="100%" height="600px" version="1.0" id="svg1">			<path d="M10 80 L 77.5 60 L 145 80 L 280 100 L 500 80 L 600 120 L 800 80 L 950 120 L 950 200 L 930 250 L 950 300 L 950 500" fill="#tranparent" stroke="#FFF"></path>		</svg>		<h2>角度偏移</h2>		<div class="line1">		</div>	</body>	</html>

此種方式的限制是滾動元素無法隨路徑進行沒有規律的變化

使用stroke-dasharray和stroke-dashoffset讓路徑邊線動起來

stroke-dasharray:設置shap和text 邊框虛線的實線長度與實線之間的間隔(虛線長度)
stroke-dashoffser:設置邊框線條相對于默認位置的偏移(正值:向左,負值:向右)

<!DOCTYPE html>	<html>	<head>		<title>stroke-dasharray/stroke-dashoffser</title>	</head>	<style type="text/css">		* {			padding: 0;			margin: 0;			box-sizing: border-box;		}		body {			background: #000;			color: #fff;		}		.move {			animation: moving 5s infinite;		}		@keyframes moving {			0% {				stroke-dashoffset: 80px;			}			100% {				stroke-dashoffset: -1600px;			}		}	</style>	<body>	<h2>設置stroke-dasharray</h2>	<b>storke-dasharray設置為80 ,此時實線和實線間隔一樣</b>	<svg width="100%" height="600px" version="1.0" id="svg1">		<path d="M10 80 L 77.5 60 L 145 80 L 280 100 L 500 80 L 600 120 L 800 80 L 950 120 L 950 200 L 930 250 L 950 300 L 950 500" fill="#tranparent" stroke="#FFF" stroke-dasharray="80"></path>	</svg>	<b>storke-dasharray設置為80 320,此時實線和是實線間隔的1/4</b>	<svg width="100%" height="600px" version="1.0" id="svg1">		<path d="M10 80 L 77.5 60 L 145 80 L 280 100 L 500 80 L 600 120 L 800 80 L 950 120 L 950 200 L 930 250 L 950 300 L 950 500" fill="#tranparent" stroke="#FFF" stroke-dasharray="80 320"></path>	</svg>	<h2>設置stroke-dashoffset讓邊線相對于初始位置發生偏移</h2>	<svg width="100%" height="600px" version="1.0" id="svg1">		<path d="M10 80 L 77.5 60 L 145 80 L 280 100 L 500 80 L 600 120 L 800 80 L 950 120 L 950 200 L 930 250 L 950 300 L 950 500" fill="#tranparent" stroke="#FFF" stroke-dasharray="80 320" stroke-dashoffset="40"></path>	</svg>	<h2>通過設置stroke-dasharray 和 stroke-dashoffset讓邊線動起來</h2>	<svg width="100%" height="600px" version="1.0" id="svg1">		<path d="M10 80 L 77.5 60 L 145 80 L 280 100 L 500 80 L 600 120 L 800 80 L 950 120 L 950 200 L 930 250 L 950 300 L 950 500" fill="#tranparent" stroke="#FFF"></path>		<path d="M10 80 L 77.5 60 L 145 80 L 280 100 L 500 80 L 600 120 L 800 80 L 950 120 L 950 200 L 930 250 L 950 300 L 950 500" fill="#tranparent" stroke="red" stroke-dasharray="80 1600" stroke-dashoffset="0" class="move"></path>	</svg>	</body>	</html>

此種方式通過邊框偏移的效果可以設置跟隨路徑的滾線條,但是無法設置線條的光線效果,即實線的陰影和實線的漸變效果(漸變區域需隨著偏移路徑的變化而變化)

canvas實現線條延不規則路徑運動

線條實現

對于不規則路徑,如果直接用畫線條的方式實現光線,需要計算每一個開始點和結束點的位置,中間還可能存在轉折點,計算起來非常麻煩,不可取
故這邊采取canvas組合圖形的模式,取線條和一個圖形重疊部分(類似于燈罩)來實現光線效果
 

組合前
 


 

組合后
 

<!DOCTYPE html>	<html>	<head>		<title>canvas實現不規則路徑光效</title>	</head>	<style type="text/css">		body {			background: #000;		}		#wrap {			position: absolute;			width: 1200px;			height: 600px		}	</style>	<body>		<div id="wrap">			<canvas id="canvas" width="1200" height="600"></canvas>		</div>	</body>	<script type="text/javascript">		var path = 'M 10 80 L 77.5 60 L 145 80 L 280 100 L 500 80 L 600 120 L 800 80 L 950 120 L 950 200 L 930 250 L 950 300 L 950 500';		var list = path.match(/([A-Z]([^A-Z]){1,})/g).map(item => {			return {				x: item.split(' ')[1],				y: item.split(' ')[2],				action: item.split(' ')[0],			}		});//獲取每個點位置		var canvas = document.getElementById('canvas');		var ctx = canvas.getContext('2d');		ctx.strokeStyle = 'rgba(255,255,255,1)';		function drawPath() {			ctx.lineWidth = 3;			ctx.beginPath();			list.forEach(item => {				if(item.action == 'M') ctx.moveTo(item.x, item.y);				if(item.action == 'L') ctx.lineTo(item.x, item.y);			});			ctx.stroke();		}		drawPath();		function drawLine() {			//設置圖形組合方式 默認source-over			ctx.globalCompositeOperation = "destination-in";			ctx.lineWidth = 60;			ctx.beginPath();			ctx.moveTo(40, 80);			ctx.lineTo(200, 80);			ctx.stroke();		}		drawLine();	</script>	</html>

讓線條動起來

當我們實現好線條剩下就需要讓線條動起來,由于線條是通過燈罩的方式來實現的,讓線條運動只需要讓燈罩動起來就好
 

<!DOCTYPE html>	<html>	<head>		<title>canvas實現不規則路徑光效</title>	</head>	<style type="text/css">		body {			background: #000;		}		#wrap {			position: absolute;			width: 1200px;			height: 600px		}	</style>	<body>		<div id="wrap">			<canvas id="canvas" width="1200" height="600"></canvas>		</div>	</body>	<script type="text/javascript">		var path = 'M 10 80 L 77.5 60 L 145 80 L 280 100 L 500 80 L 600 120 L 800 80 L 950 120 L 950 200 L 930 250 L 950 300 L 950 500';		var list = path.match(/([A-Z]([^A-Z]){1,})/g).map(item => {			return {				x: item.split(' ')[1],				y: item.split(' ')[2],				action: item.split(' ')[0],			}		});//獲取每個點位置		var step = 3;		var x1, x2, y1, y2;//確定路徑中最大最小點		var timer;		var canvas = document.getElementById('canvas');		var ctx = canvas.getContext('2d');		ctx.strokeStyle = 'rgba(255,255,255,1)';		ctx.shadowColor = 'rgba(255,255,255,1)';		ctx.lineCap = 'round';		ctx.shadowBlur = 3;		list.forEach(item => {			x1 = !x1 || Number(item.x) < x1 ? Number(item.x) : x1;			y1 = !y1 || Number(item.y) < y1 ? Number(item.y) : y1;			x2 = !x2 || Number(item.x) > x2 ? Number(item.x) : x2;			y2 = !y2 || Number(item.y) > y2 ? Number(item.y) : y2;		});		function drawPath() {			ctx.lineWidth = 3;			ctx.beginPath();			list.forEach(item => {				if(item.action == 'M') ctx.moveTo(item.x, item.y);				if(item.action == 'L') ctx.lineTo(item.x, item.y);			});			//添加光效漸變			var grd = ctx.createLinearGradient(arrLine[arrLine.length - 1].x, arrLine[arrLine.length - 1].y, arrLine[0].x, arrLine[0].y);			grd.addColorStop(0, 'rgba(255, 255, 255, 0)');   //定義漸變線起點顏色	        grd.addColorStop(1, 'rgba(255, 255, 255, 1)');  //定義漸變線結束點的顏色	        ctx.strokeStyle = grd;			ctx.stroke();		}		//設計合適的初始線條狀態		var arrLine = Array(10).fill(0).map((item, inx) => {			return {				x: x1 - 20 * inx,				y: y1 + 30,			}		});		//隨時間變化圖形路徑		function getArrLine() {			var isEnd			arrLine = arrLine.map(item => {				var x = item.x;				var y = item.y;				if(x < x2 - 30) {					x = x + step > x2 -30 ? x2 - 30 : x + step;				} else if(x == x2 -30 && y < y2) {					y = y + step > y2 ? y2 : y + step;				} else {					isEnd = true;				}				return {					x,					y				}			});			isEnd && timer && cancelAnimationFrame(timer);		}		//繪制圖形		function drawLine() {			//設置圖形組合方式 默認source-over			ctx.globalCompositeOperation = "destination-in";			ctx.lineWidth = 70;			ctx.beginPath();			arrLine.forEach((item, inx) => {				if(inx == 0) {					ctx.moveTo(item.x, item.y);				} else {					ctx.lineTo(item.x, item.y);				}			})			ctx.stroke();		}		function start() {			ctx.clearRect(0, 0, 1200, 600);			ctx.globalCompositeOperation = 'source-over';			drawPath();			drawLine();			getArrLine();			timer = requestAnimationFrame(start);		}		timer = requestAnimationFrame(start);	</script>	</html>

這種實現方式也有一定的條件限制,那就是路徑可大體抽象成為一個有一定規律的圖型或者線條,比如上面demo中路徑可抽象成為一個矩形的兩邊,或者是2條連接的直線
我們必須從沒有具體規則的路徑中抽象出一個大體的規則,不同路徑規則不同
上面的例子就是將不規則路徑抽象成了一個直角的規則路徑
 

可優化點

這邊找到了2個可優化的點
1.時間方向上: 為了讓動畫消耗較小,代碼中的定時器已經用的是requestAnimationFrame, 但是由于光線的特殊性(自帶模糊效果),為了性能更加,嘗試了2次requestAnimationFrame調用一次繪圖的方式,效果較前者未有明顯區別
2.繪圖方向上: 從上圖可發現,燈罩每次只圈出路徑的一部分,故繪圖中不需要每次都繪制全部路徑,只需要找出燈罩前后的路徑點,將這一段路徑繪制出來就好

坑點

在完成這個動動畫效果之后遇到一個至今原因不明的bug,隨著屏幕放置時間的變長,動畫越來越慢,打開任務管理器,未見內存泄漏或者cpu使用率過高。打開performance,發現頁面調幀嚴重,屏幕幀數越來越低,單個Frame CPU time越來越長,范圍來看,script和render和paint耗時未發生線性變化,只有system時間越來越來長,越來越長,期望能被大佬告知原因
一開始
 

到后來
 

解決的辦法較為...,光線每循環一個周期,我銷毀了之前的canvas并新建了canvas,上層規避了system time不知道為什么越來越長的問題
chrome版本:80.0.3987.163(正式版本) (64 位)

到此這篇關于html5 canvas 實現光線沿不規則路徑運動的文章就介紹到這了,更多相關canvas 光線不規則運動內容請搜索武林網以前的文章或繼續瀏覽下面的相關文章,希望大家以后多多支持武林網!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日韩中国免费专区在线看| 中文字幕在线观看亚洲| 亚洲成人网av| 欧美亚洲午夜视频在线观看| 亚洲色图第三页| 精品香蕉在线观看视频一| 国内精品一区二区三区四区| 国产精品第10页| 精品一区二区三区电影| 欧美视频在线免费| 亚洲一区二区三区久久| 性欧美办公室18xxxxhd| 国产精品91久久| 国产一区在线播放| 亚洲国产成人精品久久| 国产精品大陆在线观看| 丝袜情趣国产精品| 久久99久久99精品中文字幕| 亚洲电影在线看| 国产91精品青草社区| 7777免费精品视频| 亚洲综合中文字幕在线| zzjj国产精品一区二区| 日韩中文有码在线视频| 亚洲色图综合久久| 精品国产美女在线| 97国产精品人人爽人人做| 亚洲国产精品久久久久秋霞不卡| 91精品久久久久久久久青青| 亚洲女人天堂视频| 成人欧美一区二区三区黑人孕妇| 国产在线999| 奇米一区二区三区四区久久| 亚洲精品日产aⅴ| 深夜精品寂寞黄网站在线观看| 精品亚洲一区二区三区| 亚洲精品99999| 26uuu另类亚洲欧美日本一| 亚洲二区在线播放视频| 日韩av免费网站| 久久精品国产一区| 亚洲乱码国产乱码精品精| 欧美亚洲第一页| 国产香蕉一区二区三区在线视频| 国产福利精品视频| 高清欧美性猛交xxxx黑人猛交| 成人精品久久久| 日本国产高清不卡| 色爱精品视频一区| 欧美日韩亚洲视频一区| 国产女精品视频网站免费| 中文字幕亚洲一区二区三区| 日本成熟性欧美| 国产91亚洲精品| 亚洲精品国产免费| 一区二区三区视频免费| 欧美裸体视频网站| 久久久人成影片一区二区三区观看| 91精品国产一区| 欧美性xxxxhd| 久久久www成人免费精品| 91久久久久久久久久久久久| 中文字幕最新精品| 成人字幕网zmw| 国产欧美精品一区二区| 性欧美办公室18xxxxhd| 国产一区二区在线播放| 色狠狠久久aa北条麻妃| 欧美国产中文字幕| 2021久久精品国产99国产精品| 日韩av影院在线观看| 91社影院在线观看| 亚洲伊人成综合成人网| 国产视频久久网| 亚洲成在人线av| 久久99热精品这里久久精品| 日韩欧美在线视频| 日韩精品在线观看视频| 国产精品盗摄久久久| 久久伊人91精品综合网站| 日本久久久久久久久| 中文日韩电影网站| 中文字幕九色91在线| 欧亚精品在线观看| 精品久久中文字幕久久av| 成人免费看吃奶视频网站| 亚洲a在线观看| 国产精品99久久久久久www| 日韩av在线影院| 日韩精品免费在线视频观看| 欧美野外wwwxxx| 欧美精品精品精品精品免费| 欧美在线视频网站| 久久国产天堂福利天堂| 久久国产加勒比精品无码| 成人性生交大片免费看视频直播| 亚洲精品福利资源站| 国产成人精品一区二区三区| 日韩中文有码在线视频| 久久成年人免费电影| 久久久久久久999精品视频| 98视频在线噜噜噜国产| 日韩欧美精品中文字幕| 亚洲人成人99网站| 国产69精品99久久久久久宅男| 亚洲第一av网站| 精品久久久久国产| 奇米4444一区二区三区| 亚洲欧美色婷婷| 中文字幕亚洲综合| 91国内揄拍国内精品对白| 日韩精品免费在线播放| 亚洲视频专区在线| 色琪琪综合男人的天堂aⅴ视频| 精品香蕉在线观看视频一| 欧美另类极品videosbestfree| 亚洲欧美日韩视频一区| 国产91在线高潮白浆在线观看| 日韩av在线一区二区| 亚洲影院色无极综合| 久久精品中文字幕电影| 亚洲最新视频在线| 亚洲欧美成人精品| 国产精品吹潮在线观看| 精品国产精品三级精品av网址| 欧美日韩免费网站| 亚洲香蕉成人av网站在线观看| 亚洲欧美日韩精品久久亚洲区| 亚洲视频一区二区| 久久精品国产99国产精品澳门| 亚洲综合大片69999| 黄网站色欧美视频| 日韩在线视频二区| 欧美成人精品激情在线观看| 亚洲欧美国产日韩中文字幕| 91a在线视频| 久久综合亚洲社区| 久久国内精品一国内精品| 国产精品一区二区性色av| 在线看日韩av| 国产精品久久久久久久久久免费| 亚洲韩国欧洲国产日产av| 曰本色欧美视频在线| 一区二区三区 在线观看视| 伊人男人综合视频网| 国产小视频91| 91精品国产91久久久久福利| 欧美精品一二区| 成人黄色片网站| 国产精品老女人精品视频| 国产成人一区三区| 亚洲激情在线观看视频免费| 欧美日韩成人黄色| 国产欧洲精品视频| 欧美性少妇18aaaa视频| 欧美激情亚洲激情| 亚洲男人的天堂网站| 久久精品免费电影| 午夜精品久久久久久久久久久久| 欧美视频在线观看免费| 狠狠躁18三区二区一区| 色老头一区二区三区| 色噜噜国产精品视频一区二区| 91成人精品网站|