JavaScript圖形實例:利用插值實現圖像漸變

来源:https://www.cnblogs.com/cs-whut/archive/2020/06/26/13193830.html
-Advertisement-
Play Games

描述由一個圖形變化為另一個圖形過程中的各個中間圖形,稱為漸變圖形。可以利用插值演算法求得各個漸變圖形。 設在源圖形和目標圖形上各取M個對應坐標點,並分別保存到數組中,源圖形用數組SX[M]和SY[M]保存M個坐標點(sx,sy),目標圖形用數組DX[M]和DY[M]保存M個坐標點(dx,dy)。若需生 ...


      描述由一個圖形變化為另一個圖形過程中的各個中間圖形,稱為漸變圖形。可以利用插值演算法求得各個漸變圖形。

      設在源圖形和目標圖形上各取M個對應坐標點,並分別保存到數組中,源圖形用數組SX[M]和SY[M]保存M個坐標點(sx,sy),目標圖形用數組DX[M]和DY[M]保存M個坐標點(dx,dy)。若需生成源圖形變換到目標圖形中的N-1個漸變圖形,採用簡單的線性插值可以編寫如下的二重迴圈:

     for (k=1;k<N;k++)

         for (i=0;i<M;i++)

         {

            x=(dx[i]-sx[i])/N*k+sx[i];

            y=(dy[i]-sy[i])/N*k+sy[i];

            // 按求得的插值坐標點繪製漸變圖形

         }

1.六瓣花朵漸變為圓

六瓣花朵的笛卡爾坐標方程式設定為:

    t=r1*(1+sin(18*θ)/5) *(0.5+Math.sin(6*θ)/2);

    x=t*cos(θ);

    y=t* sin(θ);       (0≤θ≤2π)

圓的笛卡爾坐標方程式為:

x=r*cos(θ)

y=r*sin(θ)         (0≤θ≤2π)

在六瓣花朵和圓上分別取128個點,然後利用簡單的線性插值繪製中間24個漸變圖形。編寫如下的HTML代碼。

<!DOCTYPE html>

<head>

<title>六瓣花朵漸變為圓</title>

<script type="text/javascript">

  function draw(id)

  {

     var canvas=document.getElementById(id);

     if (canvas==null)

        return false;

     var context=canvas.getContext('2d');

     context.fillStyle="#EEEEFF";

     context.fillRect(0,0,200,200);

     context.strokeStyle="red";

     context.lineWidth=1;

     var dig=Math.PI/64;

     var x1=new Array(129);

     var y1=new Array(129);

     var x2=new Array(129);

     var y2=new Array(129);

     for (var i=0;i<=128;i++)

     {

         d=50*(1+Math.sin(18*i*dig)/5);

         t=d*(0.5+Math.sin(6*i*dig)/2);

         x1[i]=t*Math.cos(i*dig);

         y1[i]=t*Math.sin(i*dig);

         x2[i]=80*Math.cos(i*dig);

         y2[i]=80*Math.sin(i*dig);

     }

     context.beginPath();

     for (n=0;n<=25;n++)

         for (i=0;i<=128;i++)

         {

            x=(x2[i]-x1[i])/25*n+x1[i]+100;

            y=(y2[i]-y1[i])/25*n+y1[i]+100;

            if (i==0)

            {

              context.moveTo(x,y);

              bx=x;  by=y;

            }

            else

              context.lineTo(x,y);

          }

      context.lineTo(bx,by);

      context.closePath();

      context.stroke();

  }

</script>

</head>

<body onload="draw('myCanvas');">

<canvas id="myCanvas" width="200" height="200"></canvas>

</body>

</html>

將上述HTML代碼保存到一個html文本文件中,再在瀏覽器中打開包含這段HTML代碼的html文件,可以看到在畫布中繪製出從六瓣花朵漸變為圓的圖案,如圖1所示。

  

圖1  六瓣花朵漸變為圓

2.圓漸變為花朵

我們將圖1圖形中的圓漸變為六瓣花朵的過程動態展示出來。編寫的HTML文件內容如下。

<!DOCTYPE>

<html>

<head>

<title>圓漸變為花朵</title>

</head>

<body>

<canvas id="myCanvas" width="200" height="200" style="border:3px double #996633;">

</canvas>

