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 久久精品一区二区三区四区,国产精品第页,成人永久免费视频

          整合營銷服務(wù)商

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

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

          HTML5(九)-超強(qiáng)的 SVG 動(dòng)畫

          VG 動(dòng)畫有很多種實(shí)現(xiàn)方法,也有很大SVG動(dòng)畫庫,現(xiàn)在我們就來介紹 svg動(dòng)畫實(shí)現(xiàn)方法都有哪些?

          一、SVG 的 animation

          SVG animation 有五大元素,他們控制著各種不同類型的動(dòng)畫,分別為:

          • set
          • animate
          • animateColor
          • animateTransform
          • animateMotion

          1.1、set

          set 為動(dòng)畫元素設(shè)置延遲,此元素是SVG中最簡單的動(dòng)畫元素,但是他并沒有動(dòng)畫效果。

          使用語法:

          <set attributeName="" attributeType="" to="" begin="" />
          • attributeName :是要改變的元素屬性名稱。
          • attributeType :是表明attributeName屬性值的列表,支持三個(gè)固定參數(shù) CSS/XML/auto,如x,y以及transform屬于XML,opacity屬于CSS。auto是瀏覽器自動(dòng)判別的意思,也是默認(rèn)值,如果你不知道該選哪個(gè)就填auto,瀏覽器自己判別。
          • to :動(dòng)畫結(jié)束的屬性值。
          • begin :動(dòng)畫延遲時(shí)間。

          eg:繪制一個(gè)半徑為200的圓,4秒之后,半徑變?yōu)?0。

          <svg width="320" height="320">
           <circle cx="0" cy="0" r="200" style="stroke: none; fill: #0000ff;">
            <set attributeName="r" attributeType="XML" to="50" begin="4s" />
           </circle>
          </svg>

          1.2、animate

          是基礎(chǔ)的動(dòng)畫元素,實(shí)現(xiàn)單屬性的過渡效果。

          使用語法:

          <animate 
           attributeName="r" 
           from="200" to="50" 
           begin="4s" dur="2s" 
           repeatCount="2"
          ></animate>
          • from :過渡效果的屬性開始值。
          • to:過渡效果的屬性結(jié)束值。
          • begin:動(dòng)畫開始時(shí)間。
          • dur:動(dòng)畫過渡時(shí)間,控制動(dòng)畫速度。
          • repeatCount:動(dòng)畫重復(fù)次數(shù)。

          eg:繪制一個(gè)半徑為200的圓,4秒之后半徑在2秒內(nèi)從200逐漸變?yōu)?0。

          <circle cx="0" cy="0" r="200" style="stroke: none; fill: #0000ff;">
           <animate attributeName="r" from="200" to="50" 
            begin="4s" dur="2s" repeatCount="2"></animate>
          </circle>

          1.3、animateColor

          控制顏色動(dòng)畫,animate也可以實(shí)現(xiàn)這個(gè)效果,所以該屬性目前已被廢棄。

          1.4、animateTransform

          實(shí)現(xiàn)transform變換動(dòng)畫效果,與css3的transform變換類似。實(shí)現(xiàn)平移、旋轉(zhuǎn)、縮放等效果。

          使用語法:

          <animateTransform attributeName="transform"  type="scale" 
           from="1.5" to="0" 
           begin="2s"  dur="3s" 
           repeatCount="indefinite"></animateTransform>
          • repeatCount:重復(fù)次數(shù),設(shè)置為 indefinite 表示無限循環(huán),一直執(zhí)行。
          • type:添加 transform 變換類型。
          • eg:繪制一個(gè)半徑為200的圓,4秒之后開始縮放,在2秒內(nèi)從1.5縮小到0倍。
          <svg width="320" height="320">
           <circle cx="0" cy="0" r="200" style="stroke: none; fill: #0000ff;">
            <animateTransform attributeName="transform" begin="4s"  
             dur="2s" type="scale" from="1.5" to="0" 
             repeatCount="indefinite"></animateTransform>
           </circle>
          </svg>

          1.5、animateMotion

          可以定義動(dòng)畫路徑,讓SVG各個(gè)圖形,沿著指定路徑運(yùn)動(dòng)。

          使用語法:

          <animateMotion 
           path="M 0 0 L 320 320" 
          begin="4s" dur="2s"></animateMotion>
          • path:定義路徑,使用語法與《HTML5(八)——SVG 之 path 詳解》path的d屬性一致。
          • begin:延遲時(shí)間。
          • dur:動(dòng)畫執(zhí)行時(shí)間。

          eg:繪制一個(gè)半徑為10的圓,延遲4秒從左上角運(yùn)動(dòng)的右下角。

          <svg width="320" height="320">
           <circle cx="0" cy="0" r="10" style="stroke: none; fill: #0000ff;">
            <animateMotion 
             path="M 0 0 L 320 320" 
             begin="4s" dur="2s"
             ></animateMotion>
           </circle>
          </svg>

          實(shí)際制作動(dòng)畫的時(shí)候,動(dòng)畫太單一不酷,需要同時(shí)改變多個(gè)屬性時(shí),上邊的四種元素可以互相組合,同類型的動(dòng)畫也能組合。以上這些元素雖然能夠?qū)崿F(xiàn)動(dòng)畫,但是無法動(dòng)態(tài)地添加事件,所以接下來我們就看看 js 如何制作動(dòng)畫。

          二、JavaScript 控制

          上篇文章我們介紹js可以操作path,同樣也可以操作SVG的內(nèi)置形狀元素,還可以給任意元素添加事件。

          給SVG元素添加事件方法與普通元素一樣,可以只用on+事件名 或者addEventListener添加。

          eg:使用SVG繪制地一條線,點(diǎn)擊線條地時(shí)候改變 x1 ,實(shí)現(xiàn)旋轉(zhuǎn)效果。

          <svg width="800" height="800" id="svg">
              <line id="line" x1="100" y1="100" 
              x2="400" y2="300" 
              stroke="black" stroke-width="5"></line>  
            </svg>
          <script>
           window.onload = function(){
            var line = document.getElementById("line")
            line.onclick = function(){
             let start = parseInt(line.getAttribute("x1")),
                 end=400,dis = start-end
             requestAnimationFrame(next)
             let count = 0;
             function next(){
              count++
              let a = count/200,cur = Math.abs(start+ dis*a)
              line.setAttribute('x1',cur)
              if(count<200)requestAnimationFrame(next)
             }
            }
           }
          </script>

          js制作的SVG動(dòng)畫,主要利用 requestAnimationFrame 來實(shí)現(xiàn)一幀一幀的改變。

          我們上述制作的 SVG 圖形、動(dòng)畫等,運(yùn)行在低版本IE中,發(fā)現(xiàn)SVG只有IE9以上才支持,低版本的并不能支持,為了兼容低版本瀏覽器,可以使用 VML ,VML需要添加額外東西,每個(gè)元素需要添加 v:元素,樣式中還需要添加 behavier ,經(jīng)常用于繪制地圖。由于使用太麻煩,所以我們借助 Raphael.js 庫。

          三、Rapha?l.js (拉斐爾)

          Raphael.js是通過SVG/VML+js實(shí)現(xiàn)跨瀏覽器的矢量圖形,在IE瀏覽器中使用VML,非IE瀏覽器使用SVG,類似于jquery,本質(zhì)還是一個(gè)javascript庫,使用簡單,容易上手。

          使用之前需要先引入Raphael.js庫文件。cdn的地址為:https://cdn.bootcdn.net/ajax/libs/raphael/2.3.0/raphael.js

          3.1、創(chuàng)建畫布

          Rapheal有兩種創(chuàng)建畫布的方式:

          第一種:瀏覽器窗口上創(chuàng)建畫布

          創(chuàng)建語法:

          var paper = Raphael(x,y,width,height)

          x,y是畫布左上角的坐標(biāo),此時(shí)畫布的位置是絕對定位,有可能會(huì)與其他html元素重疊。width、height是畫布的寬高。

          第二種:在一個(gè)元素中創(chuàng)建畫布

          創(chuàng)建語法:

          var paper = Raphael(element, width, height);

          element是元素節(jié)點(diǎn)本身或ID width、height是畫布的寬度和高度。

          3.2、繪制圖形

          畫布創(chuàng)建好之后,該對象自帶SVG內(nèi)置圖形有矩形、圓形、橢圓形。他們的方法分別為:

          paper.circle(cx, cy, r); // (cx , cy)圓心坐標(biāo) r 半徑
          paper.rect(x, y, width, height, r); // (x,y)左上角坐標(biāo) width寬度 height高度 r圓角半徑(可選)
          paper. ellipse(cx, cy, rx, ry); // (cx , cy)圓心坐標(biāo) rx水平半徑 ry垂直半徑

          eg:在div中繪制一個(gè)圓形,一個(gè)橢圓、一個(gè)矩形。

          <div id="box"></div>
          <script>
           var paper = Raphael("box",300,300)
           paper.circle(150,150,150)
           paper.rect(0,0,300,300)
           paper.ellipse(150,150,100,150)
          </script>

          運(yùn)行結(jié)果如下:

          除了簡單圖形之外,還可以繪制復(fù)雜圖形,如三角形、心型,這時(shí)就使用path方法。

          使用語法:paper.path(pathString)

          pathString是由一個(gè)或多個(gè)命令組成,每個(gè)命令以字母開始,多個(gè)參數(shù)是由逗號分隔。

          eg:繪制一個(gè)三角形。

          let sj = paper.path("M 0,0 L100,100 L100,0 'Z'")

          還可以繪制文字,如果需要換行,使用 \n 。

          文字語法:paper.text(x,y,text)

          (x,y)是文字坐標(biāo),text是要繪制的文字。

          3.3、設(shè)置屬性

          圖形繪制之后,我們通常會(huì)添加stroke、fill、stroke-width等讓圖形更美觀,Raphael使用attr給圖形設(shè)置屬性。

          使用語法:circle.attr({"屬性名","屬性值","屬性名","屬性值",...})

          如果只有屬性名沒有屬性值,則是獲取屬性,如果有屬性值,則是設(shè)置屬性。

          注意:如果只設(shè)置一個(gè)屬性時(shí),可以省略‘{}’。如:rect.attr('fill','pink')

          eg:給上邊的矩形添加邊框和背景色。

          <div id="box"></div>
          <script>
           var paper = Raphael("box",300,300)
           let rect = paper.rect(100,100,150,200)
           rect.attr({'fill':'red','stroke':'blue','stroke-width':'10'})
          </script>

          3.4、添加事件

          RaphaelJS一般具有以下事件:
          click、dblclick、drag、hide、hover、mousedown、mouseout、mouseup、mouseover等以及對應(yīng)的解除事件,只要在前面加上“un”就可以了(unclick、undblclick)。

          使用語法:

          obj.click(function(){
           //需要操作的內(nèi)容
          })

          3.5、添加動(dòng)畫

          animate為指定圖形添加動(dòng)畫并執(zhí)行。

          使用語法:

          obj.animate({
           "屬性名1":屬性值1,
           "屬性名2":屬性值2,
            ...
          },time,type)

          屬性名和屬性值就根據(jù)你想要的動(dòng)畫類型加就ok。

          time:動(dòng)畫所需時(shí)間。

          type:指動(dòng)畫緩動(dòng)類型。常用值有:

          • linear - 線性漸變
          • ease-in | easeIn | < - 由慢到快
          • ease-out | easeOut | > - 由快到慢
          • ease-in-out | easeInOut | <> - 由慢到快再到慢
          • back-in | backIn - 開始時(shí)回彈
          • back-out | backOut - 結(jié)束時(shí)回彈
          • elastic - 橡皮筋
          • bounce - 彈跳

          eg:點(diǎn)擊矩形,矩形緩緩變大。

          <div id="box"></div>
          <script>
           var paper = Raphael("box",800,500)
           let rect = paper.rect(100,100,150,100)
           rect.attr({'fill':'red','stroke':'blue','stroke-width':'10'})
           rect.attr('fill','pink')
           rect.click(function(){
            rect.animate({
             "width":300,
             "height":300
            },1000,"bounce")
           })
          </script>

          復(fù)制上邊的代碼,分別在各個(gè)瀏覽器和低版本IE瀏覽器運(yùn)行,發(fā)現(xiàn)都可以正常運(yùn)行。SVG的動(dòng)畫庫挺多了,我們介紹了拉斐爾,有興趣的小伙伴可以自行找找其他庫。


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

          揭示概念

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

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

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

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

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

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

          入門

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

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

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

          讓我們訪問畫布及其上下文。

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

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

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

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

          #canvas {
            background: #00b4ff;
          }

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

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

          canvas.addEventListener('click', handleDrawCircle);

          由于我們需要知道在畫布上單擊的位置,因此我們將在句柄 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);
          };

          用圓弧法畫圓

          為了創(chuàng)建圓圈,我們將利用畫布上下文中可用的 arc 方法。 Arc 方法接受 x 和 y - 圓心、半徑、起始角和結(jié)束角,對于我們來說,這將是 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



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

          //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;
          };

          為了讓我們的圓圈無縫移動(dòng),我們將創(chuàng)建一個(gè)動(dòng)畫函數(shù)并使用瀏覽器的 requestAnimationFrame 方法來創(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)畫的構(gòu)建塊。 每個(gè)氣泡都是一個(gè)粒子,具有自己的位置、大小、運(yùn)動(dòng)和顏色屬性。 讓我們定義一個(gè) Particle 類來封裝這些屬性:

          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é)在畫布上渲染粒子。 我們已經(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() {}
          }

          同樣,讓我們在類中移動(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ù)中訪問該粒子,以便調(diào)用其 move 方法,因此我們將該粒子存儲在一個(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)畫功能 -

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



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

          為了創(chuàng)建大量氣泡,我們將使用 for 循環(huán)創(chuàng)建粒子并將它們添加到我們在此處創(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)畫函數(shù)中,我們將通過清除畫布并在新位置重新繪制粒子來不斷更新畫布。 這會(huì)給人一種圓圈在移動(dòng)的錯(cuò)覺。

          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í)候給它們添加顏色,使它們看起來像氣泡了!

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

          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īng)學(xué)習(xí)了如何使用 arc 方法、利用 requestAnimationFrame、利用 JavaScript 類的強(qiáng)大功能以及使用漸變設(shè)計(jì)氣泡以實(shí)現(xiàn) 3D 氣泡效果。

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

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

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


          主站蜘蛛池模板: 精品午夜福利无人区乱码一区| 日韩精品人妻一区二区中文八零 | 一区二区三区观看免费中文视频在线播放| 夜色福利一区二区三区| 国产亚洲综合精品一区二区三区 | 久久久一区二区三区| 日韩av片无码一区二区三区不卡| 人妻aⅴ无码一区二区三区| 亚洲一区二区三区乱码A| 国产亚洲综合精品一区二区三区 | 国产一区玩具在线观看| 免费一区二区无码视频在线播放| 色一情一乱一区二区三区啪啪高 | 国产在线视频一区| 国产美女口爆吞精一区二区| 精品一区二区三区在线观看l| 亚洲日本va午夜中文字幕一区| 国模精品一区二区三区| 精品亚洲一区二区三区在线播放| 人成精品视频三区二区一区| 在线观看国产一区二区三区| 国产在线一区二区视频| 国产伦精品一区二区三区免.费| 美女视频一区二区三区| 在线日韩麻豆一区| 精品一区二区三区免费视频| 中文字幕日韩人妻不卡一区 | 波多野结衣一区在线| 日美欧韩一区二去三区| 国产在线观看一区二区三区 | 国产乱子伦一区二区三区| 亚洲高清毛片一区二区| 国产91精品一区| 99久久精品国产免看国产一区| 国产精品一区二区av| 人妻久久久一区二区三区| 一本久久精品一区二区| 日韩电影在线观看第一区| 国产精品一区在线观看你懂的| 久久亚洲一区二区| eeuss鲁片一区二区三区|