HTML5之弧度角度与sin,canvas基础第二节

开始

妹子都爱好流星,如若她说不喜欢,那他自然是一个假妹子。

当今就1块儿来做一场流星雨,用程序员的野路子浪漫弹指间。

要画一场流星雨,首先,自然大家要会画一颗流星。

玩过 canvas 的同学,你画圆画方画线条这么
陆,借使说叫你画上面那些玩意儿,你会不会以为您用的是假 canvas?canvas
未有画二个带尾巴玩意儿的 api 啊。

澳门葡京 1

本章重要介绍以下多少个地点:

弧度与sin及cos的关系


一、图形的组合格局

画1颗流星

科学,的却是没那几个api,不过不表示我们画不出来。流星就是2个小石块,然后因为速度过快发生大批量的热能牵动周边的气氛发光发热,所以经飞过的地方看起来就如流星的纰漏,大家先研商一下流星那些图像,整个流星处于他本身的移动轨迹之中,当前的职位最亮,概况最清楚,而在此以前划过的位置离当下职责轨迹距离越远就越暗淡越模糊。

地方的辨析结果很要紧, canvas
上是每1帧就重绘二回,每壹帧之间的时光间隔极短。流星经过的地方会越加混淆最终毁灭不见,那有没有能够让画布画的图像每过1帧就变模糊一点而不是全数革除的不二等秘书籍?借使得以这么,就能够把每1帧用线段画一小段流星的位移轨迹,最后画出流星的意义。

澳门葡京 2

骗纸!你可能会说,那那里像流星了???
别急,让自家多画几段给您看看。

澳门葡京 3

怎么着? 仍旧不像? 大家把它画小点,那下总该像了把?

 澳门葡京 4

上边几幅图作者是在 ps 上效仿的,本质上 ps 也是在画布上画画,我们及时在
canvas 上试试。

那,直接代码完毕一下。

// 坐标
class Crood {
    constructor(x=0, y=0) {
        this.x = x;
        this.y = y;
    }
    setCrood(x, y) {
        this.x = x;
        this.y = y;
    }
    copy() {
        return new Crood(this.x, this.y);
    }
}

// 流星
class ShootingStar {
    constructor(init=new Crood, final=new Crood, size=3, speed=200, onDistory=null) {
        this.init = init; // 初始位置
        this.final = final; // 最终位置
        this.size = size; // 大小
        this.speed = speed; // 速度:像素/s

        // 飞行总时间
        this.dur = Math.sqrt(Math.pow(this.final.x-this.init.x, 2) + Math.pow(this.final.y-this.init.y, 2)) * 1000 / this.speed; 

        this.pass = 0; // 已过去的时间
        this.prev = this.init.copy(); // 上一帧位置
        this.now = this.init.copy(); // 当前位置
        this.onDistory = onDistory;
    }
    draw(ctx, delta) {
        this.pass += delta;
        this.pass = Math.min(this.pass, this.dur);

        let percent = this.pass / this.dur;

        this.now.setCrood(
            this.init.x + (this.final.x - this.init.x) * percent,
            this.init.y + (this.final.y - this.init.y) * percent
        );

        // canvas
        ctx.strokeStyle = '#fff';
        ctx.lineCap = 'round';
        ctx.lineWidth = this.size;
        ctx.beginPath();
        ctx.moveTo(this.now.x, this.now.y);
        ctx.lineTo(this.prev.x, this.prev.y);
        ctx.stroke();

        this.prev.setCrood(this.now.x, this.now.y);
        if (this.pass === this.dur) {
            this.distory();
        }
    }
    distory() {
        this.onDistory && this.onDistory();
    }
}


// effet
let cvs = document.querySelector('canvas');
let ctx = cvs.getContext('2d');

let T;
let shootingStar = new ShootingStar(
                        new Crood(100, 100), 
                        new Crood(400, 400),
                        3,
                        200,
                        ()=>{cancelAnimationFrame(T)}
                    );

let tick = (function() {
    let now = (new Date()).getTime();
    let last = now;
    let delta;
    return function() {
        delta = now - last;
        delta = delta > 500 ? 30 : (delta < 16? 16 : delta);
        last = now;
        // console.log(delta);

        T = requestAnimationFrame(tick);

        ctx.save();
        ctx.fillStyle = 'rgba(0,0,0,0.2)'; // 每一帧用 “半透明” 的背景色清除画布
        ctx.fillRect(0, 0, cvs.width, cvs.height);
        ctx.restore();
        shootingStar.draw(ctx, delta);
    }
})();
tick();
  • 影子效果shadowColor, shadowOffsetX…
  • 大局折射率globalAlpha设置,图像叠加时的功能globalCompositeOperation
  • clip() 设置绘制区域,探照灯效果和基本canvas的卡通模型
  • 零和原则制作剪纸效果
  • isPointIn帕特h()判断点的地点,clearRect()清空矩形画布
目的:

通过掌握弧度与sin及cos的关联,能够依据弧度及半径求出旋转钦赐弧度后所到达的dx,dy坐标

globalAlpha是二个介于0和一之内的值(包蕴0和一),用于钦命全数绘制的发光度。暗中认可值为0。假使全数继续操作都要依照相同的折射率,就能够先把globalAlpha设置为适当班值日,然后绘制,最终在把它设置回暗许值0.

//绘制三个革命的矩形

context.fillStyle=”red”;

context.fillRect(10,10,50,50);

效用:1颗流星

澳门葡京 5

sogoyi 快看,一颗活泼不做作的流星!!! 是或不是感觉动起来越发活龙活现一点?

1.阴影功能

其一职能和css中的 ‘box-shadow’ 类似。canvas中它有多少个天性:

  • shadowColor: 阴影的颜料
  • shadowOffsetX: x轴的舞狮
  • shadowOffsetY: Y轴的偏移
  • shadowBlur: 设置模糊值

示例:

ctx.shadowColor = 'rgba(0,0,0,0.5)'
ctx.shadowOffsetX = -2
ctx.shadowOffsetY = -1
ctx.shadowBlur = 2

ctx.font = 'bolder 50px Ubuntu'
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'

ctx.fillStyle = 'orangered'
ctx.fillText('James Sawyer', 200, 200, 400) // 400为最大宽度
弧度(angle)与角度(degree)的关系:
  • 360角度 = 2π
  • 1角度 = π/180弧度
  • 1弧度 = 180/π角度

即:30角度的弧度值 = 30 * (π/180) ,30弧度的角度值 = 30 * (180/π)

//修改全局折射率

流星雨

我们再加三个流星雨 MeteorShower
类,生成多1些随意位置的流星,做出流星雨。

