撩妹技能,canvas基础第贰节

By admin in 4858美高梅 on 2019年4月2日

开始

二嫂都欣赏流星,如若她说不希罕,那他早晚是3个假妹子。

于今就一起来做一场流星雨,用程序员的野路子罗曼蒂克弹指间。

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

玩过 canvas 的校友,你画圆画方画线条这么
陆,要是说叫你画上边那么些玩意儿,你会不会认为您用的是假 canvas?canvas
未有画2个带尾巴玩意儿的 api 啊。

4858美高梅 1

本章主要介绍以下多少个方面:

弧度与sin及cos的关系


1、图形的咬合方式

画1颗流星

正确,的却是没这些api,然则不意味着大家画不出去。流星正是3个小石块,然后因为速度过快产生大批量的热能拉动周边的空气发光发热,所以经飞过的地点看起来就像流星的漏洞,大家先商量一下流星那些图像,整个流星处于他协调的位移轨迹之中,当前的职责最亮,概略最清晰,而此前划过的地点离当下岗位轨迹距离越远就越暗淡越模糊。

地点的解析结果很要紧, canvas
上是每1帧就重绘叁回,每1帧之间的时光间隔非常的短。流星经过的地点会特别混淆最后毁灭不见,那有未有能够让画布画的图像每过一帧就变模糊一点而不是整整解除的不贰法门?假若能够这么,就能够把每壹帧用线段画一小段流星的移位轨迹,最终画出流星的遵从。

4858美高梅 2

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

4858美高梅 3

什么? 依旧不像? 大家把它画小点,那下总该像了把?

 4858美高梅 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的卡通片模型
  • 零和原则制作剪纸效果
  • isPointInPath()判断点的职位,clearRect()清空矩形画布
目的:

通过通晓弧度与sin及cos的涉及,能够依照弧度及半径求出旋转钦定弧度后所到达的dx,dy坐标

globalAlpha是一个介于0和壹之内的值(包蕴0和一),用于内定全体绘制的反射率。暗中认可值为0。假设全部继续操作都要基于相同的反射率,就足以先把globalAlpha设置为适当班值日,然后绘制,最终在把它设置回私下认可值0.

//绘制贰个革命的矩形

context.fillStyle=”red”;

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

效益:一颗流星

4858美高梅 5

sogoyi 快看,一颗活泼不做作的流星!!! 是或不是感到动起来越发有板有眼一点?

一.阴影功用

这些意义和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/π)

//修改全局折射率

流星雨

咱俩再加2个流星雨 MeteorShower
类,生成多一些随便地方的流星,做出流星雨。

// 坐标
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为半径,为斜边长

4858美高梅 6

关联图解

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

context.globalAlpha=0.5;

//绘制深紫红矩形

context.fillStyle=”blue”;

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

效果:流星雨

4858美高梅 7

globalAlpha

那本本性相对来说相比较简单,重假使设置二个大局的alpha值。那个值和
rgba(0,0,0,alpha) 中的阿尔法的作用壹样,只不过那个是安装全局的光滑度

ctx.globalAlpha = 0.7
伍角星代码示例1
<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>

4858美高梅 8

上述代码效果图

//重置全局光滑度

透明背景

先不急着激动,这一个流星雨有点单调,能够看看上边的代码中,每1帧,大家用了发光度为
0.二 的银白刷了叁次画布,背景湖蓝一片,假如说大家的需借使晶莹剔透背景啊?

譬如,大家要用那几个夜景图片做背景,然后在上头加上大家的流星,大家每1帧刷壹层背景的小伎俩就用持续啦。因为大家要确认保证除开流星之外的一些,应该是晶莹的。

4858美高梅 9

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

4858美高梅 10

那么些属性表明没须要仔细看,更不用记下来,直接看 api
示例 运转效果就很清楚了。示例里,先绘制的是填充星型,后绘制的是填充圆形。

4858美高梅 11

是还是不是柳暗花明,一目通晓?

