您的位置:时时app平台注册网站 > web前端 > #7 高端canvas内容:阴影, clip()等

#7 高端canvas内容:阴影, clip()等

2019-11-03 09:34

效果:流星雨

图片 1

四.路线方向和零和原则

零和原则: 密封图形内部是还是不是填充颜色和渠道的趋向有关,从密封图形的中间引出一条射线,钦定二个方向为正方向,与正方向相交则 1,与反方向相交-1,最终总和不为0,则该区域为填充区域;总和为0则该区域不开展填空

如图,鲜蓝色部分相交之和为0,所以不开展填空

图片 2

可以借助那几个法规来绘制出剪纸效果

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

最后效果:

图片 3

12种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:重叠部分变亮,别的部分符合规律展现
  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>

图片 4

type为xor的机能图

画生龙活虎颗流星

科学,的却是没那几个api,可是不意味着大家画不出来。扫帚星正是叁个小石块,然后因为速迈过快发生大批量的热能拉动相近的氛围发光发热,所以经飞过的地点看起来就好像扫帚星的漏洞,大家先研商一下扫帚星那几个图像,整个流星处于他和谐的活动轨迹之中,当前的岗位最亮,轮廓最显著,而早先划过的地点离当下地方轨迹间隔越远就越暗淡越模糊。

地方的分析结果很关键, canvas 上是每黄金时代帧就重绘一遍,每生机勃勃帧之间的时日间距非常的短。扫帚星经过的地点会越来越模糊最终灭亡不见,那有未有能够让画布画的图像每过风度翩翩帧就变模糊一点而不是整整肃清的章程?若是能够这么,就足以把每后生可畏帧用线段画一小段流星的运动轨迹,最终画出流星的成效。

图片 5

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

图片 6

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

 图片 7

下面几幅图笔者是在 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();

clearRect(x, y, width, height)

清除钦点宽高范围内的画布,多用来动漫重新绘制新的图腾

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

为ctx设置阴影效果后,在日前ctx状态下,canvas中绘制的图像都将面世阴影。

功效:风流倜傥颗流星

图片 8

sogoyi 快看,生龙活虎颗活泼不做作的流星!!! 是还是不是感到动起来更为绘声绘色一点?

探照灯效果和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;
  }
}   

探照灯效果

目的:

经过掌握弧度与sin及cos的关系,能够凭仗弧度及半径求出旋转钦点弧度后所达到的dx,dy坐标

最后效果

累计 globalCompositeOperation 之后的功用既最后效果:

 图片 9

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

快约上您的阿妹看扫帚星雨啊。

怎么着? 你未有妹子?

图片 10

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

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

行使格局:

ctx.globalCompositeOperation = type

流星雨

咱俩再加三个流星雨 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();

globalCompositeOperation