// 坐标
class Crood {
    constructor(x=0, y=0) {
        this.x = x;
        this.y = y;
    }
    setCrood(x, y) {
        this.x = x;
        this.y = y;
    }
    copy() {
        return new Crood(this.x, this.y);
    }
}

// 流星
class ShootingStar {
    constructor(init=new Crood, final=new Crood, size=3, speed=200, onDistory=null) {
        this.init = init; // 初始位置
        this.final = final; // 最终位置
        this.size = size; // 大小
        this.speed = speed; // 速度:像素/s

        // 飞行总时间
        this.dur = Math.sqrt(Math.pow(this.final.x-this.init.x, 2) + Math.pow(this.final.y-this.init.y, 2)) * 1000 / this.speed; 

        this.pass = 0; // 已过去的时间
        this.prev = this.init.copy(); // 上一帧位置
        this.now = this.init.copy(); // 当前位置
        this.onDistory = onDistory;
    }
    draw(ctx, delta) {
        this.pass += delta;
        this.pass = Math.min(this.pass, this.dur);

        let percent = this.pass / this.dur;

        this.now.setCrood(
            this.init.x + (this.final.x - this.init.x) * percent,
            this.init.y + (this.final.y - this.init.y) * percent
        );

        // canvas
        ctx.strokeStyle = '#fff';
        ctx.lineCap = 'round';
        ctx.lineWidth = this.size;
        ctx.beginPath();
        ctx.moveTo(this.now.x, this.now.y);
        ctx.lineTo(this.prev.x, this.prev.y);
        ctx.stroke();

        this.prev.setCrood(this.now.x, this.now.y);
        if (this.pass === this.dur) {
            this.distory();
        }
    }
    distory() {
        this.onDistory && this.onDistory();
    }
}

class MeteorShower {
    constructor(cvs, ctx) {
        this.cvs = cvs;
        this.ctx = ctx;
        this.stars = [];
        this.T;
        this.stop = false;
        this.playing = false;
    }

    createStar() {
        let angle = Math.PI / 3;
        let distance = Math.random() * 400;
        let init = new Crood(Math.random() * this.cvs.width|0, Math.random() * 100|0);
        let final = new Crood(init.x + distance * Math.cos(angle), init.y + distance * Math.sin(angle));
        let size = Math.random() * 2;
        let speed = Math.random() * 400 + 100;
        let star = new ShootingStar(
                        init, final, size, speed, 
                        ()=>{this.remove(star)}
                    );
        return star;
    }

    remove(star) {
        this.stars = this.stars.filter((s)=>{ return s !== star});
    }

    update(delta) {
        if (!this.stop && this.stars.length < 20) {
            this.stars.push(this.createStar());
        }
        this.stars.forEach((star)=>{
            star.draw(this.ctx, delta);
        });
    }

    tick() {
        if (this.playing) return;
        this.playing = true;

        let now = (new Date()).getTime();
        let last = now;
        let delta;

        let  _tick = ()=>{
            if (this.stop && this.stars.length === 0) {
                cancelAnimationFrame(this.T);
                this.playing = false;
                return;
            }

            delta = now - last;
            delta = delta > 500 ? 30 : (delta < 16? 16 : delta);
            last = now;
            // console.log(delta);

            this.T = requestAnimationFrame(_tick);

            ctx.save();
            ctx.fillStyle = 'rgba(0,0,0,0.2)'; // 每一帧用 “半透明” 的背景色清除画布
            ctx.fillRect(0, 0, cvs.width, cvs.height);
            ctx.restore();
            this.update(delta);
        }
        _tick();
    }

    start() {
        this.stop = false;
        this.tick();
    }

    stop() {
        this.stop = true;
    }  
}

// effet
let cvs = document.querySelector('canvas');
let ctx = cvs.getContext('2d');

let meteorShower = new MeteorShower(cvs, ctx);
meteorShower.start();

二.globalAlpha && globalCompositeOperation

经过弧度与半径求旋转钦命弧度后目的点的坐标:
  • sin(angle) =
    y/r:y为角的对边长度,即旋转后坐标点的y坐标;r为半径,为斜边长
  • cos(angle) =
    x/r:x为角的邻边长度,即旋转后坐标点的x坐标;r为半径,为斜边长

澳门葡京 6

论及图解

故围绕基本点(0,0)旋转求值:dx = cos(angle) * r,dy = sin(angle)
* r
注:若中央点为(十,20),则dx = 拾 + cos(angle) * r,dy = 20 +
sin(angle) * r

context.globalAlpha=0.5;

//绘制白色矩形

context.fillStyle=”blue”;

context.fillRect(30,30,50,50);

效果:流星雨

澳门葡京 7

globalAlpha

其一天性相对来说比较不难,首假若设置1个大局的阿尔法值。这些值和
rgba(0,0,0,alpha) 中的阿尔法的效用等同,只不过这些是安装全局的发光度

