新浦京81707con > 注册购买 > 图形渐变和图像形变换,HTML5边玩边学

原标题:图形渐变和图像形变换,HTML5边玩边学

浏览次数:138 时间:2019-08-07

一、状态及其保存和恢复

在这一节开始之前,我们要先理解一下什么是状态以及状态的保存和恢复。玩过 MFC 编程的人经常能碰到这样的代码:

pOldPen=pDC->SelectObject(pNewPen)

我们在选择一个新画笔对象的同时,总是要保存住旧画笔对象,为什么要这样做呢?因为新画笔对象只是临时用一下,等用完了,我们想恢复到原来的画笔配置时,如果旧的配置事先没有被保存,这些配置就丢失了,也就没办法恢复了。

在 HTML5 绘图中,某一刻的状态就是当前这一刻上下文对象的一系列属性的配置值,只是,决定一个画笔状态的属性比较少,如颜色、粗细、线型之类的,而确定上下文状态的属性比较多,包括下面这些:

一、为什么选择 HTML5

HTML5 边玩边学算上这篇已经是第七篇了,在这篇开始之前,我想先说明一下为什么叫“HTML5” 边玩边学,因为有人对 HTML5 提出质疑,毕竟他是一个新生事物。我承认我用 HTML5 来吸引眼球了,如果看过边玩边学系列的每一篇,你会发现前六篇文章内容的和 HTML5 关系不是太大,真正的内容其实是 2D 图形图像编程的学习笔记。

如果我们想学习 2D 编程,其实可供选择的编程环境数不胜数:MFC、Delphi都有图形图像处理功能(即GDI),Java、.Net 更不用说了,如果你支持开源,GTK、QT、wxPython 也是不错的选择,Flash 更是拿手好戏,甚至几个流行的只能手机平台应该也有 2D 模块。

如果你选择了上面任何一款编程环境学习 2D 编程,你会发现他们的内容基本上是一样的:线型、填充、颜色、渐变、图像、组合、裁剪区、变形等等,甚至连函数名很多都是一摸一样,毕竟他们的理论基础都是图形学。

Canvas入门(2):图形渐变和图像形转换,canvas渐变

来源:

 

一、图形渐变(均在风靡版谷歌(Google)中测验)

1、绘制线性渐变

   1: // 获取canvas 的ID

   2:     var canvas = document.getElementById('canvas');

   3:     if (canvas == null)

   4:     {

   5:         return false;

   6:     }

   7:     // 获取上下文

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

   9:     // 获取渐变对象

  10:     var g1 = context.createLinearGradient(0,0,0,300);

  11:     // 添加渐变颜色

  12:     g1.addColorStop(0,'rgb(255,255,0)');

  13:     g1.addColorStop(1,'rgb(0,255,255)');

  14:     context.fillStyle = g1;

  15:     context.fillRect(0,0,400,300);

  16:     var g2 = context.createLinearGradient(0,0,300,0);

  17:     g2.addColorStop(0,'rgba(0,0,255,0.5)');

  18:     g2.addColorStop(1,'rgba(255,0,0,0.5)');

  19:     for(var i = 0; i<10;i  )

  20:     {

  21:         context.beginPath();

  22:         context.fillStyle=g2;

  23:         context.arc(i*25, i*25, i*10, 0, Math.PI * 2, true);

  24:         context.closePath();

  25:         context.fill();

  26:     }

createLinearGradient(x1,y1,x2,y2):参数分别表示渐变开首地方和得了地方的横纵坐标

addColorStop(offset,color):offset代表设定的颜料离渐变初叶地方的偏移量,取值范围是0~1的浮点值。渐变伊始偏移量是0,渐变利落偏移量是1.color是潜移暗化的水彩。

效果:

葡京娱乐注册即送88 1

2、绘制径向渐变

   1: // 获取canvas 的ID

   2:     var canvas = document.getElementById('canvas');

   3:     if (canvas == null)

   4:     {

   5:         return false;

   6:     }

   7:     // 获取上下文

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

   9:     // 获取渐变对象

  10:     var g1 = context.createRadialGradient(400,0,0,400,0,400);

  11:     // 添加渐变颜色

  12:     g1.addColorStop(0.1,'rgb(255,255,0)');

  13:     g1.addColorStop(0.3,'rgb(255,0,255)');

  14:     g1.addColorStop(1,'rgb(0,255,255)');

  15:     context.fillStyle = g1;

  16:     context.fillRect(0,0,400,300);

  17:     var g2 = context.createRadialGradient(250,250,0,250,250,300);

  18:     g2.addColorStop(1,'rgba(0,0,255,0.5)');

  19:     g2.addColorStop(0.7,'rgba(255,255,0,0.5)')

  20:     g2.addColorStop(0.1,'rgba(255,0,0,0.5)');

  21:     for(var i = 0; i<10;i  )

  22:     {

  23:         context.beginPath();

  24:         context.fillStyle=g2;

  25:         context.arc(i*25, i*25, i*10, 0, Math.PI * 2, true);

  26:         context.closePath();

  27:         context.fill();

  28:     }