对于大家来说,原图像是每一帧画完的全体流星,目的图像是画完流星之后半晶莹剔透覆盖画布大巴林蓝矩形。而我们每1帧要封存的就是,上一帧
0.八 发光度的流星,覆盖画布中黄矩形大家无法展现。

留神那里的 destination-out 和
destination-in,示例中那四个属性最后都唯有1部分源图像保留了下来,符合我们只要保留流星的必要。小编认为
w三cschool 上讲述的不是很不错,小编用本身要好的明亮归纳一下。

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

上述示范指标图像的光滑度是
一,源图像被削减的有的是截然不见了。而作者辈想要的是他得以依据指标光滑度举办部分擦除。改一下演示里的代码看看是或不是支持半透明的乘除。

4858美高梅 12

总的来说那些天性辅助半透明的计量。源图像和对象图像交叠的一部分以半晶莹剔透的款式保留了下去。也正是说要是大家要保留
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

本条值的质量相比多,重要用来安装图形相互叠加时展现的功力,其出示效果能够分成叁组

1.后绘制的图形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)

二.后绘制的图形B在前方绘制的图形A的底下

那种状态和地方的景况就是图形的z-index改变了,别的的同样。也有3种属性

  • 撩妹技能,canvas基础第贰节。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
具体文书档案

五角星代码示例贰
<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>

4858美高梅 13

上述代码示例效果图

context.globalAlpha=0;

//这么些事例深彩虹色矩形会表现半晶莹剔透效果,透过它能够见到下边包车型大巴革命矩形。

终极效果

加上 globalCompositeOperation 之后的效益既最后效果:

 4858美高梅 14

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

快约上您的胞妹看流星雨啊。

怎样? 你未曾妹子?

4858美高梅 15

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

叁.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)

则其成效为:

4858美高梅 16

Canvas图形综合操作globalCompositeOperation


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

source-over(默许值):后绘制的图片位于先绘制的图纸上方。

source-in:后绘制的图片与先绘制的图纸重叠的局地可见,两者其余部分完全透明。

source-out:后绘制的图形与先绘制的图形不重叠的有个别可知,先绘制的图样完全透明。

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

destination-over:后绘制的图片位于先绘制的图片下方,后绘制的图纸唯有在此以前透明像素下的片段才可知,被挡住的一部分不可知。

destination-in:后绘制的图片位于先绘制的图纸下方,两者不重叠的局部完全透明。就是显示重叠的片段的形状,展现先绘制的图样的颜色。

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

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

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

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

xor:后绘制的图纸与先绘制的图纸重叠的壹些进行“异或”操作;图像异或,相异为一,相同为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

目的图像:已经嵌入画布中的绘图

四.路径方向和零和原则

零和原则:
封闭图形内部是还是不是填充颜色和路线的方向至于,从封闭图形的里边引出一条射线,钦赐三个势头为正方向,与正方向相交则+一,与反方向相交-一,最终总和不为0,则该区域为填充区域;总和为0则该区域不开始展览填空

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

4858美高梅 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()

末段效果:

4858美高梅 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:原图形只绘制在新图片之上,原图形别的1些常规展现
  9. lighter4858美高梅,:重叠部分变亮,别的部分符合规律展现
  10. darker:重叠部分变暗,其余1些常规展现
  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>

4858美高梅 19

type为xor的作用图

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

在使用globalCompositionOperation的状态下一定要多测壹些浏览器,因为差异的浏览器对那一个个性的贯彻依旧存在较大的出入。


五. clearRect, isPointInPath##

Canvas绘制阴影效果


贰、使用图片

//第一种写法:第2个参数:图片对象;第一个参数是初步画的x坐标;第多个参数:先河画的y的坐标;

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

//第三种写法:第二个参数:图片对象;第2个参数:是始于画的x坐标;第多个参数:伊始画的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)

判定一个点是不是在有个别区域内

相似拿走鼠标在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>

4858美高梅 20

上述代码效果图