ctx.globalAlpha = 0.7
伍角星代码示例一
<body>
    <script>
    window.onload = function() {
        var canvas = document.getElementById("canvas");
        if (canvas == null) {
            return false;
        }
        var ctx = canvas.getContext("2d");
        drawLine(ctx);
        drawStar(ctx);
    }

    //画横竖线(田字格)
    function drawLine(ctx) {
        ctx.strokeStyle = "#ccc";
        //划横线
        for (var i = 0.5; i < 500; i++) {
            ctx.beginPath();
            ctx.moveTo(0, i * 10);
            ctx.lineTo(500, i * 10);
            ctx.stroke();
        }
        //划竖线
        for (var i = 0.5; i < 500; i++) {
            ctx.beginPath();
            ctx.moveTo(i * 10, 0);
            ctx.lineTo(i * 10, 500);
            ctx.stroke();
        }

    }

    // 画五角星、外边圆,并绘画出以圆心为圆点的坐标轴及各角到圆心的直线
    function drawStar(ctx) {
        //五角星圆心的坐标位置
        var dx = 200;
        var dy = 200;
        //绘制出五角星外边圆圆心
        ctx.beginPath();
        ctx.arc(dx, dy, 5, 0, 2 * Math.PI, true);
        ctx.fillStyle = "#f00";
        ctx.strokeStyle = "#f00";
        //设置字号,字体
        ctx.font = "14px Verdana";
        ctx.strokeText("圆心", dx, dy);
        ctx.fill();
        //五角星外边圆的半径,即圆心到各个角的距离
        var size = 100;
        ctx.beginPath();

        /*定义一个起始弧度,从这个弧度开始画*/
        var startAngle = -Math.PI * 0.5; //逆时针的一个直角弧度,位于y轴坐标正上方位置

        /*
         *1.五角星划线的角度:一个圆的弧度为2π,分为5个角即2π/5(任意两个点到圆心形成的角度)
         *2.2π/5为蓝线圆心-0,圆心-3形成的角度,而五角星划线是从0-1,所以圆心-0,圆心-1的角度是它的两倍,故须*2
         *3.圆心-0,圆心-3可以通过此代码打开网页查看
         */
        /*dig为圆心-0,圆心-1形成的弧度*/
        var dig = (2 * Math.PI / 5) * 2;

        /*开始画五角星图*/
        ctx.beginPath();
        for (var i = 0; i < 5; i++) {
            //正弧度顺时针旋转,负弧度逆时针旋转
            var angle = startAngle + dig * i;
            /*获取当前角度下一个点的x轴坐标:Math.cos(angle) * size*/
            //cos(弧度) = x坐标/r  r为半径 = 这里的size
            var x = dx + Math.cos(angle) * size; //因弧度是以dx,dy为圆心旋转,所以需要加上dx,dy的坐标,以保持图形的圆心仍为dx,dy
            /*获取当前角度下一个点的y轴坐标:Math.sin(angle) * size*/
            //sin(弧度) = y坐标/r   r为半径 = 这里的size
            var y = dy + Math.sin(angle) * size;
            console.log("x:" + x);
            console.log("y:" + y);
            ctx.lineTo(x, y);
            //给输出文字设置颜色
            ctx.strokeStyle = "#00f";
            //输出划线先后顺序
            ctx.strokeText(i, x, y);
        }
        //这里必须写,否则五角星会少stroke一条线(不影响fill)
        //closePath,闭合图形在非闭合状态下,会通过此方法从当前点至起始点画一条直线
        ctx.closePath();
        ctx.fillStyle = "rgba(255,255,0,0.5)";
        //填充
        ctx.fill();
        //输出文字的时候设置过,状态已被ctx保存,无须再设置。
        //ctx.strokeStyle = "#00f";
        //划线
        ctx.stroke();

        /*划圆心到各角的线*/
        ctx.beginPath();
        var startAngle = -Math.PI * 0.5;
        for (var i = 0; i < 5; i++) {
            var angle = startAngle + dig * i;
            var x = dx + Math.cos(angle) * size;
            var y = dy + Math.sin(angle) * size;
            console.log("x:" + x);
            console.log("y:" + y);
            ctx.moveTo(x, y);
            ctx.lineTo(dx, dy);
        }
        //closePath这里可以不写,因为这里划的都是线,无需闭合
        //ctx.closePath();
        ctx.strokeStyle = "#f00";
        ctx.stroke();

        /*开始画五角星周边圆*/
        ctx.beginPath();
        ctx.arc(dx, dy, size, 0, 2 * Math.PI, true);
        ctx.strokeStyle = "#f00";
        ctx.stroke();

        /*以圆心为起点开始画坐标轴*/
        /*坐标轴颜色*/
        ctx.strokeStyle = "#000";
        //横坐标
        ctx.beginPath();
        ctx.moveTo(0, dy);
        ctx.lineTo(500, dy);
        ctx.stroke();
        //纵坐标
        ctx.beginPath();
        ctx.moveTo(dx, 0);
        ctx.lineTo(dx, 500);
        ctx.stroke();

    }
    </script>
    <canvas id="canvas" height="500" width="500"></canvas>
</body>

澳门葡京 8

上述代码效果图

//重置全局发光度

透明背景

先不急着激动,这些流星雨有点单调,能够看出地点的代码中,每一帧,我们用了反射率为
0.贰 的湖蓝刷了一回画布,背景深紫灰一片,借使说大家的急需是晶莹背景啊?

例如,大家要用这么些夜景图片做背景,然后在上头加上大家的流星,大家每1帧刷一层背景的小伎俩就用持续啦。因为我们要力保除开流星之外的片段,应该是晶莹的。

澳门葡京 9

这里就要用到一个冷门的属性了,globalCompositeOperation,全局组合操作? 原谅我放荡不羁的翻译。
这个属性其实就是用来定义后绘制的图形与先绘制的图形之间的组合显示效果的。
他可以设置这些值

澳门葡京 10

这个属性表明没需求仔细看,更不用记下来,直接看 api
示例 运转作效果果就很明亮了。示例里,先绘制的是填充正方形,后绘制的是填充圆形。

澳门葡京 11

是还是不是出现转机,一目掌握?

对此我们来说,原图像是每1帧画完的有所流星,指标图像是画完流星之后半晶莹剔透覆盖画布的深褐矩形。而笔者辈每一帧要封存的正是,上壹帧
0.8 光滑度的流星,覆盖画布黄色矩形大家不可能显得。

留神那里的 destination-out 和
destination-in,示例中那两个属性最终都只有部分源图像保留了下去,符合大家假使保留流星的急需。小编觉着
w三cschool 上讲述的不是很正确,作者用本人要好的接头回顾一下。

  • destination-in
    :只保留了源图像(矩形)和对象图像(圆)交集区域的源图像
  • destination-out:只保留了源图像(矩形)减去指标图像(圆)之后区域的源图像

上述示范目的图像的光滑度是
一,源图像被削减的一部分是截然不见了。而大家想要的是她得以遵循指标光滑度实行1些擦除。改一下示范里的代码看看是还是不是扶助半晶莹剔透的估量。

澳门葡京 12

看来这么些性情帮忙半晶莹剔透的计算。源图像和对象图像交叠的1些以半晶莹剔透的方式保留了下去。也正是说假若咱们要保留
0.八 反射率的流星,能够那样设置 globalCompositeOperation

ctx.fillStyle = 'rgba(0,0,0,0.8)'
globalCompositeOperation = 'destination-in';
ctx.fillRect(0, 0, cvs.width, cvs.height);


// 或者
ctx.fillStyle = 'rgba(0,0,0,0.2)'
globalCompositeOperation = 'destination-out';
ctx.fillRect(0, 0, cvs.width, cvs.height);

globalCompositeOperation

那么些值的习性比较多,主要用来安装图表相互叠加时展现的功力,其出示效果能够分为三组

一.后绘制的图形B在上头,前边绘制的图形A被遮盖

  • source-over: 私下认可值,前边的图片B在A的地点
  • source-atop: 前边的图样B只体现与前方图形A的接力部分,A则全体突显(A + A∩B)
  • source-out: 只展现B图形未与图形A未交叉部分,A不展现 (A∪B – A –
    A∩B)
  • source-in: 只突显图形交叉部分(A∩B)

2.后绘制的图形B在前面绘制的图形A的底下

那种气象和方面包车型地铁情况便是图形的z-index改变了,其他的壹律。也有3种天性

  • destination-over: A在B上面
  • destination-atop:
    前面包车型客车图形A只展现与眼下图形B的交叉部分,B则整个出示 (B + A∩B)
  • destination-out: 只呈现A图形未与图片B未交叉部分,B不显得 (A∪B –
    B – A∩B)
  • destination-in: 只显示图形交叉部分(A∩B)

