zoukankan      html  css  js  c++  java
  • JavaScript图形实例:利用插值实现图像渐变

          描述由一个图形变化为另一个图形过程中的各个中间图形,称为渐变图形。可以利用插值算法求得各个渐变图形。

          设在源图形和目标图形上各取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 正五边形渐变为五瓣花朵

  • 相关阅读:
    HAProxy、Keepalived 在 Ocatvia 的应用实现与分析
    Octavia 的 HTTPS 与自建、签发 CA 证书
    Octavia 创建 loadbalancer 的实现与分析
    OpenStack Rally 质量评估与自动化测试利器
    自建 CA 中心并签发 CA 证书
    Failed building wheel for netifaces
    通过 vSphere WS API 获取 vCenter Datastore Provisioned Space 置备空间
    OpenStack Placement Project
    我们建了一个 Golang 硬核技术交流群(内含视频福利)
    没有图形界面的软件有什么用?
  • 原文地址:https://www.cnblogs.com/cs-whut/p/13193830.html
Copyright © 2011-2022 走看看