img.onload=function(){

Canvas的图像绘制:drawImage


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

功能:

通过canvas的drawImage方法 ,将点名图片绘制到canvas画布上。

}

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

综合选择drawImage( )和其它格局,能够对图像举办各样基本操作。而操作的结果能够经过toDataU哈弗L( )方法得到。然而有1个例外,即图像不能够来自别的域。要是图像来自其余域,调用toDataULacrosseL( )会抛出错误。

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提供了toDataU途锐L的接口,能够便宜的将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>

4858美高梅 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:叁个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成分创立四个createjs的舞台
    var stage = new createjs.Stage("demoCanvas");
  4. 创办要求被添加到舞台的靶子,如创立二个图形对象
    var circle = new createjs.Shape();
  5. 对图纸对象举行拍卖,如画二个圆circle.graphics.beginFill("DeepSkyBlue").drawCircle(0, 0, 50);
  6. 将图纸对象添加到舞杜阿拉去 stage.addChild(circle);
  7. 创新舞台 stage.update();

要是须要依据钦赐的帧频率变化舞台,继续看下方:
捌.设置帧频率计时形式createjs.Ticker.timingMode = createjs.Ticker.RAF;
9.安装刷新频率fsp值createjs.Ticker.framerate = 10;即10fsp,1/10秒的速度刷新。
10.设置Ticker的tick事件监听createjs.Ticker.addEventListener("tick", func);
1①.定义func;通过tick事件,会依据钦赐的频率执行该func函数;全体对舞台的操作在此间处理即可,记得更新舞台stage.update();

*注意点:
一.暗中认可的计时情势为createjs.Ticker.TIMEOUT,
2.RAF计时情势下,framerate无效,
3.RAF形式下动画效率更通畅,
四.不须要按钦命帧频率时,可使用RAF计时方式

document.location.href = dataURL;

break;

}

}

好好的情形是页面上有多少个点击链接:

1、Image Tag

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

2、New Window

开拓一个新的窗口,并出示一个PNG格式的图形

3、Download

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

很悲伤,点击并未反映,为何吗?小编做了无数试验,原因出在图纸渲染上,canvas上1经添加图片,toDataU奇骏L()将失效,获取不到canvas新闻。通过不难几步来评释那些难题。

把js脚本中图纸渲染的有个别去除,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>

4858美高梅 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()取的原本图像数据

//有七个参数:第三贰个参数,发轫得到像素的x,y坐标,第壹八个参数,获取像素点的宽高。

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

此地重临的靶子是getImageData()的实例,每一个getImageData()对象都有多本性格:width、height、data。

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

//在那之中data属性是二个数组,保存着图像中每八个像素的数量。

//在data数据中,每八个像素用多个要向来保存,分别代表红、绿、蓝和反射率。

//数组中的每一种成分都以介于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){

//将录制的每壹帧,绘制在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来调用,接收多个函数作为回调,再次来到三个ID值,通过把这些ID值传给window.cancelAnimationFrame()能够打消该次动画。

window.requestAnimationFrame()方法用于告诉浏览器,你想在浏览器的下个重绘
此前来执行多个动画或许实施浏览器通过调用2个一定的函数来更新动画的呼吁。该方法会在下次重返在此之前实施三个用作参数的回调函数。

window.requestAnimationFrame
是尤其为贯彻高性能的帧动画而设计的一个API,近期已在多少个浏览器获得了支撑,包涵IE10+,Firefox,Chrome,Safari,Opera等,在运动设备上,ios陆上述版本以及IE
mobile
10上述也帮衬requestAnimationFrame,唯一比较遗憾的是当前安卓上的原生浏览器并不协助requestAnimationFrame,可是对requestAnimationFrame的支撑应该是必然了,安卓版本的chrome
1陆+也是支撑requestAnimationFrame的。

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


7、达成多个小球随机械运输动,用面向对象的办法

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++) {

//设置贰个随机的半径

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);

}

//定义四个即兴数的函数

functionrandomNum(max,min) {

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

}

发表评论

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

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有