叁.其余意况

  • lighter: 交叉部分的颜色变浅
  • copy: 只复制最后绘制的图形B
  • xor: 交叉部分被去掉即(A∪B – A∩B)

除此而外上边的1一种,还有更加多的选项:

globalCompositeOperation
具体文书档案

5角星代码示例二
<script>
    function strokeFiveStar() {
        var canvas = document.getElementById("canvas");
        if (canvas == null) {
            return false;
        }
        var ctx = canvas.getContext("2d");
        /*圆心坐标*/
        var cx = 200;
        var cy = 200;
        /*绘制圆心*/
        ctx.arc(cx, cy, 5, 0, 2 * Math.PI, false);
        ctx.fillStyle = "#f00";
        ctx.fill();

        /*定义起始绘制点弧度 -90角度,y轴正上方*/
        var startAngle = -Math.PI / 2;
        //定义半径
        var r = 100;
        //绘制线条两点(如第1个点与第2个点)与圆心点构成的弧度
        var dig = (2 * Math.PI / 5) * 2;
        ctx.beginPath();
        /*根据角度连接5个点*/
        for (var i = 0; i < 5; i++) {
            var dx = cx + Math.cos(startAngle + dig * i) * r;
            var dy = cy + Math.sin(startAngle + dig * i) * r;
            /*i=0时,因没有子路径,故lineTo的作用相当于moveTo*/
            ctx.lineTo(dx, dy);
            ctx.strokeText("第" + (i + 1) + "个点", dx, dy);
        }
        /*将最后一个点连接到第一个点*/
        ctx.closePath();
        ctx.stroke();
    }
</script>

澳门葡京 13

上述代码示例效果图

context.globalAlpha=0;

//那么些事例紫青黑色矩形会表现半透明效果,透过它能够看出下边包车型客车新民主主义革命矩形。

终极效果

添加 globalCompositeOperation 之后的作用既最终效果:

 澳门葡京 14

github:
https://github.com/gnauhca/dailyeffecttest/tree/master/b-meteorshower

快约上你的妹子看流星雨啊。

怎么着? 你从未妹子?

澳门葡京 15

转载请注明出处:Web前端开发 » 撩妹技能 get,教你用 canvas 画一场流星雨

3.clip() 将画布设置成当前的

开创剪辑区域

意味着使用安装的路子区域作为绘制的限量环境

例如:

ctx.beginPath()
ctx.arc(400, 400, 150, 0, Math.PI * 2)
ctx.stroke() // 用于做辅助线,可以不加这行
# clip()表示使用上面的圆围成的区域作为绘制环境
ctx.clip()

ctx.font = 'bold 150px Ubuntu'
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
ctx.fillStyle = 'black'
ctx.fillText('CANVAS', canvas.width/2, canvas.height/2)

则其功效为:

澳门葡京 16

Canvas图形综合操作globalCompositeOperation


globalCompositionOperation表示绘制后的图样怎么样与先绘制的图片组成。这些性格的值是字符串,大概的值如下:

source-over(暗中认可值):后绘制的图片位于先绘制的图片上方。

source-in:后绘制的图样与先绘制的图样重叠的一对可知,两者别的部分完全透明。

HTML5之弧度角度与sin,canvas基础第二节。source-out:后绘制的图片与先绘制的图片不重叠的有的可知,先绘制的图纸完全透明。

source-atop:后绘制的图片与先绘制的图片重叠的1对可知,先绘制图形不受影响。

destination-over:后绘制的图片位于先绘制的图片下方,后绘制的图纸唯有从前透明像素下的局地才可知,被挡住的片段不可知。

destination-in:后绘制的图形位于先绘制的图形下方,两者不重叠的有个别完全透明。就是显得重叠的有的的形制,显示先绘制的图片的水彩。

destination-out:后绘制的图样擦除与先绘制的图片重叠的一对。

destination-atop:后绘制的图样位于先绘制的图样下方,在两岸不重叠的地点,先绘制的图片会变透明。

lighter:后绘制的图样与先绘制的图片重叠部分的值相加,使该片段变亮。(叠加的是颜色额)

copy:后绘制的图样完全代替与之重叠的先绘制图形。

xor:后绘制的图样与先绘制的图片重叠的1对实行“异或”操作;图像异或,相异为一,相同为0.即重叠部分不出示,不重叠部分显得。

//画指标图

context.beginPath();

context.fillStyle=”red”;

context.fillRect(100,50,100,300);

//画源图

context.beginPath();

context.globalCompositeOperation=”destination-out”;

//context.globalCompositeOperation=”xor”;

context.fillStyle=”blue”;

context.arc(250,200,100,0, Math.PI*2);

探照灯效果和canvas基本动画

探照灯利用clip() 函数将可视区域随动画的改变而更改

动画片效果

动画效果利用 setInveral()函数来不停的翻新画布,到达动画的功能

window.onload = function() {
  var canvas = document.querySelector('#canvas');
  canvas.width = 800;
  canvas.height = 800;

  # 设置探照灯对象模型
  /*
   * @param (x, y): 表示圆心坐标
   * @param radius: 圆的半径
   * @param vx, vy: 水平和垂直方向的速度,通过他们控制速度大小
   */
  var searchLight = {
  x: 400,
    y: 400,
    radius: 150,
    vx: Math.random() * 5 + 10,
    vy: Math.random() * 5 + 15
  };

  # 通过setInterval来更新模型的位置
  # 每40ms更新一次
  setInterval(() => {
    draw(ctx);
    update(canvas.width, canvas.height);
  }, 40);
}

function draw(ctx) {
  # 绘制之前先清空画布
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  ctx.save();

  # 讲画图绘制为黑色
  ctx.beginPath();
  ctx.fillStyle = 'black';
  ctx.fill()

  # 绘制圆形区域
  ctx.save()
  ctx.beginPath()
  ctx.arc(
    searchLight.x, searchLight.y, 
    searchLight.r,
    0, Math.PI * 2
  );
  ctx.fill();
  # 将上面的区域作为剪辑区域
  ctx.clip();

  ctx.font = 'bold 150px Ubuntu';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillStyle = '#058';
  ctx.fillText('CANVAS', canvas.width/2, canvas.height/2)

  ctx.restore();
} 