这么些值的特性超级多,重要用来安装图形相互叠合时展现的成效,其出示效果能够分成3组

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卡塔 尔(阿拉伯语:قطر‎

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卡塔 尔(英语:State of Qatar)
  • destination-in: 只展现图形交叉部分(A∩B卡塔 尔(英语:State of Qatar)

3.别样情况

  • lighter: 交叉部分的颜料变浅
  • copy: 只复制最终绘制的图形B
  • xor: 交叉部分被去掉即(A∪B - A∩B卡塔 尔(阿拉伯语:قطر‎

除此之外上边的11种,还应该有更加的多的选项:

globalCompositeOperation 具体文书档案

弧度与sin及cos的关系


开始

妹子都喜爱流星,如若她说不赏识,那他必然是八个假妹子。

到现在就伙同来做一场流星雨,用技师的野门路洒脱须臾间。

要画一场扫帚星雨,首先,自然大家要会画风流浪漫颗彗星。

玩过 canvas 的同校,你画圆画方画线条这么 6,假使说叫你画下面那几个玩意儿,你会不会认为您用的是假 canvas?canvas 未有画二个带尾巴玩意儿的 api 啊。

图片 11

风姿浪漫.阴影功效

本条意义和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为最大宽度
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,图像会推广即模糊;反之则缩短卡塔尔国

晶莹剔透背景

先不急着激动,这几个流星雨有一些单调,能够观望地点的代码中,每生龙活虎帧,大家用了反射率为 0.2 的紫水晶色刷了贰回画布,背景紫灰一片,如果说大家的急需是晶莹背景啊?

诸如,我们要用这些夜景图片做背景,然后在地点加上大家的流星,大家每风姿洒脱帧刷风流罗曼蒂克层背景的小手段就用持续啦。因为我们要保证除开彗星之外的生龙活虎对,应该是晶莹剔透的。

图片 12

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

图片 13

这么些属性表明没必要稳重看,更不用记下来,直接看 api 示例 运维作效果果就很明亮了。示例里,先绘制的是填充星型,后绘制的是填充圆形。

图片 14

是或不是柳暗花明,成竹在胸?

对于大家的话,原图疑似每生龙活虎帧画完的有着扫帚星,目的图疑似画完扫帚星之后半透明覆盖画布的暗黄矩形。而笔者辈每风华正茂帧要保存的正是,上风度翩翩帧 0.8 折射率的流星,覆盖画布士林蓝矩形我们不可能显得。

小心这里的 destination-out 和 destination-in,示例中那五个本性最后都唯有点源图像保留了下来,相符大家假若保留扫帚星的要求。小编觉着 w3cschool 上叙述的不是很正确,小编用自身要好的精晓归纳一下。

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

上述示范目的图像的发光度是 1,源图像被核减的有些是完全不见了。而大家想要的是他得以依据指标发光度进行一些擦除。改一下示范里的代码看看是还是不是援助半晶莹剔透的精兵简政。

图片 15

总的看这一个个性协理半晶莹剔透的乘除。源图像和对象图像交叠的片段以半透明的格局保留了下来。相当于说如果大家要保存 0.8 光滑度的扫帚星,能够这么设置 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);

本章主要介绍以下几个地方:

以身作则代码:
<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>

图片 16

上述代码示例效果图

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

则其效能为:

图片 17

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

图片 18

上述代码效果图

  • 阴影效果shadowColor, shadowOffsetX...
  • 大局反射率globalAlpha设置,图像叠加时的功能globalCompositeOperation
  • clip() 设置绘制区域,探照灯效果和基本canvas的动漫模型
  • 零和原则制作剪纸效果
  • isPointInPath()剖断点的职责,clearRect()清空矩形画布

Canvas图形综合操作globalCompositeOperation


五. clearRect, isPointInPath##

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

globalAlpha

本条天性相对来讲比较轻巧,主若是安装二个大局的阿尔法值。这么些值和 rgba(0,0,0,alpha) 中的阿尔法的效果与利益等同,只不过这么些是安装全局的发光度

ctx.globalAlpha = 0.7

Canvas的图像绘制:drawImage


二.globalAlpha && globalCompositeOperation

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

图片 19

提到图解

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

CreateJs之EaselJs底工应用


弧度(angle)与角度(degree)的关系:
  • 360角度 = 2π
  • 1角度 = π/180弧度
  • 1弧度 = 180/π角度

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

EaselJs怎样运用?
  1. 引入easeljs的js文件 <script src="http://www.zhikejy.com/uploads/allimg/191103/0934404591-19.jpg"></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();

假使必要依照钦赐的帧频率变化舞台,继续看下方:
8.设置帧频率计时方式createjs.Ticker.timingMode = createjs.Ticker.RAF;
9.安装刷新频率fsp值createjs.Ticker.framerate = 10;即10fsp,1/10秒的速度刷新。
10.设置Ticker的tick事件监听createjs.Ticker.addEventListener("tick", func);
11.定义func;通过tick事件,会依照钦赐的效用试行该func函数;全数对舞台的操作在这里地管理即可,记得更新舞台stage.update();

*注意点:
1.默许的计时格局为createjs.Ticker.TIMEOUT,
2.RAF计时形式下,framerate无效,
3.RAF情势下动画功能更流畅,
4.没有必要按钦点帧频率时,可接收RAF计时情势

Canvas绘制阴影效果


EaselJs是什么?

EaselJs:三个javascript库,方便更赶快的拍卖canvas。

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

图片 20

上述代码示例效果图

底蕴运用的示范代码:
<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>

图片 21

上述代码示例效果图

代码示例:
<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>

图片 22

上述代码效果图

功能:

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

接受办法:
  • shadowOffsetX:间隔图形当前坐标轴x轴的偏移量,私下认可值为0
  • shadowOffsetY:间距图形当前坐标轴y轴的偏移量,暗许值为0
  • shadowColor:阴影的颜料,私下认可值为fully-transparent black,即透明
  • shadowBlur:阴影的歪曲程度,暗中认可值为0

本文由时时app平台注册网站发布于web前端,转载请注明出处:#7 高端canvas内容:阴影, clip()等

关键词: