Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 国产精品亚洲综合,国内精品视频一区二区三区,在线观看亚洲精品专区

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          使用 HTML5 Canvas 和 JavaScript 開(kāi)發(fā)動(dòng)畫(huà)氣泡:分步教程


          家好! 歡迎來(lái)到本教程,我們將深入了解使用 HTML 畫(huà)布和 JavaScript 在代碼中創(chuàng)建有趣的氣泡的世界。 最好的部分? 我們將只使用一點(diǎn) HTML 和所有 JavaScript,而不是 CSS 來(lái)實(shí)現(xiàn)所有這一切。

          揭示概念

          今天,我們要掌握以下幾個(gè)概念:

          使用畫(huà)布上下文的 arc 方法創(chuàng)建圓。

          利用 requestAnimationFrame 函數(shù)實(shí)現(xiàn)平滑的圓形動(dòng)畫(huà)。

          利用 JavaScript 類的強(qiáng)大功能來(lái)創(chuàng)建多個(gè)圓圈,而無(wú)需重復(fù)代碼。

          向我們的圓圈添加描邊樣式和填充樣式以獲得 3D 氣泡效果。

          你可以跟著我一起看,或者如果你想看源代碼,可以使用最終的codepen

          入門(mén)

          首先,我們需要一個(gè) HTML5 Canvas 元素。 Canvas 是創(chuàng)建形狀、圖像和圖形的強(qiáng)大元素。 這就是氣泡將產(chǎn)生的地方。 讓我們來(lái)設(shè)置一下 -

          <canvas id="canvas"></canvas>

          為了使用畫(huà)布做任何有意義的事情,我們需要訪問(wèn)它的上下文。 Context 提供了在畫(huà)布上渲染對(duì)象和繪制形狀的接口。

          讓我們?cè)L問(wèn)畫(huà)布及其上下文。

          const canvas = document.getElementById('canvas');
          const context = canvas.getContext('2d');

          我們將設(shè)置畫(huà)布以使用整個(gè)窗口的高度和寬度 -

          canvas.width = window.innerWidth;
          canvas.height = window.innerHeight;

          讓我們通過(guò)添加一些 css 為畫(huà)布提供一個(gè)漂亮的舒緩淺藍(lán)色背景。 這是我們要使用的唯一 CSS。 如果您愿意,也可以使用 JavaScript 來(lái)完成此操作。

          #canvas {
            background: #00b4ff;
          }

          是時(shí)候創(chuàng)造泡泡了!

          讓我們進(jìn)入有趣的部分。 我們將通過(guò)單擊畫(huà)布來(lái)創(chuàng)建氣泡。 為了實(shí)現(xiàn)這一點(diǎn),我們首先創(chuàng)建一個(gè)點(diǎn)擊事件處理程序:

          canvas.addEventListener('click', handleDrawCircle);

          由于我們需要知道在畫(huà)布上單擊的位置,因此我們將在句柄 DrawCircle 函數(shù)中跟蹤它并使用事件的坐標(biāo) -

          //We are adding x and y here because we will need it later.
          let x, y
          const handleDrawCircle = (event) => {
            x = event.pageX;
            y = event.pageY;
          
          // Draw a bubble!
            drawCircle(x, y);
          };

          用圓弧法畫(huà)圓

          為了創(chuàng)建圓圈,我們將利用畫(huà)布上下文中可用的 arc 方法。 Arc 方法接受 x 和 y - 圓心、半徑、起始角和結(jié)束角,對(duì)于我們來(lái)說(shuō),這將是 0 和 2* Math.PI,因?yàn)槲覀冋趧?chuàng)建一個(gè)完整的圓。

          const drawCircle = (x, y) => {
            context.beginPath();
            context.arc(x, y, 50, 0, 2 * Math.PI);
            context.strokeStyle = 'white';
            context.stroke();
          };


          使用 requestAnimationFrame 方法移動(dòng)圓圈

          現(xiàn)在我們有了圓圈,讓我們讓它們移動(dòng),因?yàn)椤?/p>

          GIF



          請(qǐng)記住,當(dāng)我們創(chuàng)建圓時(shí),我們使用了 arc 方法,它接受 x 和 y 坐標(biāo) - 圓的中心。 如果我們快速移動(dòng)圓的 x 和 y 坐標(biāo),就會(huì)給人一種圓在移動(dòng)的印象。 讓我們?cè)囋嚢桑?/span>

          //Define a speed by which to increment to the x and y coordinates
          const dx = Math.random() * 3;
          const dy = Math.random() * 7;//Increment the center of the circle with this speed
          x = x + dx;
          y = y - dy;

          我們可以將其移至函數(shù)內(nèi) -

          let x, y;
          const move = () => {
            const dx = Math.random() * 3;
            const dy = Math.random() * 7;  x = x + dx;
            y = y - dy;
          };

          為了讓我們的圓圈無(wú)縫移動(dòng),我們將創(chuàng)建一個(gè)動(dòng)畫(huà)函數(shù)并使用瀏覽器的 requestAnimationFrame 方法來(lái)創(chuàng)建一個(gè)移動(dòng)的圓圈。

          const animate = () => {
            context.clearRect(0, 0, canvas.width, canvas.height);
            move();
              drawCircle(x,y);  requestAnimationFrame(animate);
          };//Don't forget to call animate at the bottom 
          animate();



          創(chuàng)建粒子:引入粒子類

          現(xiàn)在我們已經(jīng)創(chuàng)建了一個(gè)圓圈,是時(shí)候創(chuàng)建多個(gè)圓圈了!

          但在我們創(chuàng)建多個(gè)圓圈之前,讓我們準(zhǔn)備一下我們的代碼。為了避免重復(fù)我們的代碼,我們將使用類并引入 Particle 類。 粒子是我們動(dòng)態(tài)藝術(shù)作品和動(dòng)畫(huà)的構(gòu)建塊。 每個(gè)氣泡都是一個(gè)粒子,具有自己的位置、大小、運(yùn)動(dòng)和顏色屬性。 讓我們定義一個(gè) Particle 類來(lái)封裝這些屬性:

          class Particle {
            constructor(x = 0, y = 0) {}
            draw() {
              // Drawing the particle as a colored circle
              // ...
            }  move() {
              // Implementing particle movement
              // ...
            }
          }

          讓我們將一些已設(shè)置的常量移至 Particle 類 -

          class Particle {
            constructor(x = 0, y = 0) {
              this.x = x;
              this.y = y;
              this.radius = Math.random() * 50;
              this.dx = Math.random() * 3;
              this.dy = Math.random() * 7;
            }
            draw() {
              // Drawing the particle as a colored circle
              // ...
            }  move() {
              // Implementing particle movement
              // ...
            }
          }

          draw 方法將負(fù)責(zé)在畫(huà)布上渲染粒子。 我們已經(jīng)在drawCircle中實(shí)現(xiàn)了這個(gè)功能,所以讓我們將它移動(dòng)到我們的類中并將變量更新為類變量

          class Particle {
            constructor(x = 0, y = 0) {
              this.x = x;
              this.y = y;
              this.radius = Math.random() * 50;
              this.dx = Math.random() * 3;
              this.dy = Math.random() * 7;
              this.color = 'white';
            }
            draw() {
              context.beginPath();
              context.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
              context.strokeStyle = this.color;
              context.stroke();    context.fillStyle = this.color;
              context.fill();
            }  move() {}
          }

          同樣,讓我們?cè)陬愔幸苿?dòng) move 函數(shù) -

          move() {
              this.x = this.x + this.dx;
              this.y = this.y - this.dy;
          }

          現(xiàn)在,我們需要確保在事件處理程序中調(diào)用 Particle 類。

          const handleDrawCircle = (event) => {
            const x = event.pageX;
            const y = event.pageY;
            const particle = new Particle(x, y);
          };canvas.addEventListener('click', handleDrawCircle);

          由于我們需要在 animate 函數(shù)中訪問(wèn)該粒子,以便調(diào)用其 move 方法,因此我們將該粒子存儲(chǔ)在一個(gè)名為 molecularArray 的數(shù)組中。 當(dāng)創(chuàng)建大量粒子時(shí),這個(gè)數(shù)組也會(huì)很有幫助。 這是反映這一點(diǎn)的更新代碼 -

          const particleArray = [];
          const handleDrawCircle = (event) => {
            const x = event.pageX;
            const y = event.pageY;  const particle = new Particle(x, y);
            particleArray.push(particle);
          };canvas.addEventListener('click', handleDrawCircle);

          記得也要更新動(dòng)畫(huà)功能 -

          此時(shí),您將在屏幕上看到這個(gè)粒子 -



          驚人的! 現(xiàn)在,到了有趣的部分! 讓我們創(chuàng)建很多圓圈并設(shè)計(jì)它們的樣式,使它們看起來(lái)像氣泡。

          為了創(chuàng)建大量氣泡,我們將使用 for 循環(huán)創(chuàng)建粒子并將它們添加到我們?cè)诖颂巹?chuàng)建的粒子數(shù)組中。

          const handleDrawCircle = (event) => {
            const x = event.pageX;
            const y = event.pageY;
            for (let i = 0; i < 50; i++) {
              const particle = new Particle(x, y);
              particleArray.push(particle);
            }
          };canvas.addEventListener('click', handleDrawCircle);

          在動(dòng)畫(huà)函數(shù)中,我們將通過(guò)清除畫(huà)布并在新位置重新繪制粒子來(lái)不斷更新畫(huà)布。 這會(huì)給人一種圓圈在移動(dòng)的錯(cuò)覺(jué)。

          const animate = () => {
            context.clearRect(0, 0, canvas.width, canvas.height);
            particleArray.forEach((particle) => {
              particle?.move();
              particle?.draw();
            });  requestAnimationFrame(animate);
          };animate();


          現(xiàn)在我們有了移動(dòng)的氣泡,是時(shí)候給它們添加顏色,使它們看起來(lái)像氣泡了!

          我們將通過(guò)向氣泡添加漸變填充來(lái)實(shí)現(xiàn)此目的。 這可以使用 context.createRadialGradient 方法來(lái)完成。

          const gradient = context.createRadialGradient(
            this.x,
            this.y,
            1,
            this.x + 0.5,
            this.y + 0.5,
            this.radius
          );
          gradient.addColorStop(0.3, 'rgba(255, 255, 255, 0.3)');
          gradient.addColorStop(0.95, '#e7feff');context.fillStyle = gradient;



          總結(jié)

          恭喜! 您剛剛僅使用 HTML Canvas 和 JavaScript 創(chuàng)建了一些超級(jí)有趣的東西。 您已經(jīng)學(xué)習(xí)了如何使用 arc 方法、利用 requestAnimationFrame、利用 JavaScript 類的強(qiáng)大功能以及使用漸變?cè)O(shè)計(jì)氣泡以實(shí)現(xiàn) 3D 氣泡效果。

          請(qǐng)隨意嘗試顏色、速度和大小,使您的動(dòng)畫(huà)真正獨(dú)一無(wú)二。

          請(qǐng)隨意嘗試顏色、速度和大小,使您的動(dòng)畫(huà)真正獨(dú)一無(wú)二。

          我希望您在學(xué)習(xí)本教程時(shí)能像我在創(chuàng)建它時(shí)一樣獲得樂(lè)趣。 現(xiàn)在,輪到你進(jìn)行實(shí)驗(yàn)了。 我很想看看你是否嘗試過(guò)這個(gè)以及你創(chuàng)造了什么。 與我分享您的代碼鏈接,我很樂(lè)意查看。

          代瀏覽器都內(nèi)置了專用動(dòng)畫(huà)技術(shù),Martin G?rner為您展現(xiàn)四種最棒的實(shí)例。

          現(xiàn)代移動(dòng)操作系統(tǒng)將用戶接口動(dòng)畫(huà)化,并已達(dá)到了電腦端交互的標(biāo)準(zhǔn)——精選流暢的動(dòng)畫(huà),體現(xiàn)出沉浸效果以及支持直觀的交互。我們都想當(dāng)然的認(rèn)為,可以設(shè)置一個(gè)列表,使之帶有運(yùn)動(dòng)特性,用手指輕輕一推,它就如同有重量和慣性一樣運(yùn)動(dòng)起來(lái),直到遇到邊緣再反彈回來(lái)一點(diǎn)。但是,在網(wǎng)絡(luò)上,我們還達(dá)不到這樣的效果。

          接受事實(shí)吧,現(xiàn)有網(wǎng)上的動(dòng)畫(huà)經(jīng)常被視作UI災(zāi)難,還在使用二十年前陳舊的<blink>標(biāo)簽技術(shù)。加入Flash有點(diǎn)幫助,不過(guò)它缺乏HTML DOM集成,都變成了不美觀的800×600分辨率,并且JavaScript DOM操作還有其標(biāo)志性的5幀/秒(fps)動(dòng)畫(huà)率——真是絕望啊!

          改變

          2013年,現(xiàn)代瀏覽器內(nèi)置了專用動(dòng)畫(huà)技術(shù),達(dá)到60 fps。是時(shí)候去忘掉過(guò)去,開(kāi)始構(gòu)建美妙的UI動(dòng)畫(huà)體驗(yàn)了。我將展示四個(gè)動(dòng)畫(huà)技術(shù),幫助你決定,哪一個(gè)更適合你的項(xiàng)目。

          CSS3動(dòng)畫(huà)——3D

          讓我們從最簡(jiǎn)單的聲明式技術(shù)開(kāi)始:CSS3。這里不需要JavaScript,存CSS,加上一點(diǎn)現(xiàn)代手段。

          CSS通過(guò)兩種基本屬性來(lái)聲明動(dòng)畫(huà):過(guò)渡和動(dòng)畫(huà)。過(guò)渡屬性通知瀏覽器計(jì)算兩種狀態(tài)(由各自CSS定義)間的中間幀。動(dòng)畫(huà)通過(guò)改變?cè)谻SS觸發(fā)。比如,當(dāng)你以編程方式改變它的層,或啟動(dòng)一個(gè):hover CSS。

          當(dāng)縮略圖層從開(kāi)始轉(zhuǎn)變到結(jié)束,圖像則從一處平滑的移動(dòng)到另一處,典型的表現(xiàn)為JavaScript DOM動(dòng)作的結(jié)果。

          img { -webkit-transition: 1s; }.begin { left: 0px; }.end { left: 500px; }

          動(dòng)畫(huà)屬性最常用于持續(xù)運(yùn)行的動(dòng)畫(huà)特效,它還允許自定義中間步驟的動(dòng)畫(huà)。

          創(chuàng)建一個(gè)旋轉(zhuǎn)的圖像:

          img {-webkit-animation: myAnim 3s infinite; }@-webkit-keyframes myAnim{ from {-webkit-transform: rotate(0deg) } 50% {/* possible intermediate positions at any % */} to {-webkit-transform: rotate(360deg) }}

          利用大量CSS屬性制作動(dòng)畫(huà)具有無(wú)限的創(chuàng)造性,你可以根據(jù)意圖在邊框?qū)挾葍?nèi)任意創(chuàng)建動(dòng)畫(huà)。 不過(guò),大多數(shù)對(duì)動(dòng)畫(huà)有用的屬性都是幾何變換和不透明的。CSS3通過(guò)易操作的轉(zhuǎn)換屬性提供了全系列二維幾何變換:平移、旋轉(zhuǎn)、縮放和歪斜。

          用旋轉(zhuǎn)、縮放和歪斜創(chuàng)建2D轉(zhuǎn)換:

          • webkit-transform:旋轉(zhuǎn)30度

          • webkit-transform:縮小50%

          • webkit-transform:歪斜-20度,再20度

          接下來(lái)變得有趣了。如果你覺(jué)得在CSS中添加3D效果,技術(shù)上是為了粗體和斜體的設(shè)計(jì),這很愚蠢,請(qǐng)接著閱讀。通過(guò)擴(kuò)展幾何轉(zhuǎn)換到三維圖像將是一個(gè)很自然的方式,相同變換屬性還可以做平移X,Y,Z軸以及旋轉(zhuǎn)X,Y,Z軸。

          3D旋轉(zhuǎn)圖像:

          • webkit-transform:Y軸旋轉(zhuǎn)45度

          再加上點(diǎn)拋出動(dòng)畫(huà)效果,看上去就像是一個(gè)旋轉(zhuǎn)的三維立方體。

          如果確實(shí)這般容易的話,就不會(huì)有任何趣味性了。設(shè)計(jì)師留了一點(diǎn)懸念,你可以試一下,只對(duì)一個(gè)圖像進(jìn)行旋轉(zhuǎn),瀏覽器默認(rèn)渲染出來(lái)的效果是不帶透視性的:

          • webkit-transform:Y軸旋轉(zhuǎn)45度

          可以添加上透明屬性,默認(rèn)是無(wú)窮大極限值也是不帶有一點(diǎn)透明效果的。就如同靠近鏡頭的對(duì)象與很遠(yuǎn)距離外的對(duì)象看上去大小一樣。

          為了確保圖像看上去更真實(shí),你還需要指定一個(gè)鏡頭與屏幕之間距離的值。加上-webkitperspective: 1000px就可以了。

          一點(diǎn)數(shù)學(xué)問(wèn)題:什么是透視性?

          要在一塊平面屏幕上呈現(xiàn)一個(gè)3D對(duì)象,首先畫(huà)出一條線連接眼鏡或相機(jī)與3D物理上的點(diǎn)。這條線與屏幕的交集就是相應(yīng)像素所在的位置。為了找到像素在屏幕上的坐標(biāo),利用泰勒斯定理,你需要空間中點(diǎn)的3D坐標(biāo)和相機(jī)與屏幕之間的距離(f在光學(xué)中也被稱為焦距)。這就是視角屬性提供的距離。如果這個(gè)距離是無(wú)限遠(yuǎn)的,你可以看到所有射線(眼球到3D點(diǎn)線)是水平緊密狀的,而且很遠(yuǎn)很遠(yuǎn)的對(duì)象在屏幕上的大小一樣。

          現(xiàn)在我們有設(shè)置一個(gè)3D立方體的所有基礎(chǔ)了,利用六個(gè)圖像以及CSS 3D轉(zhuǎn)換,接下來(lái)就可以實(shí)現(xiàn)旋轉(zhuǎn)了。

          旋轉(zhuǎn)

          這一步很簡(jiǎn)單:我們把一個(gè)三維旋轉(zhuǎn)封裝到一個(gè)div,將會(huì)產(chǎn)生如下效果:

          瀏覽器執(zhí)行你讓它所做的步驟:在div渲染一個(gè)三維立方體,然后像一張平面圖片般在自身運(yùn)用3D旋轉(zhuǎn)。這是默認(rèn)效果,雖然不是你想要的。你要告訴瀏覽器運(yùn)用嵌套div來(lái)構(gòu)成3D轉(zhuǎn)換,-webkit-transform-style: preserve-3d屬性。通過(guò)這個(gè),我們就能得到想要的旋轉(zhuǎn)立方體了。

          準(zhǔn)確獲取

          很容易在空間失去定位。我的建議是采用一個(gè)div,命名為SCENE。這就是透明屬性存放的位置。在內(nèi)部,放置一個(gè)命名為OBJECT的div,它應(yīng)當(dāng)擁有transform-style: preserve-3d屬性,并且該div就是你應(yīng)用轉(zhuǎn)換移動(dòng)整個(gè)對(duì)象的地方。最后,在該div內(nèi)部,使用3D轉(zhuǎn)換設(shè)置你想要的正面圖像,創(chuàng)建所需對(duì)象。在我們的例子中,立方體的六個(gè)面:

          .SCENE { -webkit-perspective: 1000px; }.OBJECT{ -webkit-transform-style: preserve-3d; -webkit-transform: rotateX(20deg rotateY(120deg) rotateZ(50deg); /* replace this with an animation property if you want movement */}.FACE1 { -webkit-transform:translateX(150px)rotateY(90deg);}...

          關(guān)于3D CSS轉(zhuǎn)換很棒的一點(diǎn)是CSS動(dòng)畫(huà)和過(guò)渡的完美結(jié)合。我們?cè)谶@留了一個(gè)練習(xí),讓旋轉(zhuǎn)立方體運(yùn)動(dòng)起來(lái),當(dāng)鼠標(biāo)光標(biāo)懸停其上時(shí),立方體自動(dòng)打開(kāi)來(lái)。操作方法是:把立方體的面移動(dòng)到與中心一定距離的地方。第二組CSS屬性有一個(gè) :hover選擇器,將立方體的面放置在更遠(yuǎn)的距離。通過(guò)運(yùn)用第一種轉(zhuǎn)換屬性,你將看到立方體從中心盤(pán)旋打開(kāi),同時(shí)還保持旋轉(zhuǎn)(演示)。

          可縮放的矢量圖像(SVG)

          HTML與CSS都是強(qiáng)大的動(dòng)畫(huà)技術(shù),但缺乏繪圖基元。SVG能夠彌補(bǔ)這點(diǎn),并擁有其獨(dú)特的動(dòng)畫(huà)標(biāo)簽。SVG動(dòng)畫(huà)部分被特定稱為同步多媒體集成語(yǔ)言(SMIL)。

          首先,SVG是用于矢量基元的,比如矩形、圓形和貝塞爾曲線:

          <svg> <rect x="5" y="5" width="140" height="140" stroke="#000000" strokewidth="4"fill="#AAAAFF" opacity="1"/></svg>

          同樣可用于:

          <line x1 y1 x2 y2><circle cx cy r><path d><image x y width height xlink:href>

          其中一個(gè)基元,<path>標(biāo)簽,是SVG中最好用的。它允許你使用直線、弧和貝塞爾曲線定義任意路徑。路徑定義看上去想一個(gè)字母,如同Inkscape矢量圖形軟件生成的。對(duì)于SVG動(dòng)畫(huà),你應(yīng)該理解這一點(diǎn)。

          一個(gè)二次和三次貝塞爾曲線的例子:

          <svg> <path d="M 30,240 Q 170,40 260,230" stroke="#F00" /> <path d="M 30,240 C 70,90 210,150 260,230" stroke="#F00" /></svg>

          語(yǔ)法:

          M x,y ? ? 新的起點(diǎn) (標(biāo)記)

          L x,y ? ? ?到哪里的直線

          Q cx, cy, x, y ?二次貝塞爾曲線到 (x,y)和一個(gè)控制點(diǎn)

          C cx,cy, dx,dy, x,y 三次貝塞爾曲線到(x, y)和兩個(gè)控制點(diǎn)

          A ? ? ? 橢圓弧

          z ? ? ? 字符串最后,用于結(jié)束路徑

          讓我們把這些矢量變得更生動(dòng)化。你可以查看演示,一個(gè)家伙踏著滑板翱翔于白云間。

          沖浪板上下擺動(dòng),小人的嘴巴在大和更大的笑容間交替變化,眼睛滾動(dòng),瞳孔擴(kuò)張。這是SVG動(dòng)畫(huà)四種可能的類型。

          最簡(jiǎn)單的一種SVG動(dòng)畫(huà)運(yùn)用<animate>標(biāo)簽,改變一種幾何形狀的一個(gè)參數(shù),在本例中,就是眼睛的半徑。

          要使瞳孔擴(kuò)張,需要改變屬性列表值中的半徑值。

          <circle cx="200" cy="205" r="80" > <animate dur="3s" attributeName="r" values="80; 150; 80" repeatCount="indefinite" /></circle>

          方便的是變化的屬性還可以成為<path>標(biāo)簽。允許你創(chuàng)建一個(gè)動(dòng)畫(huà)路徑。 唯一的限制是兩個(gè)曲線之間要進(jìn)行轉(zhuǎn)換,必須是同一種類型且擁有相同數(shù)量的控制點(diǎn)。它們必須由相同位置上的同一個(gè)字母定義,唯一不同的只能是參數(shù)的改變。當(dāng)移動(dòng)小人的嘴巴時(shí),只有“微笑”和“大笑”位置被定義了。SVG動(dòng)畫(huà)將完成插值。

          <path fill="#fff"> <animate attributeName="d" dur="2s" repeatCount="indefinite" values="m 0,0 c 1,15 -13,45 -45,45 -32,0 -44,-28 -44,-44 z; m 0,0 c -4,15 -66,106 -98,106 -32,0 3,-89 9,-105 z" /></path>

          當(dāng)然,SVG還能進(jìn)行幾何變換,也能做成動(dòng)畫(huà)。這里的動(dòng)畫(huà)標(biāo)簽是<animate Transform>。你必須告訴它想要將哪里的轉(zhuǎn)變做成動(dòng)畫(huà),還要提供一個(gè)分號(hào)分隔的所有關(guān)鍵位置的值列表。還可以組成動(dòng)畫(huà)轉(zhuǎn)換,你告訴瀏覽器使用additive=”sum” 屬性。

          幾何轉(zhuǎn)換的動(dòng)畫(huà):

          <g> ... <!-- SVG primitives group --> <animateTransform dur="3s" repeatCount="indefinite" additive="sum" attributeName="transform" type="translate" values="0,0; 200,-130; -100,200; 0,0" /> <animateTransform dur="3s" repeatCount="indefinite" additive="sum" attributeName="transform" type="rotate" values="0; 20; -20; 0" /></g>

          第三個(gè)和最后一個(gè)SVG動(dòng)畫(huà)標(biāo)簽也很有用。<animateMotion>用來(lái)引導(dǎo)對(duì)象沿著特定路徑運(yùn)動(dòng)。 它有一個(gè)隱藏的技巧稱為rotate=”auto”屬性。它讓對(duì)象不僅能夠遵循指定路徑,同時(shí)自身保持朝前,如同路上行駛的車輛一樣。

          <g> ... <!-- SVG primitives group --> <animateMotion dur=”1s"repeatCount="indefinite" path="m 0,0 a 15,11 0 1 1 -30,0 15,11 0 1 1 30,0 z" /></g>

          SMIL有大量控制動(dòng)畫(huà)特征。在它的JavaScript API中揭露pauseAnimations(), unpauseAnimations()和setCurrentTime(t) 函數(shù)在全局性開(kāi)始/停止/暫停一個(gè)動(dòng)畫(huà)的功能。還在所有三種動(dòng)畫(huà)標(biāo)簽(<animate>, <animateTransform>, <animateMotion>)上指定了begin與end屬性。它們可以利用一個(gè)事件節(jié)點(diǎn)/用戶事件/動(dòng)畫(huà)事件的強(qiáng)大組合。你可以指定,動(dòng)畫(huà)在點(diǎn)擊之后的一秒結(jié)束或開(kāi)始。

          例如,下面這個(gè)SVG按鈕被點(diǎn)擊后有一個(gè)移動(dòng)的陰影效果:

          <g id="buttonID"> <!-- SVG button artwork here --> <animate begin="buttonID.click" dur="1s"\ .../></g>

          HTML5繪圖

          由聲明性動(dòng)畫(huà)轉(zhuǎn)換到編程性動(dòng)畫(huà)技術(shù),<canvas>標(biāo)簽是你的第一選擇。本文所提到的所有技術(shù)中,<canvas>標(biāo)簽最具有跨瀏覽器支持,瀏覽器廠商做了很多努力使之兼容60fps動(dòng)畫(huà),以下是設(shè)置一個(gè)畫(huà)布的方法:

          <canvas width="400" height="400" style = "width: 400px; height: 400px;"></canvas>

          第一個(gè)尺寸(標(biāo)簽屬性)設(shè)置了畫(huà)布的分辨率,這就是你所使用的坐標(biāo)空間。第二個(gè)尺寸(CSS屬性)是畫(huà)布出現(xiàn)在屏幕上的形狀大小。為什么不把畫(huà)布物理尺寸設(shè)置到100%分辨率,內(nèi)部坐標(biāo)空間不變,瀏覽器為任意窗口都能正確渲染圖畫(huà)?非常遺憾,瀏覽器將畫(huà)布內(nèi)容作為點(diǎn)陣圖來(lái)掃描的,任何擴(kuò)大范圍的結(jié)果都將導(dǎo)致模糊混亂的像素。于是,把這兩個(gè)值設(shè)置成相同的值是唯一可行的選項(xiàng)。

          初始化畫(huà)布需要JavaScript中<canvas>元素,并在其上調(diào)用getContext('2d')函數(shù)。獲得的圖畫(huà)內(nèi)容對(duì)象被用來(lái)調(diào)用到畫(huà)布API。內(nèi)容是狀態(tài)性的,存儲(chǔ)三種不同的狀態(tài)信息:繪畫(huà)風(fēng)格,即時(shí)幾何轉(zhuǎn)換以及累計(jì)繪圖路徑。在畫(huà)布上進(jìn)行繪畫(huà)的方法是發(fā)布繪圖指令,不產(chǎn)生任何可見(jiàn)內(nèi)容,但在內(nèi)存中已創(chuàng)建了一個(gè)路徑,然后發(fā)布一個(gè)油墨指令(ctx.stroke(), ctx.fill() 或兩者皆有),就能顯示出路徑了。

          逐幀動(dòng)畫(huà)

          畫(huà)布動(dòng)畫(huà)需要設(shè)置一個(gè)動(dòng)畫(huà)循環(huán),你應(yīng)當(dāng)基于requestAnimationFrame()函數(shù)(帶有正確的前綴)。該函數(shù)使瀏覽器能夠管理幀率,在瀏覽器選項(xiàng)卡隱藏時(shí)也能停止動(dòng)畫(huà)。

          function runAnimation(){ yourWorld.draw() // this is your drawing code webkitRequestAnimationFrame(runAnimation);}

          一般來(lái)說(shuō),畫(huà)布被用于動(dòng)畫(huà)的時(shí)候,對(duì)象的位置必須是在逐幀的基礎(chǔ)上才行,這是因?yàn)樗鼈兌际俏锢矸抡娴慕Y(jié)果。觀看box2dweb.js教程。仿真不斷改變仿真世界中對(duì)象的位置,動(dòng)畫(huà)循環(huán)周期性的在屏幕上展現(xiàn)當(dāng)前環(huán)境狀態(tài)。

          畫(huà)布SVG精靈

          在畫(huà)布動(dòng)畫(huà)中使用SVG精靈是一種很有用的技巧。一個(gè)任意復(fù)雜性的靜態(tài)矢量圖片在畫(huà)布上呈現(xiàn)都是繁瑣的,這樣做實(shí)際上可行,雖然不如發(fā)送一個(gè).svg到 ctx.drawImage()簡(jiǎn)單。出于模糊安全的原因,只有內(nèi)聯(lián)SVG支持,你必須在Blob API中使用它(代碼)。

          SVG精靈能夠以任意比例展示其矢量美態(tài),但遺憾的是,只支持Chrome瀏覽器。

          使用WebGL

          WebGL暴露瀏覽器運(yùn)行的JavaScript應(yīng)用程序OpenGL API,而不需要任何插件。理論上講,你只需要在<canvas> 元素上調(diào)用getContext(‘webgl’)(而不是之前的2d)就可以了。然而,WebGL非常大,并且API等級(jí)低。最重要的是,web版本沒(méi)有默認(rèn)的渲染路徑,這意味著你無(wú)法給它一個(gè)形狀,讓它使用適合的默認(rèn)值展示出來(lái)。所以你必須編寫(xiě)著色器,使用GLSL語(yǔ)言編寫(xiě)屏幕上出現(xiàn)的任何內(nèi)容。

          幸運(yùn)的是我們有Three.js幫助。Three最初是由Mr.doob開(kāi)發(fā)的庫(kù),用于一些Chrome演示(www.ro.me/www.chaostoperfection.com),但它是相對(duì)獨(dú)立的。它擁有所有的基礎(chǔ),以及內(nèi)置獨(dú)特的著色器,你就可以專注于其他有用的方面:相機(jī)、燈光、行動(dòng)。

          首先要做的是編寫(xiě)Three粘合代碼(很簡(jiǎn)單):

          var renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(width, height);renderer.setClearColorHex(0x000000, 0); // color,transparency// the renderer creates a canvas elementfor youdocument.whereeveryouwant.appendChild(renderer.domElement);

          在lights和action之前,需創(chuàng)建camera和位置:

          // arguments: FOV,viewAspectRatio, zNear, zFarvar camera = new THREE.PerspectiveCamera(35,width/height, 1, 10000);camera.position.z = 300;

          然后是light:

          var light = new THREE.DirectionalLight(0xffffff, 1);//color, intensitylight.position.set(1, 1, 0.3); // direction

          我們?cè)囍尸F(xiàn)一個(gè)立方體吧,3D對(duì)象在Three中被稱為網(wǎng)絡(luò),都由一個(gè)幾何體和一個(gè)材料構(gòu)成。

          我們使用一個(gè)簡(jiǎn)單的結(jié)構(gòu):

          var texture = THREE.ImageUtils.loadTexture(‘Fernando Togni.jpg’);var cube = new THREE.Mesh( new THREE.CubeGeometry(100, 100, 100), new THREE.MeshLambertMaterial({map: texture}) );

          最后添加內(nèi)容,稱為渲染函數(shù)。

          var scene = new THREE.Scene();scene.add(cube);scene.add(light);renderer.render(scene, camera);

          這將為我們的立方體產(chǎn)生一個(gè)靜態(tài)圖像,為了讓它動(dòng)起來(lái),我們包裹渲染召集一個(gè)動(dòng)畫(huà)循環(huán),改變立方體在每一幀的位置。

          function runAnimation(t){ // animate your objects depending on time cube.rotation.y = t/1000; cube.position.x = ... renderer.render(scene, camera); // display requestAnimationFrame(runAnimation); // and loop}

          推薦使用三維建模軟件例如Sketchup。Three識(shí)別幾類3D模型結(jié)構(gòu),包括COLLADA(.dae)具有廣泛行業(yè)支撐。下面是如何在Three中加載一個(gè)模型:

          var loader = new THREE.ColladaLoader();loader.load("Android.dae", function(collada){ var model = collada.scene; model.position = ...; // x, y, z model.rotation = ...; // x, y, z scene.add(model);} );

          再做一些努力,更換機(jī)器人外觀花式,Three提供蘭伯特和馮氏照明風(fēng)格,法線貼圖,凹凸貼圖,環(huán)境映射以及更多。

          還可以使機(jī)器人運(yùn)動(dòng)起來(lái),具體步驟參考教程。

          原文鏈接:http://www.gbtags.com/gb/share/2124.htm

          tml:

          <!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>玻璃效果網(wǎng)站</title>
                  <link href="../css/20240302.css" rel="stylesheet">
              </head>
              <body>
                  <main>
                      <section class="glass">
                          <div class="dashboard">
                              <div class="user">
                                  <img src="./image/20240302/photo1.png" alt="">
                                  <h3>
                                      Demo
                                  </h3>
                                  <p>Pro Member</p>
                              </div>
                              <div class="links">
                                  <div class="link">
                                      <img src="./image/20240302/Streams.png" alt="" />
                                      <h2>Streams</h2>
                                  </div>
                                  <div class="link">
                                      <img src="./image/20240302/Games.png" alt="" />
                                      <h2>Games</h2>
                                  </div>
                                  <div class="link">
                                      <img src="./image/20240302/news.png" alt="" />
                                      <h2>New</h2>
                                  </div>
                                  <div class="link">
                                      <img src="./image/20240302/Library.png" alt="" />
                                      <h2>Library</h2>
                                  </div>
                              </div>
                              <div class="pro">
                                  <h2>Join pro for free games.</h2>
                                  <img src="./image/20240302/show_128.png" alt="" />
                              </div>
                          </div>
                          <div class="games">
                              <div class="status">
                                  <h1>Active Games</h1>
                                  <input type="text" />
                              </div>
                              <div class="cards">
                                  <div class="card">
                                      <img src="./image/20240302/20240302_1.png" alt="" />
                                      <div class="card-info">
                                          <h2>惡 魔 之 魂</h2>
                                          <p>PS5 Version</p>
                                          <div class="progress"></div>
                                      </div>
                                      <h2 class="percentage">60%</h2>
                                  </div>
                                  <div class="card">
                                      <img src="./image/20240302/20240302_2.png" alt="" />
                                      <div class="card-info">
                                          <h2>無(wú) 路 之 旅</h2>
                                          <p>PS5 Version</p>
                                          <div class="progress"></div>
                                      </div>
                                      <h2 class="percentage">60%</h2>
                                  </div>
                                  <div class="card">
                                      <img src="./image/20240302/20240302_3.png" alt="" />
                                      <div class="card-info">
                                          <h2>麻布仔大冒險(xiǎn)</h2>
                                          <p>PS5 Version</p>
                                          <div class="progress"></div>
                                      </div>
                                      <h2 class="percentage">60%</h2>
                                  </div>
                              </div>
                          </div>
                      </section>
                  </main>
                  <div class="circle1"></div>
                  <div class="circle2"></div>
              </body>
          </html>

          Css:

          * {
              margin: 0;
              padding: 0;
              box-sizing: border-box;
          }
          
          h1{
              color: #426696;
              font-weight: 600;
              font-size: 3rem;
              opacity: 0.8;
          }
          
          h2, 
          p{
              color: #658ec6;
              font-weight: 500;
              opacity: 0.8;
          }
          
          h3{
              color: #426696;
              font-weight: 600;
              opacity: 0.8;
          }
          
          main {
              font-family: "Poppins", sans-serif;
              min-height: 100vh;
              background: linear-gradient(to right top, #ffcb06, #ec9c07);
              display: flex;
              align-items: center;
              justify-content: center;
          }
          
          .glass{
              background: white;
              min-height: 80vh;
              width: 60%;
              background: linear-gradient(
                  to right bottom, 
                  rgba(255, 255, 255, 0.7), 
                  rgba(255, 255, 255, 0.3)
              );
              border-radius: 2rem;
              z-index: 2;
              backdrop-filter: blur(2rem);
              display: flex;
          }
          
          .circle1,.circle2{
              background: white;
              background: linear-gradient(
                  to right bottom, 
                  rgba(255, 255, 255, 0.8), 
                  rgba(255, 255, 255, 0.3)
              );
              height: 20rem;
              width: 20rem;
              position: absolute;
              border-radius: 50%;
          }
          
          .circle1{
              top: 5%;
              right: 15%;
          }
          
          .circle2{
              bottom: 5%;
              left: 10%;
          }
          
          .dashboard{
              flex: 1;
              display: flex;
              flex-direction: column;
              align-items: center;
              justify-content: space-evenly;
              text-align: center;
              background: linear-gradient(
                  to right bottom, 
                  rgba(255, 255, 255, 0.7), 
                  rgba(255, 255, 255, 0.3)
              );
              border-radius: 2rem;
          }
          
          .link{
              display: flex;
              margin: 2rem 0rem;
              padding: 1rem 5rem;
              align-items: center;
          }
          
          .link h2{
              padding: 0rem 1rem;
          }
          
          .games{
              flex: 2;
          }
          
          .pro{
              background: linear-gradient(to right top, #ffcb06, #ec9c07);
              border-radius: 2rem;
              color: white;
              padding: 1rem;
              position: relative;
          }
          
          .pro img{
              position: absolute;
              top: 5%;
              right: 8%;
          }
          
          .pro h2{
              width: 40%;
              color: white;
              font-weight: 600;
          }
          
          .status{
              margin-bottom: 3rem;
          
          }
          
          .status input{
              background: linear-gradient(
                  to right bottom, 
                  rgba(255, 255, 255, 0.7), 
                  rgba(255, 255, 255, 0.3)
              );
              border: none;
              width: 50%;
              padding: 0.5rem;
              border-radius: 2rem;
          }
          
          .games{
              margin: 5rem;
              display: flex;
              flex-direction: column;
              justify-content: space-evenly;
          }
          
          .card{
              display: flex;
              background: linear-gradient(
                  to left top, 
                  rgba(255, 255, 255, 0.8), 
                  rgba(255, 255, 255, 0.5)
              );
              border-radius: 1rem;
              margin: 2rem 0rem;
              padding: 2rem;
              box-shadow: 6px 6px 20px rgba(122, 122, 122, 0.212);
              justify-content: space-between;
          }
          
          .card-info{
              display: flex;
              flex-direction: column;
              justify-content: space-between;
          }
          
          .progress{
              background: linear-gradient(to right top, #ffcb06, #ec9c07);
              width: 100%;
              height: 25%;
              border-radius: 1rem;
              position: relative;
              overflow: hidden;
          }
          
          .progress::after {
              content: "";
              width: 100%;
              height: 100%;
              background: rgba(236, 236, 236);
              position: absolute;
              left: 60%;
          }
          
          .percentage{
              font-weight: bold;
              background: linear-gradient(to right top, #ffcb06, #ec9c07);
              -webkit-background-clip: text;
              -webkit-text-fill-color: transparent;
          }


          效果


          主站蜘蛛池模板: 痴汉中文字幕视频一区| 日本免费一区二区三区最新vr| 人妻天天爽夜夜爽一区二区| 成人免费一区二区无码视频| 亚洲一区二区三区AV无码| 精品国产天堂综合一区在线| 性色av一区二区三区夜夜嗨 | 在线日韩麻豆一区| 日本一区二区免费看| 波多野结衣的AV一区二区三区| 日本精品视频一区二区三区| 中文字幕日韩一区二区三区不卡| 久久国产香蕉一区精品| 无码人妻精品一区二| 国产精品亚洲综合一区在线观看| 日本一区二区三区爆乳| 蜜臀AV在线播放一区二区三区| 激情内射日本一区二区三区| 大伊香蕉精品一区视频在线| 一区二区三区高清在线| 亚洲av片一区二区三区| 一区二区三区四区在线视频| 日本人真淫视频一区二区三区| 日韩精品一区二区三区不卡| 国产日韩精品一区二区在线观看| 国产麻豆精品一区二区三区| 在线视频国产一区| 日韩精品电影一区亚洲| 一区二区三区四区在线视频 | 亚洲电影一区二区三区| 国产激情视频一区二区三区| 日本成人一区二区| 91在线视频一区| eeuss鲁片一区二区三区| 国产福利一区二区精品秒拍| 精品一区二区三区视频在线观看 | 国产一区二区视频在线播放| 中文字幕在线精品视频入口一区 | 日韩在线一区视频| 亚洲国产综合精品一区在线播放| 国产日韩高清一区二区三区 |