# 小球运动模型,很基本的逻辑判断
function update(canvasWidth, canvasHeight) {
  searchLight.x += searchLight.vx;
  searchLight.y += searchLight.vy;

  # 如果小球超出了左边的边界,则速度反向,x点变为圆的半径
  if (searchLight.x - searchLight.radius <= 0) {
    searchLight.vx = -searchLight.vx;
    searchLight.x = searchLight.radius;
  }

  # 如果小球超出了右边的边界,
  # 则速度反向,x点变为 画布宽度 - 圆的半径
  if (searchLight.x + searchLight.radius >= canvasWidth) {
    searchLight.vx = -searchLight.vx;
    searchLight.x = canvasWidth - searchLight.radius;
  }

  # y轴方向 基本同上   
  if (searchLight.y - searchLight.radius <= 0) {
    searchLight.vy = -searchLight.vy;
    searchLight.y = searchLight.radius;
  }

  if (searchLight.y + searchLight.radius >= canvasHeight) {
    searchLight.vy = -searchLight.vy;
    searchLight.y = canvasHeight - searchLight.radius;
  }
}   

探照灯效果

使用情势:

ctx.globalCompositeOperation = type

对象图像:已经松开画布中的绘图

4.路径方向和零和原则

零和原则:
封闭图形内部是还是不是填充颜色和路线的取向至于,从封闭图形的中间引出一条射线,内定多个趋势为正方向,与正方向相交则+一,与反方向相交-一,最后总和不为0,则该区域为填充区域;总和为0则该区域不开始展览填空

如图,卡其色色部分相交之和为0,所以不实行填写

澳门葡京 17

能够依照这一个条件来绘制出剪纸效果

ctx.beginPath()
// 顺时针绘制一个圆
ctx.arc(400, 400, 300, 0, Math.PI * 2, false)
// 逆时针绘制一个圆
ctx.arc(400, 400, 300, 0, Math.PI * 2, true)

#中心部分因为零和原则,中间部分将不填充
ctx.closePath()

// 添加阴影效果
ctx.shadowColor = 'black'
ctx.shadowOffsetX = 2
ctx.shadowOffsetY = 2
ctx.shadowBlur = 4

ctx.fillStyle = '#058'
ctx.fill()

最后效果:

澳门葡京 18

1二种type值的介绍:
  1. source-over:新图片覆盖原图形,其余一些常规展现
  2. destination-over:原图形覆盖新图片,其余部分符合规律突显
  3. source-in:只展现在原图形里面的新图片,其余一些透明
  4. destination-in:只突显在新图片里面包车型大巴原图形,其余部分透明
  5. source-out:只展现在原图形之外的新图片,其余一些透明
  6. destination-out:只展现在新图片之外的原图形,别的壹些透明
  7. source-atop:新图片只绘制在原图形之上,原图形别的部分寻常展现
  8. destination-atop:原图形只绘制在新图片之上,原图形其余部分符合规律展现
  9. lighter:重叠部分变亮,别的1些常规显示
  10. darker:重叠部分变暗,别的一些常规展现
  11. xor:重叠部分透明,其余部分符合规律彰显
  12. copy:只保留新图片,其余一些透明

上述品种的可比可参看Mozilla开发者文书档案的globalCompositeOperation属性

<!-- globalCompositeOperation demo-->
<head>
    <meta charset="UTF-8">
    <title>globalCompostionOperation</title>
    <script>
        function draw(id) {
            var canvas = document.getElementById(id);
            if(canvas == null) {
                return false;
            }
            var ctx = canvas.getContext("2d");
            var types = new Array(
                    /*0*/"source-over", /*覆盖原图形,其他部分正常显示*/
                    /*1*/"destination-over",/*覆盖新图形,其他部分正常显示*/
                    /*2 chrome不支持*/"source-in",/*原图形之内的新图形,其他(原图形&新图形)都透明*/
                    /*3 chrome不支持*/"destination-in",/*新图形之内的原图形,其他(原图形&新图形)都透明*/
                    /*4*/"source-out",/*原图形之外的新图形,其他(原图形&新图形)都透明*/
                    /*5 chrome不支持*/"destination-out",/*新图形之外的原图形,其他(原图形&新图形)都透明*/
                    /*6 chrome不支持*/"source-atop",/*原图形之上,新图形只绘制原图形范围内部分,其他部分正常显示*/
                    /*7*/"destination-atop",/*新图形之上,原图形只绘制新图形范围内部分,其他部分正常显示*/
                    /*8 chrome不支持*/"lighter",/*重叠部分加色,其他不变*/
                    /*9 chrome不支持*/"darker",/*重叠部分减色,其他不变*/
                    /*10*/"xor",/*重叠部分透明,其他不变*/
                    /*11*/"copy"/*只保留新图形,其他清除*/
                    /*以上类型,详情可参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Compositing*/
            );
            /*设置图形叠加组合模式*/
            ctx.globalCompositeOperation = types[10];
            ctx.fillStyle = "#f00";
            ctx.fillRect(100,100,200,200);
            ctx.fillStyle = "#ff0";
            ctx.fillRect(150,150,200,200);

        }
    </script>
</head>
<body onload="draw('canvas')">
    <canvas id="canvas" height="500" width="500"></canvas>
</body>

澳门葡京 19

type为xor的效应图

源图像:打算放置到画布中的绘图

在使用globalCompositionOperation的情事下一定要多测一些浏览器,因为不一致的浏览器对这一个个性的贯彻依旧存在较大的距离。


五. clearRect, isPointInPath##

Canvas绘制阴影效果


2、使用图片

//第2种写法:第一个参数:图片对象;第叁个参数是起头画的x坐标;第三个参数:起首画的y的坐标;

//context.drawImage(img,0,0);

//第二种写法:第三个参数:图片对象;第一个参数:是初叶画的x坐标;第5个参数:开首画的y的坐标;第多少个参数:图片绘制到canvas上的上涨幅度;第5个参数:图片绘制到canvas上的莫大;

//context.drawImage(img,0,0,200,200);

//第三种写法(裁剪):第四个参数:图片对象;第一多少个参数在原图上要裁剪的初步x、y的坐标;第陆、七个参数:在原图上要裁剪的宽和高;第四、两个参数:要松开canvas画布上的发轫x、y坐标;第七多少个参数:要到canvas画布上的宽和高;

context.drawImage(img,100,100,100,100,50,50,300,300);

var  canvas=document.getElementById(“myCanvas”);

var   context=canvas.getContext(“2d”);

clearRect(x, y, width, height)

解决钦命宽高范围内的画布,多用来动画重新绘制新的图画

ctx.clearRect(200, 200, canvas.weight, canvas.heigth)
功能:

为ctx设置阴影效果后,在现阶段ctx状态下,canvas中绘制的图像都将出现阴影。

var   img= newImage();

isPointInPath(x, y)

认清3个点是不是在有些区域内

貌似拿走鼠标在canvas中的地方选拔:

var x = event.clientX - canvas.getBoundingClientRect().left;
var y = event.clientY - canvas.getBoundingClientRect().top;

// (x, y)即为鼠标所在canvas的坐标

然后通过 isPointInPath(x, y)来判断是否在所选区域内

示例:

当鼠标在区域内时,点击小球改变颜色:

var canvas = document.getElementById('#canvas')
canvas.height = 800
canvas.width = 800

var ctx = canvas.getContext('2d')

// 创建一个容器,用来放置所有小球的信息
var balls = []

window.onload = function() {
  // 产生10个随机球
  for (var i = 0; i < 10; i++) {
    var iBall = {
      x: Math.random() * canvas.width,
      y: Math.random() * canvas.heigth,
      r: Math.random() * 20 + 20
    }
    balls[i] = iBall
  }

  draw()
  canvas.addEventListener('click', detect)
}

// 获取随机颜色值
function getRandomColor() {
 return '#' +  ('00000' +Math.random() * 0x1000000<<2).toString(16).slice(-6)
}

function draw() {
  for (var i = 0; i < balls.length; i++) {
    ctx.beginPath();
    ctx.arc(balls[i].x, balls[i].y, balls[i].r, 0, Math.PI * 2);
    ctx.fillStyle = '#058';
    ctx.fill();
  }
}

function detect(e) {
  var x = event.clientX - canvas.getBoundingClientRect().left;
  var y = event.clientY - canvas.getBoundingClientRect().top;
  ctx.beginPath();
  ctx.arc(balls[i].x, balls[i].y, balls[i].r, 0, Math.PI * 2);

  # 判断鼠标位置,是否在圆内
  ctx.fillStyle = getRandomColor() || 'red';
  ctx.fill();   
}

具体demo

应用格局:
  • shadowOffsetX:距离图形当前坐标轴x轴的偏移量,私下认可值为0
  • shadowOffsetY:距离图形当前坐标轴y轴的偏移量,私下认可值为0
  • shadowColor:阴影的颜料,私下认可值为fully-transparent black,即透明
  • shadowBlur:阴影的歪曲程度,暗许值为0

img.src=”img/20150821130732_anQeR.jpeg”;

代码示例:
<body>
<script>
    window.onload = function () {
        var canvas = document.getElementById("canvas");
        if (canvas == null) {
            return false;
        }
        var ctx = canvas.getContext("2d");
        /*设置x坐标阴影偏移量*/
        ctx.shadowOffsetX = -10;
        /*设置y坐标阴影偏移量*/
        ctx.shadowOffsetY = 10;
        /*设置阴影颜色*/
        ctx.shadowColor = "#ccc";
        /*设置阴影模糊程度,默认是0*/
        ctx.shadowBlur = 20;

        /*绘制图形*/
        ctx.fillStyle = "#ff0";
        ctx.fillRect(100,100,50,50);
        /*这个图形一样会有阴影效果,ctx的状态不断被更新*/
        ctx.fillStyle = "#ff0";
        ctx.fillRect(200,100,50,50);
    }
</script>
<canvas id="canvas" width="500" height="500">您的浏览器不支持</canvas>
</body>

澳门葡京 20

上述代码效果图

img.onload=function(){

Canvas的图像绘制:drawImage


context.drawImage(img,100,100,100,100,50,50,300,300);

功能:

透过canvas的drawImage方法 ,将钦定图片绘制到canvas画布上。

}

绘图流程:
  1. 创办2个图形对象,用来承载图像 var img = new Image();
  2. 设置图像源 img.src = "xxx.jpg;"
  3. 监听图像对象的onload事件,图像加载成功后会执行该事件内定的函数
    img.onload = draw
  4. 在onload制定的draw函数中经过drawImage方法将img对象中的图像绘制到canvas画布中

回顾使用drawImage( )和别的办法,能够对图像举办种种基本操作。而操作的结果可以透过toDataU牧马人L( )方法赢得。但是有三个见仁见智,即图像无法来自其余域。借使图像来自别的域,调用toDataU帕杰罗L( )会抛出错误。

drawImage的3种方法:
  1. drawImage(img,destX,destY):以画布的destX、destY作为图像展现早先点,将整个img图像按图像原始像素绘制到画布中,超出画布不绘制;

  2. drawImage(img,destX,destY,destWidth,destHeight):将一切img图像绘制到画布中,以画布的destX、destY作为展现图像的开始点,destWidth、destHeight作为图像的展现大小;若destWidth、destHeight大于图像原始像素,则图像会推广(会搅乱);反之则减少。

  3. drawImage(img,sourceX,sourceY,sourceWidth,sourceHeight,destX,destY,destWidth,destHeight):从img的sourceX、sourceY早先点,获取sourceWidth、sourceHeight大小的图像,并将获取到的图像draw到画布中,从画布的destX、destY开头点早先绘制,将取得到的图像绘制成destWidth、destHeight大小(destWidth、destHeight若大于sourceWidth、sourceHeight,图像会推广即模糊;反之则裁减)

canvas提供了toDataURAV4L的接口,能够便宜的将canvas画布转化成base6肆编码的image。如今帮衬的最佳的是png格式,jpeg格式的现世浏览器基本也支撑,不过帮忙的不是很好。

示范代码:
<script>
    window.onload = function () {
        var canvas = document.getElementById("canvas");
        if (canvas == null) {
            return false;
        }
        var ctx = canvas.getContext("2d");
        /*创建一个图片对象*/
        var img = new Image();
        /*监听图片加载,加载成功结束后执行*/
        img.onload = function () {
            /*将原图draw到画布上,超出画布部分,不绘制*/
            ctx.drawImage(img, 0, 0);
            /*将整个img绘制到画布上,画布上的img起始点为100,100,宽高为300*300*/
            ctx.drawImage(img, 100, 100, 200, 200);
            /*以img的200,200为起始点,在img上获取宽高位150*150范围的图片,
            并将获取到的图片粘贴到画布坐标300,300的位置上,图片大小为200*200*/
            /*图片会变模糊,因为source的大小是150*150,而dest的大小为200*200*/
            ctx.drawImage(img, 200, 200, 150, 150, 300, 300, 200, 200);
        }
        img.src = "../raw/1.jpg";
    };
</script>

澳门葡京 21

上述代码示例效果图

//大家成立1个画布,在上头做一些绘制,然后试着把它保存为地面图片。

var  can = document.getElementById(‘canvas’);

var  ctx = can.getContext(‘2d’);

var   imgA = new Image();

imgA.src =’

/uploads/2013/09/css_yangshijiance.png’;

imgA.onload = function() {

ctx.drawImage(imgA, -25, 0, imgA.width, imgA.height);

ctx.restore();

};

var   imgB = new Image();

imgB.src = ‘

/uploads/2013/09/canvas_chroma.png’;

imgB.onload = function() {

ctx.globalAlpha = 0.1

ctx.drawImage(imgB, -100, -75, imgB.width, imgB.height);

ctx.restore();

};

function toImage(returnType) {

CreateJs之EaselJs基础应用


var dataURL = document.getElementById(‘canvas’).toDataURL(“image/png”);

// The returnType argument specifies how to get the

// the image.  ‘obj’ will set the source to an image element.

// ‘window’ will open a new window and display the image.

// ‘download’ will prompt the user to save the image.

switch(returnType) {

case ‘obj’:

var imgObj = new Image();

EaselJs是什么?

EaselJs:1个javascript库,方便更敏捷的拍卖canvas。

imgObj.src = dataURL;

document.getElementById(‘graphics’).appendChild(imgObj);

break;

case ‘window’:

window.open(dataURL, “Canvas Image”);

break;

case ‘download’:

dataURL = dataURL.replace(“image/png”, “image/octet-stream”);

EaselJs如何使用?
  1. 引入easeljs的js文件
    <script src="https://code.createjs.com/easeljs-0.8.2.min.js"></script>
  2. 在body成分中开创一个canvas成分
    <canvas id="demoCanvas" width="500" height="300"></canvas>
  3. 遵照canvas成分创制3个createjs的舞台
    var stage = new createjs.Stage("demoCanvas");
  4. 创设须要被添加到舞台的目的,如创造3个图片对象
    var circle = new createjs.Shape();
  5. 对图片对象实行拍卖,如画1个圆circle.graphics.beginFill("DeepSkyBlue").drawCircle(0, 0, 50);
  6. 将图片对象添加到舞奥兰多去 stage.addChild(circle);
  7. 履新舞台 stage.update();

借使需求依照钦命的帧频率变化舞台,继续看下方:
八.设置帧频率计时形式createjs.Ticker.timingMode = createjs.Ticker.RAF;
玖.安装刷新频率fsp值createjs.Ticker.framerate = 10;即十fsp,一成秒的进程刷新。
拾.设置Ticker的tick事件监听createjs.Ticker.addEventListener("tick", func);
1一.定义func;通过tick事件,会基于内定的频率执行该func函数;全部对舞台的操作在那边处理即可,记得更新舞台stage.update();

*注意点:
1.暗许的计时形式为createjs.Ticker.TIMEOUT,
二.RAF计时格局下,framerate无效,
叁.RAF情势下动画功能更通畅,
四.不必要按钦点帧频率时,可应用RAF计时形式

document.location.href = dataURL;

break;

}

}

优良的气象是页面上有两个点击链接:

1、Image Tag

点击会有一张图片插入在网页中。

2、New Window

开拓七个新的窗口,并体现三个PNG格式的图形

3、Download

下载保存一张PNG个格式的图纸

很懊丧,点击并未反映,为何吗?笔者做了成都百货上千试验,原因出在图片渲染上,canvas上只要添加图片,toDataU奇骏L()将失效,获取不到canvas新闻。通过不难几步来表达那个标题。

把js脚本中图纸渲染的1些去除,A和B图。为了便利观看,在画布上画多个大致的矩形,填充颜色:

ctx.fillStyle = ‘Red’;

ctx.strokeStyle = ‘Green’;

ctx.beginPath();

ctx.rect(20, 20, 100, 100);

ctx.stroke();

ctx.fill();

如此那般画布上便显得为二个革命矩形,格式为PNG


基础运用的演示代码:
<head>
    <meta charset="UTF-8">
    <title>easeljs的使用流程</title>
    <!--将js引入到文档中-->
    <script src="js/easeljs-0.8.2.min.js"></script>
    <script>
        function init() {
            /*基于canvas创建一个Stage对象*/
            var stage = new createjs.Stage("demoCanvas");
            /*创建一个图形对象*/
            var shape = new createjs.Shape();
            /*fill一个颜色为黄色,半径为50,圆心在100,100坐标的圆*/
            shape.graphics.beginFill("#ff0").drawCircle(100, 100, 50);
            /*设置圆的起始坐标点x,y,故圆心位于200,200*/
            shape.x = 100;
            shape.y = 100;
            /*将shape对象加入到stage中*/
            stage.addChild(shape);
            /*更新stage*/
            stage.update();

            /* 在shape对象中再画一个圆,圆心100,100,原因与shape
             * 的起始位置x,y相关
             * f是beginFill的Tiny写法,dc是drawCircle的Tiny写法
             * 更多Tiny写法可参考http://www.createjs.com/docs/easeljs/classes/Graphics.html*/
            shape.graphics.f("#f00").dc(0, 0, 50);
            /*shape发生变化后需要更新舞台才能显示最新的变化*/
            stage.update();

            /*设置Ticker的计时模式 RAF更流畅,缺点是
             忽略帧速率(即忽略createjs.Ticker.framerate)*/
            //createjs.Ticker.timingMode = createjs.Ticker.RAF;
            /* 设置帧速率,默认是30FSP,即1/30秒执行一次update
             * 如果Ticker计时模式设置为createjs.Ticker.RAF,那么此值无效;*/
            createjs.Ticker.framerate = 5;
            /* 添加一个tick监听事件,tick事件会根据指定的帧速率执行
             * 对应的函数,如这里的update*/
            createjs.Ticker.addEventListener("tick", update);

            /* 计时模式为TIMEOUT的情况下,framerate=5,
             * 故该函数会每隔1/5秒的频率被调用*/
            function update(event) {
                shape.x += Math.random() * 300;
                shape.y += Math.random() * 300;
                /* 这个500是canvas的宽度,可以通过获得canvas对象.width获得
                 * 如果shape的起始点x坐标大于canvas宽度,则初始化shape.x=0*/
                if (shape.x > 500) {
                    shape.x = 0;
                }
                /*如果shape的起始点y坐标大于canvas高度,则初始化shape.y=0*/
                if (shape.y > 500) {
                    shape.y = 0;
                }
                /*每一次变化都需要通过update()来更新舞台即stage*/
                stage.update();
            }
        }
    </script>
</head>
<body onload="init()">
<!--emment写法:canvas#demoCanvas[width=500,height=500]{您的浏览器不支持}-->
<canvas id="demoCanvas" width="500" height="500">您的浏览器不支持</canvas>
</body>

澳门葡京 22

上述代码示例效果图

三、裁剪

var  canvas=document.getElementById(“myCanvas”);

var  context=canvas.getContext(“2d”);

//绘制三个三角形

context.beginPath();

context.moveTo(200,200);

context.lineTo(250,200);

context.lineTo(225,150);

context.closePath();

context.stroke();

//调用裁剪

context.clip();

var  img= newImage();