createRadialGradient(x1,y1,radius1,x2,y2,radius2):x1,y1,radius1分别是渐变开头圆的圆心横纵坐标和半径。x2,y2,radius2独家是渐变利落圆的圆心横纵坐标和半径。

效果

葡京娱乐注册即送88 2

二、图形转换

1、坐标转变:平移、缩放和旋转

   1: // 获取canvas 的ID

   2:     var canvas = document.getElementById('canvas');

   3:     if (canvas == null)

   4:     {

   5:         return false;

   6:     }

   7:     // 获取上下文

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

   9:     context.fillStyle = '#eeeeff';

  10:     context.fillRect(0,0,400,300);

  11:     // 平移坐标原点

  12:     context.translate(200,50);

  13:     context.fillStyle = 'rgba(255,0,0,0.25)';

  14:     for(var i = 0; i<50;i  )

  15:     {

  16:         context.translate(25,25);

  17:         // 图形缩放

  18:         context.scale(0.95,0.95);

  19:         // 图形旋转

  20:         context.rotate(Math.PI / 10);

  21:         context.fillRect(0,0,100,50);

  22:     }

translate(x,y):平移原点,x,y表示向左和向下移动多少单位,私下认可单位是像素

scale(x,y):缩放,x,y表示水平和垂直方向的缩放大小。小于1收缩,大于1放大。

rotate(angle):旋转,angle是旋转角度,单位是弧度。大于0表示顺时针旋转,反之逆时针。

效果:

葡京娱乐注册即送88 3

2、矩阵转变

   1: // 获取canvas 的ID

   2:     var canvas = document.getElementById('canvas');

   3:     if (canvas == null)

   4:     {

   5:         return false;

   6:     }

   7:     // 获取上下文

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

   9:     // 定义颜色

  10:     var colors = ['red','orange','yellow','green','blue','navy','purple'];

  11:     // 定义线宽

  12:     context.lineWidth = 10;

  13:     // 矩阵变换

  14:     context.transform(1,0,0,1,100,0);

  15:     // 循环绘制圆弧

  16:     for (var i = 0; i < colors.length; i  )

17: { //原点每一趟下移11个px

  18:          context.transform(1,0,0,1,0,10);

  19:         context.strokeStyle = colors[i];

  20:         context.beginPath();

  21:         context.arc(50,100,100,0,Math.PI,true);

  22:         context.stroke();

  23:     }

transform(m11,m12,m21,m22,dx,dy):改措施应用三个新的转移矩阵与近年来改换矩阵张开乘法运算。dx,dy代表原点坐标左移和下移的单位,默许是像素。

该转换矩阵格式如下

m11     m12   dx

m21      m22  dy

0            0         1

终极效果:

葡京娱乐注册即送88 4

计算:坐标转换的诀要均能够用transform()替代,法则如下:

1、translate(x,y)  <=>  transform(1,0,0,1,dx,dy)或transform(0,1,1,0,dx,dy),前多少个参数表示不对图片进行缩放操作。

2、scale(x,y) <=> transform(x,0,0,y,0,0)或transform(0,y,x,0,0,0),前面八个参数表示不实行移动。

3、 rotate(angle) <=> transform(Math.cos(angle*Math.PI/180),Math.sin(angle*Math.PI/180),- Math.sin(angle*Math.PI/180),Math.cos(angle*Math.PI/180),0,0)或

transform(-Math.sin(angle*Math.PI/180),Math.cos(angle*Math.PI/180),Math.cos(angle*Math.PI/180),Math.sin(angle*Math.PI/180),0,0)

 

下一篇:Canvas入门(3):图像管理和制图像和文字字

1、当前上下文对象的活动、旋转、缩放配置

 搞精晓大家确实想学习怎么样未来,其实编制程序景况只是个工具而已,大家依照个人爱好,采纳最有助于的一款来行使。其实笔者更侧重 Python 编制程序情形,只是借使本人用了Python,估量跟作者交换的人就不会太多了,我们机器里安装 Python 运维时的猜测不会太多。

您好,教您三个html5 canvas的标题: 小编在canvas中画了多个图形,有图像(image)、直线

canvas能够兑现
第一canvas要响应鼠标事件(onmousedown之类)
后来全数的图纸一定要创立相应的靶子,来记录她们所在的岗位以及大小还会有zOrder(层叠地点,在2个目的重叠的时候决定什么人在上面),相应的目的放置四个数组里并按zOrder排序
当canvas的鼠标click事件触发后,根据zOrder的次第来检查实验鼠标坐标在不在有个别对象的区域里,假如在,则进行相应的函数  

2、当前上下文对象的 strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation 属性值

那就是说为啥选取 HTML5 并非其余呢?首先,Javascript 语法简洁利落,相应的函数库小巧可是够用, HTML5 Canvas 标签的 2D 表现技能也达到了要求,Chrome 浏览器的运转速度令人满足。除外,大家不用安装笨重的购并开拓条件,不供给安装运营时,大家只需求贰个巩固功能的记事本、二个浏览器就能够去实施大家的主见,何况从来将效率表以后网络上。大家只是公布小说同别的人分享本身的主张而已,至于平台、框架、语言特色,这么些毫无干系的事物自然牵扯的越少越好,这便是自身选拔HTML5 的因由。

ps怎把图像里的一块不平整图形进行渐变色管理?

用多边形套索工具将不法规图形作为选区选取起来,然后用渐变工具渐变填充就能够了  

葡京娱乐注册即送88, 来源: 一、图形渐变(均在最新版谷歌中测量试验) 1、绘制线性渐变...

3、当前上下文对象的剪裁路线配置

据此,请大家不要误会了标题标意义:那一个种类并不是 HTML5 的学习笔记,而只是用 HTML5 来表现一些文化内容而已,你更加多关心的相应是知识和剧情笔者,你能够在其他另外一款编制程序情形下复出他们。

地方这一密密麻麻安排决定了现阶段这一刻上下文对象的事态,个中移动、旋转、缩放、globalCompositeOperation(组合)、裁剪上边大家立时会讲到。

 

 

二、动画初叶

二、状态的保存与还原

动画片正是一种类一连的镜头按梯次显示出来而已,只是,在影视TV中,这么些镜头完成已经被打算好了,而在微型Computer程序中,大家看到每一时而的镜头都以即时绘制的,大意流程能够公布如下:

上边大家说某说话的事态由那么多属性决定,大家要保留这一阵子的境况就要把这个属性值多个二个都封存,复苏的时候在三个二个都安装回去,那也太费事了。确实是如此的,所以上下文对下提供明白多少个简易的章程,对情况进行保存和借尸还魂,他们是:

a、轻微退换图形的数额(坐标、形状、颜色等等)

save( ) 和 restore( )

b、清空画布

save 和 restore 方法能够频仍调用,每调用三次 save 方法,调用时的情景(即一多元属性值)就压入三个栈中。

c、绘制图形

每调用贰次 restore 方法,最终三遍 save 的情况就被苏醒,即出栈。

d、回到步骤 a

想像一下弹匣,第一颗被发射出来的子弹,总是最后二个被压入弹匣的。

当然,这里只是给出了三个最简便的流水生产线框架,要兑现复杂的卡通片可能还要思索越来越多的标题,比方有的清除、碰撞检查实验之类的。

 

 

三、变型

其他,绘制进度中有五个速度要求调整:

1、移动:translate(dx,dy)

先是个是绘制速度,即每分钟绘制多少次(帧),可能也能够这么说,每一帧暂停多少日子。如若你的卡通片每一帧都以一个规范,只是地方不一样,那么些速度影响十分的小。

其一办法看起来很简短,其实它富含了一定的数学意义,你能够以为是总体坐标系的原点发生了运动,新坐标系下任意一点(x,y)也就是原坐标系下的坐标为:

其次个图形移动的进度。

x'=x dx
y'=y dy

进而,千万不要把那多少个速度搞混了,绘制的越快,只好表示动画更通畅,但并不意味着你的图像移动的更加快。

举个例子大家调用 ctx.translate(5,8) 改换上下文对象的坐标系状态,然后在新景观下的点(3,2)绘图,约等于图像被绘制到了原状态下的点(8,10)处,即

 

x'=5 3=8
y'=5 2=10

使用 HTML5 绘制动画基本上正是上边那个流程,只是你还须要注意两点:

只怕你会问,为啥要那么辛苦,直接在(8,10)处绘制比行吗?比方把

1、为了便利绘制的图样,我们平时会退换上下文对象的的情况,所以在绘制图形前后,千万别忘了保留和回复情状,假使您不太驾驭情状是何等,请看眼下的一篇小说《HTML5边玩边学(6):小车人,变形......》

ctx.translate(5,8)
ctx.drawImage(img,3,2)

2、大家供给将全方位绘制动作放到反应计时器里面,不然一切浏览器将错失响应。Javascript 有几个机械漏刻方法,分别是:

改成

setInterval(code,millisec) 和 setTimeout(code,millisec)

ctx.drawImage(img,8,10)

那四个主意自己就介绍了,能够去 谷歌 相关的材质。

如此不是更简便、越来越直白吗?

上面大家付出贰个前后移动方块的小动画,当蒙受顶端可能尾巴部分时,会改变方向。代码如下:

本人的知晓是,移动越来越多的情状下是为别的图形转变服务的,伏贴的改换坐标原点能够让图形学计算越来越好掌握,并推动非常大平价,上面小编举个轻易的事例,假使:

葡京娱乐注册即送88 5葡京娱乐注册即送88 6主干动画

有一条线段 ,是 x 轴正发展的一小段

<canvas id="canvas1" width="250" height="300" style="background-color:black">
    你的浏览器不扶助 Canvas 标签,请使用 Chrome 浏览器 或然 FireFox 浏览器
</canvas><br/>
帧数:<input  id="txt1" type="text" value="25"/><br/>
每一趟运动距离:<input type="text" id="txt2" value="10"/><br/>
<input type="button" value="开始" onclick="move_box()"/>
<input type="button" value="暂停" onclick="stop()"/>

y = 0 (1 <= x <= 3),

<script type="text/javascript">
    //定时器
    var interval=null;
    
    //甘休动画
    function stop(){
        clearInterval(interval);
    }

若是以坐标原点为圆心,逆时针转动90度,则线段与 y 轴正向重合,旋转后的线条为:

    //===================================================================
    //基本动画
    //====================================================================
    function move_box(){
        //结束动画
        stop();
        //移动速度
        var delta=parseInt(document.getElementById('txt1').value);
        //每秒绘制多少次
        var fps=parseInt(document.getElementById('txt2').value);

x = 0 (1 <= y <= 3)

        //画布对象
        var canvas=document.getElementById("canvas1")
        //获取上下文对象
        var ctx = canvas.getContext("2d");
        //设置颜色
        ctx.fillStyle="red";
        
        //方块的启幕位置
        var x=100;var y=50;
        //方块的尺寸和增长幅度
        var w=30;var h=30;
        
        //伊始动画
        interval = setInterval(function(){
            //改变 y 坐标
            y=y delta;
            //上边缘检查测验
            if(y<0){
                y=0;
                delta=-delta;
            }
            //上边缘检验
            if((y h)>canvas.getAttribute("height")){
                y=canvas.getAttribute("height")-h;
                delta=-delta;
            } 
            //清空画布
            ctx.clearRect(0,0,canvas.getAttribute("width"),canvas.getAttribute("height"));
            //保存状态
            ctx.save();
            //移动坐标
            ctx.translate(x,y);
            //重新绘制
            ctx.fillRect(0,0,w,h);
            //恢复生机状态
            ctx.restore();
        },1000/fps);
    }    
</script>

但是大家不容许每一遍旋转都以原点为圆心进行旋转,假使我们以线段的多少个端点(1,0)为圆心进行旋转,大家怎么才干博得旋转后线段上每一点的坐标值呢?其实这几个进度能够分为三步:

 

第一步:移动原点坐标到(1,0),新的线条仍旧在 x 轴上,可是方程变为了:y = 0 (0 <= x <= 2)

 

第二步:以新坐标系的原点为圆心举办旋转,获得新坐标系下的线条 x = 0 (0 <= y <= 2)

{{{{

其三步:将新坐标系的原点移动到新坐标系下(-1,0)处,就要原点苏醒到原位,此时的线条为:x = 1 (0 <= y <= 2)

您的浏览器不扶助 Canvas 标签,请使用 Chrome 浏览器 或然 FireFox 浏览器

其三步所得到的线条正是最终索要绘制的线条。

帧数:
历次运动距离:
}}}}

从那些事例我们能够看出来,就算在那样简单的图景下,假设不活动坐标原点来一贯总计旋转后的图形,也是比较艰辛的。

 

本文由新浦京81707con发布于注册购买,转载请注明出处:图形渐变和图像形变换,HTML5边玩边学

关键词: 新浦京81707con

上一篇:黑马程序员,正则表达式

下一篇:没有了