整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          WEB前端開源智體世界:喬布斯3D紀念館-22課-煙花插件的制作

          用dtns.network德塔世界(開源的智體世界引擎),策劃和設計《喬布斯超大型的開源3D紀念館》的系列教程。dtns.network是一款主要由JavaScript編寫的智體世界引擎(內嵌了three.js編輯器的定制版-支持以第一視角游覽3D場館),可以在瀏覽器和node.js、deno、electron上運行,它是一個跨平臺的軟件,支持多個操作系統使用!

          下面分為幾步介紹,如何基于dtns.plugin實現煙花插件的制作。該《煙花插件》采用開源的js-canvas繪制燃放煙花的特效。通過dtns.plugin(基于vue2.x版本構建《煙花插件》),通過npm build lib編譯生成index.js,將index.js和index.json配置文件,壓縮生成dpkg的類似各類小程序安裝包的插件。

          基于js原生開發的dtns.plugin插件,擁有移植方便,使用簡單,易于傳播的特點。并且上手簡單,特別容易開發。是除了poplang智體編程之外,極好的插件開發技術棧。可以輕松地在dtns.network智體世界和dtns.connector客戶端中,實現各類輕應用(例如dpkg、xverse、xcard等)開發的利器!

          這也是構建dtns.os(智體OS)的利器!

          第一步:打開頭榜頁面,找到“煙花插件-4”

          注:第一次點擊會下載dpkg插件文件(并提示文件保存路徑——游覽器);第二次點擊會進入“煙花插件”頁面(/firework路徑,后面會講到如何配置這個頁面路由路徑)

          第二步:點擊“煙花插件”,查看煙花燃放動畫效果

          注:由于頂部無【返回】按鈕,須通過游覽器的回退按鈕或手機上的返回觸摸鍵返回頭榜頁面。

          第三步:打開vscode中的dtns.plugin文件夾,了解dpkg插件開發原理

          注:如上圖所示,在dtns.plugin/pkgs/pages/firework/FireWork.vue中查看到template標簽,繼續向下滑動,可以看到這個是一個典型的vue文件(如下圖所示)

          注:可以看到vue模板template的name為FireWork(插件名稱,后續引入這個component組件,需要用到,并且在dpkg插件的配置文件index.json中也需要聲明)

          第四步:查看dtns.plugin/pkgs/index.js文件,了解插件install安裝到vue全局組件的機制和配置

          注:須將剛才的Firework.vue組件,導入為FireWork變量,并且存放于components數組中,以便install函數安裝(在vue中安裝為全局組件,以方便導入dtns.connector后能按組件名稱(name)進行加載插件。

          第五步:查看dtns.plugin插件工程下面的package.json——可看到npm run lib指令將剛才的FireWork.vue插件編譯為庫文件

          注:通過上述的scripts中的指令,可以看到運行npm run lib,即可編譯生成index.js庫文件(后續改名為index.js插件文件)

          在vscode終端中運行npm run lib指令后,生成lib\dtns-plugin.um.min.js庫文件(如下圖所示)

          注:后續步驟,會將這個文件修改為index.js的dpkg插件js文件。

          第六步:通過demo.html測試剛編譯的js插件lib庫文件是否可用

          注:打開demo.html,可以看到將./lib/dtns-plugin.um.js庫文件導入,并引入了vue.min.js庫文件,然后在div-id=”app”的html元素正方,通過fire-work標簽引入了名稱為FireWork的組件。這是一個典型的vue2.x的web應用。Vue.js開發者應該很快能理解它。

          第七步:雙擊demo.html,查看插件運行結果(如下圖所示)

          打開剛才的dtns.plugin/demo.html,可以看到如上效果圖

          第八步:在dtns.plugin/lib路徑下,復制dtns-plugin.um.min.js文件

          注:亦可復制dtns-plugin.um.js文件(但是文件未經壓縮,會導致插件dpkg文件變大)

          第九步:將此文件復制至dtns.plugin/dpkg/firework路徑下,將dtns-plugin.um.min.js改名為index.js目標庫文件名

          注:只有index.js才能被dtns.connector真正識別并導入插件成功。

          第十步:點擊dpkg/index.json,將其內容修改如下圖所示

          注:這是一個[]的數組,里面包含了一個{}json對象

          注2:屬性name是插件的名稱;path代表了插件加載后打開的路徑,workPath是代表在ibchat智體IB中輸入指令“firework”(“word”屬性的值)后路徑的路徑。

          注3:url屬性務必為剛才的vue組件名“FIreWork”——寫錯將導致該插件無法被識別并導入——并且type屬性須為“name”,不能為vue或其它值。

          注4:其它的title、desc、author、date按照開發者實際情況填寫即可。

          第十一步:將index.js和index.json不加文件夾情況下,直接壓縮為zip壓縮包,并將.zip文件格式修改為.dpkg,成功構建真正的dpkg的輕應用插件(類似各類小程序包)

          注:將index.js和index.json直接右鍵菜單,選擇壓縮文件為zip。然后將.zip文件后綴修改為.dpkg(注意,有些操作系統會隱藏這個文件格式后綴,將在【文件夾選項-查看文件格式】等方式實現文件后綴的查看和修改為.dpkg。

          第十二步:回到dtns.connector德塔世界連接器,點擊頭榜右上角+號,進入發布頭榜頁面

          點擊+號后,進入發布頭榜頁面(如下圖所示)

          注:將剛才壓縮生成的firework-4.dpkg輕應用包,以文件方式上傳。并將頭榜內容設置為“煙花插件-4”,并點擊右上角“確認”按鈕,發布插件成功!

          第十三步:回到頭榜頁面,找到《3D紀念館-購買煙花》的xverse輕應用,點擊右上角...,進入頭榜編輯器,然后點擊下方的“編輯xverse輕應用源碼”進入3D場景編輯器

          進入3D場景編輯器(如下圖所示)

          注:通過滾動球控制玩家視角正對著“喬布斯傳”3D擺件正前方。

          第十四步:點擊3D擺件右側屬性面板的“腳本”-編輯按鈕,打開poplang智體編程編輯器

          注:我們看到,通過$.g_firework_onload實現了對煙花插件的全局函數的調用——以實現在3D紀念館中燃放煙花。

          注2:通過ib3.file.go obj_file* onflag實現了煙花插件的預加載(不須人工點擊,實現自動安裝煙花插件——后續的dtns.os智體操作系統,亦可通過該指令實現了插件的自動化部署和全局函數的調用)

          第十五步:在dtns.plugin的vscode工程中,我們通過查看FireWork.vue源碼,找到了全局函數window.g_firework_onload的出處(如下圖所示)

          第十六步:點擊頂部的“啟動(自由視角)”預覽3D場館,點擊中間的“喬布斯傳”3D擺件,出現燃放煙花動畫效果

          注:點擊屏幕中間,這些煙花特效會關閉(亦是在FireWork.vue中實現了該事件的綁定)

          通過上述16步,我們成功完成了“煙花插件”的制作。通過dtns.plugin插件引擎,我們成功的構建了dpkg插件文件,從而直接通過頭榜上傳和頭榜支付購買煙花插件.dpkg文件的方式,為dtns.connector德塔世界連接器融入了煙花插件功能(并實現了3D場館中調用插件全局函數)。最終實現了3D場館的擺件點擊播放煙花插件動畫,完整實現了一個從vue插件構建,上傳發布,文件鎖售賣插件,在poplang智體編程場景中調用全局函數使用它的完整閉環。

          整個dpkg插件的體驗非常完整。可以看到,使用dpkg和dtns.plugin插件系統,可輕松構建dtns.connector的輕應用插件生態。插件的開發、部署、上傳、體驗、銷售、購買均非常方便。非常適合構建【插件商店】生態、插件開發者生態、插件開源生態等。

          總結而言:dtns.connector德塔世界連接器,擁有了dpkg輕應用生態(融入了vue.js插件開發生態),變得更像是一個基于游覽器原生應用的操作系統:可命名為dtns.os操作系統。所有插件和項目均為開源,歡迎體驗!

          注:dtns.network德塔世界(開源的智體世界引擎)是在github和gitee上開源的項目!

          祝建黨100周年 祖國 長沙

          感恩當下,祝福未來

          長沙橘子洲的煙花真好看

          <script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>

          那給你們也搞個代碼做的煙花吧!

          在網上轉載大神寫的, 用谷歌瀏覽最好

          代碼里調用 run() 可實現帶線的煙花,

          點擊canvas生成一朵煙花

          右擊canvas清空一次畫布

          雙擊canvans生成一朵帶線的隨機煙花

          代碼里我將clear()方法隱藏掉了, 所以不會每一幀都清空畫布

          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
          <html xmlns="http://www.w3.org/1999/xhtml">
          <head>
          <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
          <title>點擊放煙花, 右擊清空</title>
          <style>
          *{margin:0;padding:0;background-color:black;}
              canvas{border:1px solid;}
          </style>
           
           
          <!-- 煙花類 和煙花碎屑類 -->
          <script>
          // 煙花
          function Firework(sx, sy, ex, ey, hue){
          	this.sx = sx; // 開始x軸
          	this.sy = sy; // 開始y軸
          	this.ex = ex; // 結束x軸
          	this.ey = ey; // 結束y軸
          	this.x = sx; // 實時x軸
          	this.y = sy; // 實時y軸
          	this.old = new Array(); // 之前的舊角度
          	this.speed = random(50, 100);
          	this.angle = Math.atan2(ey - sy, ex - sx); // 角度
          	this.actualDistance = 0; // 實際路徑
          	this.distance = countDistance(sx, sy, ex, ey); // 計算總距離
          	this.acceleration = 1.05; // 加速
          	this.friction = 0.95 //摩擦力
          	this.gravity = 1; //重力
          	this.hue = hue; // 色調
          	this.brightness = random(50, 80); //隨機明度
          	this.alpha = 1; //初始透明度
          	this.decay = random(0.015, 0.03); //碎屑小時的時間
          	this.color = "black";
          	// 現將old存儲兩個xy, 防止畫出的時候下標溢出
          	this.old.push({x:this.x, y:this.y});
          	this.old.push({x:this.x, y:this.y});
          }
          // 煙花路徑更新
          Firework.prototype.update = function(){
          	this.old.push({x:this.x, y:this.y}); // 儲存廢舊路徑
          	var x = Math.cos(this.angle) * this.speed;
          	var y = Math.sin(this.angle) * this.speed;
          	this.actualDistance = countDistance(this.sx, this.sy, this.x + x, this.y + y);
          	this.x += x;
          	this.y += y;
          	this.old.push({x:this.x, y:this.y});
          	if(this.distance < this.actualDistance) // 行走路徑大于實際路徑
          		return false; // 煙花到目標燃放點
          	else
          		return true; // 煙花未到目標燃放點
          }
          // 爆炸顆粒
          function Particle(x, y, hue){
          	this.x = x;
          	this.y = y;
          	this.old = new Array(); // 記錄步數
          	this.angle = random(0, 2 * Math.PI); // 任意角度
          	this.speed = random(1, 10); //隨機速度
          	this.friction = 0.95 //摩擦力
          	this.gravity = 1; //重力
          	this.hue = random(hue - 20, hue + 20); //生成與煙花色彩相近的碎屑
          	this.brightness = random(50, 80); //隨機明度
          	this.alpha = 1; //初始透明度
          	this.decay = random(0.015, 0.03); //碎屑存在時間
          }
          // 爆炸顆粒更新
          Particle.prototype.update = function(){
          	this.old.push({x:this.x, y:this.y});
          	this.speed *= this.friction; // 添加重力
          	this.x += Math.cos(this.angle) * this.speed; // 計算下一步x軸
          	this.y += Math.sin(this.angle) * this.speed + this.gravity; // 計算下一步y軸 + 重力
          	this.old.push({x:this.x, y:this.y});
          	this.alpha -= this.decay; // 每走一步消除碎屑透明度
          	if(this.alpha < this.decay){ // 碎屑透明度輕于碎屑存在時間
          		return false; // 煙花要消失
          	}else{
          		return true; // 煙花在燃放
          	}
          }
          // 爆炸顆粒工廠
          function ParticleFactory(sx, sy, hue){
          	var array = new Array();
          	var size = random(50, 500); // 煙花數量
          	var scope = random(50, 500); // 煙花范圍
          	for(var i = 0 ; i < size ; i++){
          		array.push(new Particle(sx, sy, hue));
          	}
          	return array;
          }
          </script>
           
          <!-- 工具類 -->
          <script>
          // 隨機數
          function random(min, max) {
          	return Math.random() * (max - min) + min;
          }
          // 隨機顏色
          function randomRgba(min, max) {
          	var r = random(0, 255);
          	var g = random(0, 255);
          	var b = random(0, 255);
          	var opacity = random(0.1, 1);
          	var color = "rgba(" + r + ", " + g + ", " + b + ", " + opacity + ")";
          	return color;
          }
          // 計算角度
          function countDistance(x, y, xx, yy) {
          	var a = x - xx;
          	var b = y - yy;
          	return Math.sqrt(a * a + b * b);
          }
          // 清空畫布
          function clear(){
          //	ctx.clearRect(0, 0, width, height);
              ctx.globalCompositeOperation = 'destination-out';
              ctx.fillStyle = 'rgba(0, 0, 0, 0.9)';
              ctx.fillRect(0, 0, width, height);
              ctx.globalCompositeOperation = 'lighter';
          }
          // 畫線
          function draw(obj){
          	ctx.beginPath();
          	ctx.moveTo(obj.old[obj.old.length-2].x, obj.old[obj.old.length-2].y);
          	ctx.lineTo(obj.x, obj.y);
          	var color = 'hsla(' + obj.hue + ',100%,' + obj.brightness + '%,' + obj.alpha + ')';
          	ctx.strokeStyle = color;
          	ctx.stroke();
          }
          </script>
          </head>
           
          <body>
           
              <canvas style="background-color:black;" id="canvas"></canvas>
              
          </body>
          <script>
              var canvas = document.getElementById("canvas");
          	var ctx = canvas.getContext("2d");
          	var width = window.innerWidth - 10, height = window.innerHeight - 10;
          	var widthBorder = width * 0.1;
          	var heightBorder = height * 0.1;
          	var hue = 20;
          	canvas.width = width;
          	canvas.height = height;
          	
          	canvas.onclick = function(){
          		moveParticle(ParticleFactory(event.x, event.y, hue+=10))
          	}
          	
          	canvas.oncontextmenu = function(e){
          		e.preventDefault();
          		clear();
          	}
          	
              // 組合
          	function run(){
          		var x = width / 2;
          		var y = height;
          		var xx = random(widthBorder, width - widthBorder);
          		var yy = random(heightBorder, height - heightBorder);
          		var firework = new Firework(x, y, xx, yy, hue);
          		hue += 10;
          		moveFirework(firework);
          	}
          	// 煙花線
          	function moveFirework(f){
          		var id = setInterval(function(){
          			// 設置不畫線
          		    draw(f);
          			if(!f.update()){
          				draw(f);
          				clearInterval(id);
          				moveParticle(ParticleFactory(f.x, f.y, f.hue));
          			}
          		}, 100);
          		
          	}
          	// 爆炸屑
          	function moveParticle(arr){
          		var id = setInterval(function(){
          			var i = arr.length;
          			var o = null;
          			if(i){
          			//	 clear();
          			}else{
          				clearInterval(id);
          			}
          			while(i--){
          				o = arr[i];
          				if(o.update()){
          					draw(o);
          				}else{
          					arr.splice(i, 1);
          				}
          			}
          		}, 70);
          	}
          	
          </script>
          </html>
          

          喜歡的一鍵三連哦!

          果果為大家帶來了

          C/C++的學習基礎教程及相關資源

          (僅僅是部分截圖哦)

          資料領取方式:

          1. 關注本號
          2. 私信“111”即可獲取領取方式哦

          女生總是會在被求婚的時候感動的痛哭流涕,作為程序員的你如果提前給自己的女票一個求婚的動畫,想象一下她會不會很感動呢?

          今天就教大家用CSS3來做一個求婚的動畫效果吧,源碼已經放在了Github上,感興趣的可以認真看下源碼,地址如下:

          https://github.com/zhouxiongking/article-pages/tree/master/articles/wedding

          CSS

          實際效果

          首先我們來看看實際運行出來的效果,如下圖所示。

          效果圖

          在整個效果中,其實是用到了一系列的圖片,然后控制圖片的出現順序以及出現和結束的位置。

          在這個效果中,主要應用到的是animation屬性,如果對這個屬性還不是很了解的,可以先去學習一下。接下來我們具體分析整個動態是怎么實現的。

          頁面構成

          首先,我們看看頁面的構成,包括文字,其他的都是圖片,包括三個煙花效果,男孩,女孩,男孩手中的花,底部的花。頁面HTML代碼如下所示。

          頁面HTML

          文字效果

          文字部分主要是有一個平移的效果,所以使用translate屬性即可。

          文字部分動畫

          煙花效果

          在文字旁邊的煙花效果實際是一張圖片從中心點向外的擴張,因此可以使用scale屬性實現,然后通過時間的不同,來顯示出不同的煙花。

          煙花效果

          女孩效果

          圖中的女孩實際是站著不動,只是通過改變透明度來顯示出動畫效果,因此可以使用opacity屬性來實現。

          女孩效果

          男孩效果

          圖中的男孩實際有一個向女孩移動的效果,因此也是通過translate屬性來實現。

          男孩效果

          手中鮮花效果

          男孩手中的鮮花實際上也是一個由中心點向外擴張的效果,并且改變透明度,通過scale和opacity屬性實現。

          手中鮮花效果

          底部鮮花效果

          底部的鮮花實際是由兩張圖片重復顯示組成,然后給每張圖片增加一個動畫效果,從效果圖中可以看出是有一個從下到上的平移過程,因此也是使用translate屬性實現。

          底部鮮花效果

          至此所有的動畫效果都已經講解完畢了,雖然每個動畫只是用到一兩個屬性,但是組合之后就可以完成這樣一個小巧的求婚動畫,是不是很有趣呢?

          結束語

          當然文中的代碼并不是全部的實現,文中的代碼只包括使用CSS3的動畫效果的實現,全部的代碼可以去Github上去看。

          今天的這篇文章學會了嗎?


          主站蜘蛛池模板: 日产一区日产2区| 国产精品一区二区三区久久| 久久精品国产一区| 亚洲一区二区三区影院 | 国产精品无码一区二区三级| 国产人妖视频一区二区破除| 蜜桃视频一区二区| 国精品无码一区二区三区在线| 另类一区二区三区| 亚洲国产AV一区二区三区四区 | 一区二区三区在线播放视频| 清纯唯美经典一区二区| 精品福利一区二区三区免费视频| 亲子乱av一区区三区40岁| av在线亚洲欧洲日产一区二区| 日本一区二区不卡在线| 精品欧美一区二区在线观看| 久久精品国产一区二区三区不卡| 精品一区二区三区免费| 亚洲sm另类一区二区三区 | 大屁股熟女一区二区三区| 精品人妻码一区二区三区| 日本免费精品一区二区三区| 无码人妻AⅤ一区二区三区| 精品国产一区二区三区久| 国产精品无圣光一区二区| 丰满爆乳无码一区二区三区| 国产人妖视频一区二区| 国产成人精品一区二区三在线观看| 国产在线精品一区二区三区不卡 | 亚洲高清一区二区三区电影| 国产成人一区在线不卡| 亚洲AV无码国产精品永久一区 | 亚洲欧洲日韩国产一区二区三区| 一区二区三区内射美女毛片| 亚洲日韩一区精品射精| 精品一区二区三区在线视频| 国产亚洲综合一区二区三区 | 东京热人妻无码一区二区av| 日韩精品免费一区二区三区| 日韩精品乱码AV一区二区|