img.src=”img/20150821130732_anQeR.jpeg”;

img.onload=function() {

context.drawImage(img,0,0);

}

//你上边画的是什么形象,裁剪出来的就是怎么着模样


4、使用图像数据

var  canvas=document.getElementById(“myCanvas”);

var   context=canvas.getContext(“2d”);

//getImageData()取的本来图像数据

//有四个参数:第一3个参数,先导获得像素的x,y坐标,第壹八个参数,获取像素点的宽高。

//var  ImageData=context.getImageData(0,0, img.width, img.height);

那边再次回到的对象是getImageData()的实例,每一种getImageData()对象都有八个天性:width、height、data。

width和height表示访问像素区域大小

//当中data属性是贰个数组,保存着图像中每五个像素的数码。

//在data数据中,每2个像素用4个因向来保存,分别表示红、绿、蓝和反射率。

//数组中的各种成分都以介于0和255以内的,能够直接待上访问到原始图像数据,

//就可见以各样办法来操作那几个数据。

var  img= newImage();

img.src=”img/20150821130732_anQeR.jpeg”;

img.onload=function() {

context.drawImage(img,0,0);

var   ImageData=context.getImageData(0,0, img.width, img.height);

var   data=ImageData.data;

//注意:每一回循环控制变量i都递增肆,在收获每种像素的红、绿、蓝颜色值后,

//总计出她们的平均值,再把这么些平均值设置为各种颜色的值,

//结果就是去掉了每一个像素的颜色,只保留了亮度接近的灰度值.(用伍彩变黑白)

for(var i=0; i<data.length; i+=4){

var  r=data[i];

var  g=data[i+1];

var  b=data[i+2];

//求rgb的平均值,

var  gray=(r+g+b)/2;

//设置颜色值

data[i]=gray;

data[i+1]澳门葡京,=gray;

data[i+2]=gray;

}

//putImageData()方法把图像数据绘制到画布上,有多少个参数

//第一个参数,获取ImageData,第三八个参数,要放到画布上的x,y坐标

context.putImageData(ImageData,0,0);

}


五、canvas录像处理

function animation( ){

//video.ended 属性重返音频/录像是不是已甘休。重临值:布尔值true|false。倘若播放已甘休,则赶回 true。不然重回 false。

if(!video.ended){

//将录像的每1帧,绘制在canvas上

context.drawImage(video,0,0,canvas.width,canvas.height);

window.requestAnimationFrame(animate);

}

}

//当录像能够播放时,实行播报调用循环

//video的oncanplay事件类似于图像的onload,加载成功之后

//oncanplay 事件在用户可以开首播报录像/音频(audio/video)时接触。

//object.oncanplay=function(){myScript};

//object.addEventListener(“canplay”,myScript);

video.oncanplay=function(e){

video.play( );

window.requestAnimationFrame(animate);

}


六、canvas动画

最原始的你还是可以应用window.set提姆out()大概window.setInterval()通过不断更新成分的状态地方等来促成动画,前提是镜头的换代频率要高达每秒伍拾陆次才能让眼睛看到流畅的动画片效果。

window.requestAnimationFrame()通过递归调用同一方法来不断更新画面以高达动起来的功效,但它优于setTimeout/setInterval的地点在于它是由浏览器专门为动画片提供的API,在运转时浏览器会活动优化措施的调用,并且只要页面不是激活状态下的话,动画会自动刹车,有效节约了CPU费用。

注销该次动画:能够直接调用,也足以通过window来调用,接收3个函数作为回调,重返三个ID值,通过把这几个ID值传给window.cancelAnimationFrame()可以收回该次动画。

window.requestAnimationFrame()方法用于告诉浏览器,你想在浏览器的下个重绘
在此以前来执行一个卡通大概实施浏览器通过调用贰个一定的函数来更新动画的伏乞。该方法会在下次重临在此之前实施三个当作参数的回调函数。

window.requestAnimationFrame
是特意为完成高质量的帧动画而设计的二个API,近年来已在七个浏览器获得了支撑,包含IE十+,Firefox,Chrome,Safari,Opera等,在活动装备上,ios陆上述版本以及IE
mobile
10以上也援救requestAnimationFrame,唯一相比遗憾的是时下安卓上的原生浏览器并不援救requestAnimationFrame,不过对requestAnimationFrame的匡助应该是必定了,安卓版本的chrome
16+也是扶助requestAnimationFrame的。

例子window.requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;


七、落成多少个小球随机械运输动,用面向对象的法子

var   canvas=document.getElementById(“myCanvas”);

var   context=canvas.getContext(“2d”);

//圆是三个类,就是目的唯有八个,便是圆

functionCircle(x,y,r,speedX,speedY,color) {

//全体的性情

this.r=r;

this.x=x;

this.speedX=speedX;

this.speedY=speedY;

this.y=y;

this.color=color;

}

//在原型上写方法,

//第3个格局,画圆

Circle.prototype.draw=function() {

context.beginPath();

context.fillStyle=this.color;

context.arc(this.x, this.y, this.r,0, Math.PI*2);

context.fill();

}

//第一个法子,运动

Circle.prototype.move=function() {

//那里改变x递加的值,可以变更运动速度

this.x+=this.speedX;

this.y+=this.speedY;

if(this.x>=canvas.width-this.r||this.x<=this.r) {

this.speedX*= -1;

}

if(this.y>=canvas.height-this.r||this.y<=this.r) {

this.speedY*= -1;

}

}

//实行实例化操作

//完毕同时出现多少个小球,必要同时实例化出多个目的

//储存new出来的实例化对象数组

var   arr=[ ];

//来众多个小球

for(var  i=0; i<100; i++) {

//设置1个Infiniti制的半径

var   R=randomNum(30,5);

//随飞机位置置

var   X=randomNum(canvas.width-R, R);

var    Y=randomNum(canvas.height-R, R);

//随机速度

var   speedX=randomNum(8,1);

var    speedY=randomNum(8,1);

//随机颜色

var    
COLOR=”rgb(“+randomNum(255,0)+”,”+randomNum(255,0)+”,”+randomNum(255,0)+”)”;

//将对像实例化

var    newCircle= newCircle(X, Y, R, speedX, speedY, COLOR);

arr.push(newCircle)

}

moveCircle();

//定义一个实践动画的函数

function    moveCircle() {

//先清理画布

context.clearRect(0,0, canvas.width, canvas.height);

//循环执行实例化对象的数组

for(var  i=0; i<arr.length;i++){

arr[i].draw();

arr[i].move();

}

//执行动画

window.requestAnimationFrame(moveCircle);

}

//定义2个随便数的函数

functionrandomNum(max,min) {

returnparseInt(Math.random()*(max-min+1)+min);

}

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website