<script type="text/javascript">

   var canvas = document.getElementById('myCanvas');

   var context = canvas.getContext('2d');

   context.fillStyle="#EEEEFF";

   context.fillRect(0,0,200,200);

   context.fillStyle = "red";

   var dig=Math.PI/64;

   var x1=new Array(129);

   var y1=new Array(129);

   var x2=new Array(129);

   var y2=new Array(129);

   var n=0;

   for (var i=0;i<=128;i++)

   {

        d=50*(1+Math.sin(18*i*dig)/5);

        t=d*(0.5+Math.sin(6*i*dig)/2);

        x1[i]=t*Math.cos(i*dig);

        y1[i]=t*Math.sin(i*dig);

        x2[i]=80*Math.cos(i*dig);

        y2[i]=80*Math.sin(i*dig);

   }

   function draw()

   {

       context.clearRect(0,0,200,200);

       context.beginPath();

       for (i=0;i<=128;i++)

       {

            x=(x1[i]-x2[i])/25*n+x2[i]+100;

            y=(y1[i]-y2[i])/25*n+y2[i]+100;

            if (i==0)

            {

              context.moveTo(x,y);

              bx=x;  by=y;

            }

            else

              context.lineTo(x,y);

      }

      context.lineTo(bx,by);

      context.stroke();

      n = n+ 1;

      if (n > 25)  n= 0;

      context.fill();

   }

   window.setInterval('draw()', 300);

</script>

</body>

</html>

將上述HTML代碼保存到一個html文本文件中,再在瀏覽器中打開包含這段HTML代碼的html文件,可以在畫布中看到從圓漸變為六瓣花朵的動畫過程,如圖2所示。

 

圖2  從圓漸變為六瓣花朵

3.六瓣花朵漸變為正方形

仿照上面的思路,設計程式將六瓣花朵漸變為正方形,且漸變計算時採用對數函數。編寫如下的HTML代碼。

   <!DOCTYPE html>

<head>

<title>六瓣花朵漸變為正方形</title>

<script type="text/javascript">

  function draw(id)

  {

     var canvas=document.getElementById(id);

     if (canvas==null)

        return false;

     var context=canvas.getContext('2d');

     context.fillStyle="#EEEEDD";

     context.fillRect(0,0,300,300);

     context.strokeStyle="red";

     context.lineWidth=1;

     var dig=Math.PI/60;

     var x1=new Array(120);

     var y1=new Array(120);

     var x2=new Array(120);

     var y2=new Array(120);

     // 生成花瓣基本數據,坐標保存在(x1[i],y1[i])中

     var petalNum=6;      // 花瓣數

     for (var i=0;i<120;i++)

     {

         d=50*(1+Math.sin(petalNum*(i*dig+Math.PI/4)));

         x1[i]=d*Math.cos(i*dig+Math.PI/4);

         y1[i]=-d*Math.sin(i*dig+Math.PI/4);

     }

     // 生成多邊形基本數據,坐標保存在(x2[i],y2[i])中

     var r=150;

     var sideNum=4;     // 正多邊形邊數

     var k=120/sideNum; 

     dig=Math.PI/sideNum;

     var dd=2*r*Math.sin(dig)/k; 

     for (i=0;i<sideNum;i++)

     {

        aa=2*i*dig+3*Math.PI/4;

        x0=r*Math.sin(aa);

        y0=r*Math.cos(aa);

        for (j=0;j<k;j++)

        {

           x2[i*k+j]=x0+j*dd*Math.sin(aa+Math.PI/2+Math.PI/sideNum);

           y2[i*k+j]=y0+j*dd*Math.cos(aa+Math.PI/2+Math.PI/sideNum);

        }

     }

     context.beginPath();

     // 按對數規律進行圖案漸變

     for (n=0;n<=25;n++)

     {

         for (i=0;i<120;i++)

         {

            x=(x2[i]-x1[i])/Math.log(25)*Math.log(n)+x1[i]+150;

            y=(y2[i]-y1[i])/Math.log(25)*Math.log(n)+y1[i]+150;

            if (i==0)

            {

              context.moveTo(x,y);

              bx=x;  by=y;

            }

            else

              context.lineTo(x,y);

          }

          context.lineTo(bx,by);

      }

      context.closePath();

      context.stroke();

  }

</script>

</head>

<body onload="draw('myCanvas');">

<canvas id="myCanvas" width="320" height="320"></canvas>

</body>

</html>

將上述HTML代碼保存到一個html文本文件中,再在瀏覽器中打開包含這段HTML代碼的html文件,可以看到在畫布中繪製出從六瓣花朵漸變為正方形的圖案,如圖3所示。

 

圖3  從六瓣花朵漸變為正方形

      將繪製圖3的HTML程式中的花瓣數設置為5,正多邊形邊數也設置為5,即修改語句“var petalNum=6;”為“var petalNum=5;”,修改語句“var sideNum=4;”為“var sideNum=5;”,則在畫布中繪製出如圖4所示的從五瓣花朵漸變為正五邊形的圖案。

  

圖4  從五瓣花朵漸變為正五邊形

4.正五邊形漸變為五瓣花朵

我們將圖4圖形中的正五邊形漸變為五瓣花朵的過程動態展示出來。編寫的HTML文件內容如下。

<!DOCTYPE>

<html>

<head>

<title>正五邊形漸變為五瓣花朵</title>

</head>

<body>

<canvas id="myCanvas" width="300" height="300" style="border:3px double #996633;"></canvas>

<script type="text/javascript">

   var canvas = document.getElementById('myCanvas');

   var context = canvas.getContext('2d');

   context.fillStyle="#EEEEFF";

   context.fillRect(0,0,300,300);

   context.fillStyle = "red";

   var dig=Math.PI/60;

   var x1=new Array(120);

   var y1=new Array(120);

   var x2=new Array(120);

   var y2=new Array(120);

   // 生成花瓣基本數據,坐標保存在(x1[i],y1[i])中

   var petalNum=5;

   for (var i=0;i<120;i++)

   {

         d=50*(1+Math.sin(petalNum*(i*dig+Math.PI/4)));

         x1[i]=d*Math.cos(i*dig+Math.PI/4);

         y1[i]=-d*Math.sin(i*dig+Math.PI/4);

   }

   // 生成多邊形基本數據,坐標保存在(x2[i],y2[i])中

   var r=150;

   var sideNum=5;

   var k=120/sideNum; 

   dig=Math.PI/sideNum;

   var dd=2*r*Math.sin(dig)/k; 

   for (i=0;i<sideNum;i++)

   {

        aa=2*i*dig+3*Math.PI/4;

        x0=r*Math.sin(aa);

        y0=r*Math.cos(aa);

        for (j=0;j<k;j++)

        {

           x2[i*k+j]=x0+j*dd*Math.sin(aa+Math.PI/2+Math.PI/sideNum);

           y2[i*k+j]=y0+j*dd*Math.cos(aa+Math.PI/2+Math.PI/sideNum);

        }

   }

   var n=0;

   function draw()

   {

       context.clearRect(0,0,300,300);

       context.beginPath();

       for (i=0;i<120;i++)

       {

            x=(x1[i]-x2[i])/Math.log(25)*Math.log(n)+x2[i]+150;

            y=(y1[i]-y2[i])/Math.log(25)*Math.log(n)+y2[i]+150;

            if (i==0)

            {

              context.moveTo(x,y);

              bx=x;  by=y;

            }

            else

              context.lineTo(x,y);

        }

        context.lineTo(bx,by);

        context.closePath();

        context.stroke();

        n = n+ 1;

        if (n > 25)  n= 0;

        context.fill();

   }

   window.setInterval('draw()', 400);

</script>

</body>

</html>

將上述HTML代碼保存到一個html文本文件中,再在瀏覽器中打開包含這段HTML代碼的html文件,可以在畫布中看到從正五邊形漸變為五瓣花朵的動畫過程,如圖5所示。

  

圖5 正五邊形漸變為五瓣花朵


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.case語句 case語句使用簡單的結構對數值做出選擇,更為重要的是,它還可以用來設置變數的值 --CASE語法格式: case input_name when 表達式 then 結果執行 …… end; 說明:首先設定一個變數的值,然後順序比較when關鍵字後面給出的值,若相等,則執行then ...
  • 目前跨端開發比較熱門的就是 React Native 和 Flutter 了,到底該選哪門技術似乎也快成了大前端圈的一個熱門話題。對於web前端來說,基於web生態的 React Native 應該是一個更加順暢而自然的選擇;但 Flutter 讓人動心的地方就是高性能和 跨端UI一致性。而Reac ...
  • 瞭解表單及其控制項 1.form:表單標簽 表單屬性: action:表單提交到哪裡 method:以什麼方式去提交到action指定的地址,有get和post,預設為get target: placeholder:表示在文本裡面預設顯示什麼文字 2.form裡面含有的控制項: input: selec ...
  • var start = "2020-6-26 20:36:00"; //開始時間 var now = new Date(); //當前時間 var ns = new Date(start).getTime() - now.getTime(); //毫秒差 //時間差 var todays = fun ...
  • /** * 多個關鍵詞列表高亮(word_list1,color1,word_list2,color2,...) * @param word_list 關鍵詞列表(例: ["關鍵詞a","關鍵詞b"],不區分大小寫) * @param color 顏色值(例: "#ff0000") * @retur ...
  • 普利姆演算法(加點法)求最小生成樹 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> ...
  • 我們在進行vue開發時會將公共的部分進行抽象,然後生成一個獨立的組件,這個組件可以被其它頁面引用,如果希望有交互的動作就設計到了值的傳遞,或者方法的回調等問題,這一次我們主要來說一下父組件和子組件的交互。 值的傳遞 子組件,通過定義了prods,然後可以實現從父組件向子組件的傳遞: <templat ...
  • 前言 computed 在 Vue 中是很常用的屬性配置,它能夠隨著依賴屬性的變化而變化,為我們帶來很大便利。那麼本文就來帶大家全面理解 computed 的內部原理以及工作流程。 在這之前,希望你能夠對響應式原理有一些理解,因為 computed 是基於響應式原理進行工作。如果你對響應式原理還不是 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...