canvas画板基础应用的学习
canvas是html5中的绘图容器,我们可以通过javascript的控制来进行图形的绘制,绘制对象可以是路径、盒、圆、字符等,同时,你也可以通过js给画布添加图像,下面来介绍canvas的各种基本的用法:
1、首先,我们需要在html标签中创建一个canvas标签,并且通过脚本对其进行引入。
- <canvas id="myCanvas" width="200" height="100" style="border:1px solid red">
- </canvas>
- var c=document.getElementById("myCanvas");
- var ctx=c.getContext("2d");
在这里,getContext("2d") 对象是内建的 HTML5 对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。我们对canvas画布的所有操作都是针对ctx而言的。
2、基本图形的绘制方法(线,圆,盒子)
(1)绘制基本的线条
- ctx.moveTo(0,0); // 定义画笔开始的起始点坐标
- ctx.lineTo(200,100); // 定义画笔结束的结束点坐标
- ctx.stroke(); // 执行绘画操作
(2)绘制圆形
ctx.arc(x, y, r, 其实弧度值, 结束弧度值, boolean) boolean为true时逆时针, false为顺时针,默认状态为false
- ctx.beginPath(); // 开启绘画的状态
- ctx.arc(95,50,40,0,2*Math.PI); // 定义绘制圆形的圆心坐标, 半径等参数
- ctx.stroke();
(3)利用canvas进行文本的绘制
绘制实心字体
- ctx.font="30px Arial"; //设置字体大小和样式
- ctx.fillText("Hello World",10,50); // 设置文本内容, 文本起始点的x, y轴坐标
绘制空心字体
- ctx.font="30px Arial";
- ctx.strokeText("Hello World",10,50);
3、渐变在canvas中的运用
渐变可以填充在矩形, 圆形, 线条, 文本等等, 各种形状可以自己定义不同的颜色。
以下有两种不同的方式来设置Canvas渐变:
- createLinearGradient(x,y,x1,y1) - 创建线条渐变
- createRadialGradient(x,y,r,x1,y1,r1) - 创建一个径向/圆渐变
当我们使用渐变对象,必须使用两种或两种以上的停止颜色。
addColorStop()方法指定颜色停止,参数使用坐标来描述,可以是0至1.
使用渐变,设置fillStyle或strokeStyle的值为 渐变,然后绘制形状,如矩形,文本,或一条线。
- //创建一个线性的渐变
// 创建渐变- var grd=ctx.createLinearGradient(0,0,200,0);
- grd.addColorStop(0,"red");
- grd.addColorStop(1,"white");
- // 填充渐变
- ctx.fillStyle=grd;
- ctx.fillRect(10,10,150,80);
// 创建一个径向的渐变
// 创建渐变
var grd=ctx.createRadialGradient(75,50,5,90,60,100); grd.addColorStop(0,"red"); grd.addColorStop(1,"white");- // 填充渐变
ctx.fillStyle=grd; ctx.fillRect(10,10,150,80);
4、外部图片的引入
ctx.drawImage();
- html
- <img src="http://n.sinaimg.cn/translate/20170218/v8d2-fyarrcf4608880.jpg" id="img"/>
- <canvas height="200" width="200" id="myCanvas"></canvas>
- js
- var canvas = document.querySelect("#myCanvas");
- var ctx = canvas.getContext("2d");
- var img = document.querySelect("#img");
- ctx.drawImage(img,10,10);
以上是canvas的最最最基本的一些操作,当然,canvas还可以实现更多强大的功能, 绘制出来更绚丽的图形,通过与js的 结合还可以进行游戏页面的设计及游戏开发
下面是一个用canvas为基本结构绘制的《打灰机✈️》游戏,希望大家多多指
- html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- <style media="screen">
- #canvas{
- display: block;
- margin: 0 auto;
- background: lightgray;
- border: 1px solid darkgray;
- }
- </style>
- </head>
- <body>
- <canvas id="canvas" width="640" height="960"></canvas>
- <audio src="audio/game_music.mp3" id="gameMusic"></audio>
- <audio src="audio/bullet.mp3" id="bullet"></audio>
- <audio src="audio/enemy_out.mp3" id="out"></audio>
- <audio src="audio/enemy_down.mp3" id="down"></audio>
- <audio src="audio/game_over.mp3" id="gameOver"></audio>
- </body>
- <script src="js/mian.js" charset="utf-8"></script>
- </html>
- main.js
- window.onload = function (){
- var scene = new Scene();
- // 添加背景
- var position = new Position(0, -scene.canvas.height);
- var size = new Size(scene.canvas.width, scene.canvas.height + 10);
- var velocity = new Velocity(0, 2);
- var background = new Spirit(position, size, velocity, 'images/bg_01.jpg', 'background');
- position = new Position(0, 0);
- var backgroundRepeat = new Spirit(position, size,velocity, 'images/bg_02.jpg', 'background');
- scene.addRole(background);
- scene.addRole(backgroundRepeat);
- // 添加我方飞机
- size = new Size(64, 72);
- position = new Position((scene.canvas.width - size.width) / 2, scene.canvas.height - size.height);
- velocity = new Velocity(0, 0);
- var aircraft = new Spirit(position, size, velocity, 'images/aircraft.png', 'aircraft');
- scene.addRole(aircraft);
- // 添加键盘监听事件
- document.onkeydown = function (event){
- switch (event.keyCode) {
- case 37:
- aircraft.velocity.x = -5;
- break;
- case 38:
- aircraft.velocity.y = -5;
- break;
- case 39:
- aircraft.velocity.x = 5;
- break;
- case 40:
- aircraft.velocity.y = 5;
- break;
- }
- console.log(event.keyCode);
- if (!scene.start && event.keyCode == 13) {
- window.location.reload();
- }
- };
- document.onkeyup = function(){
- aircraft.velocity.x = 0;
- aircraft.velocity.y = 0;
- }
- scene.canvas.onclick = function (event){
- var x = event.clientX - this.offsetLeft;
- var y = event.clientY - this.offsetTop;
- if (!scene.start && x > 220 && x < 420 && y > 520 && y <) {
- window.location.reload();
- }
- }
- // var requestId = null;
- function gameStart(){
- var gameMusic = document.querySelector('#gameMusic');
- gameMusic.loop = 'loop';
- gameMusic.volume = 0.2;
- gameMusic.play(); // 播放背景音乐
- document.querySelector('#gameOver').pause();
- requestAnimationFrame(launch);
- }
- // 场景加载
- var count = 0;
- var speed = 2;
- function launch(){
- scene.redraw();
- if (scene.start) {
- count++;
- if (scene.score < 200000) {
- speed = 2;
- } else if (scene.score >= 200000 && scene.score <) {
- speed = 4;
- } else if (scene.score >= 500000) {
- speed = 10;
- }
- if (count % 40 == 0) {
- var index = 0;
- if (Math.random()*1000 <) {
- index = 0;
- }
- if (Math.random()*1000 >= 750 && Math.random()*1000 <) {
- index = 1;
- }
- if (Math.random()*1000 >= 800 && Math.random()*1000 <) {
- index = 2;
- document.querySelector('#out').play();
- }
- if (Math.random()*1000 >= 890) {
- index = 3;
- }
- var size1 = new Size(50, 30);
- var size2 = new Size(70, 90);
- var size3 = new Size(110, 170);
- var size4 = new Size(58, 88);
- var sizes = [size1, size2, size3, size4];
- var position = new Position(Math.random() * (scene.canvas.width - sizes[index].width), -sizes[index].height);
- var velocity = new Velocity(0, speed);
- if (index == 3) {
- plane = new Spirit(position, sizes[index], velocity, 'images/ufo1.png', 'brolly');
- }else {
- var enemy = 'images/flivver'+(index + 1)+'.png';
- var plane = new Spirit(position, sizes[index], velocity, enemy, 'flivver');
- }
- plane.hp = Math.pow(index,3);
- switch (index) {
- case 0:
- plane.score = 1000;
- plane.hp = 1;
- break;
- case 1:
- plane.score = 5000;
- plane.hp = 4;
- break;
- case 2:
- plane.score = 10000;
- plane.hp = 9;
- // 大飞机出来时的音效
- break;
- }
- scene.addRole(plane);
- }
- }
- for (var i = 0; i <= scene.buttles; i++) {
- if (i < 3) {
- var speed1 = 20, speed2 = 5;
- }
- if (i >= 3 & i <) {
- var speed1 = 10, speed2 = 8;
- }
- if (i >= 10) {
- var speed1 = 4, speed2 = 13;
- }
- }
- switch (scene.buttles) {
- case 0:
- bullet (count, aircraft, scene,0, speed1, speed2,0);
- break;
- case 1:
- bullet (count, aircraft, scene,-15, speed1, speed2,0);
- bullet (count, aircraft, scene,15, speed1, speed2,0);
- break;
- case 2:
- bullet (count, aircraft, scene,0, speed1, speed2,0);
- bullet (count, aircraft, scene, -15, speed1, speed2,0.2);
- bullet (count, aircraft, scene,15, speed1, speed2,-0.2);
- break;
- case 3:
- bullet (count, aircraft, scene,7, speed1, speed2,0);
- bullet (count, aircraft, scene, -7, speed1, speed2,0);
- bullet (count, aircraft, scene,21, speed1, speed2,-0.2);
- bullet (count, aircraft, scene,-21, speed1, speed2,0.2);
- break;
- case 4:
- bullet (count, aircraft, scene,10, speed1, speed2,0);
- bullet (count, aircraft, scene,0, speed1, speed2,0);
- bullet (count, aircraft, scene, -10, speed1, speed2,0);
- bullet (count, aircraft, scene,20, speed1, speed2,Math.random() *5);
- bullet (count, aircraft, scene,-20, speed1, speed2,-Math.random() *5);
- break;
- default:
- bullet (count, aircraft, scene,10, speed1, speed2,0);
- bullet (count, aircraft, scene,0, speed1, speed2,0);
- bullet (count, aircraft, scene, -10, speed1, speed2,0);
- bullet (count, aircraft, scene,20, speed1, speed2, -Math.random() *5);
- bullet (count, aircraft, scene,-20, speed1, speed2, Math.random() *5);
- }
- requestAnimationFrame(launch);
- }
- gameStart();
- }
- // 创建对应所需信息
- // 设置位置对象
- function Position(x, y){
- this.x = x;
- this.y = y;
- }
- // 设置尺寸对象
- function Size(width, height){
- this.width = width;
- this.height = height;
- }
- // 定义增量信息
- function Velocity(x, y){
- this.x = x;
- this.y = y;
- }
- /****************设置精灵对象******************/
- function Spirit(position, size, velocity, chartlet, type){
- this.position = position;
- this.size = size;
- this.velocity = velocity;
- this.type = type;
- this.hp = 0; // 精灵的血量值
- this.chartlet = new Image();
- this.chartlet.src = chartlet;
- // 最大位置,用于检测边界
- this.maxPosition = new Position(this.position.x + this.size.width, this.position.y + this.size.height);
- // 根据当前位置计算出下一位置坐标
- this.nextPosition = function (){
- this.position.x += this.velocity.x;
- this.position.y += this.velocity.y;
- this.maxPosition.x = this.position.x + this.size.width;
- this.maxPosition.y = this.position.y + this.size.height;
- };
- this.previousPosition = function(){
- this.position.x -= this.velocity.x;
- this.position.y -= this.velocity.y;
- this.maxPosition.x = this.position.x + this.size.width;
- this.maxPosition.y = this.position.y + this.size.height;
- };
- // 根据精灵的信息进行绘制
- this.draw = function (ctx){
- ctx.drawImage(this.chartlet, this.position.x, this.position.y, this.size.width, this.size.height);
- };
- }
- /*******************定义游戏场景类***********************/
- function Scene(){
- // 获取场景对应的画布和图形上下文信息
- this.canvas = document.querySelector('#canvas');
- this.ctx = this.canvas.getContext('2d');
- this.spirits = []; // 定义spirit数组来保存精灵信息
- // this.requestId = null;
- this.start = true; // 控制游戏是否进行
- this.score = 0;
- this.buttles = 0;
- // 向数组中添加精灵信息
- this.addRole = function (role){
- this.spirits.push(role);
- };
- // 定义清空场景的方法
- this.clear = function (){
- this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
- };
- // 定义重绘地图的方法
- this.redraw = function (){
- this.clear();
- // 定义一个临时数组来保存在画布范围内的精灵
- var drawedSpirits = [];
- for (var i = 0; i < this.spirits.length; i++) {
- this.spirits[i].nextPosition();
- if (this.boundsDetection(this.spirits[i])) {
- drawedSpirits.push(this.spirits[i]);
- } else {
- if (this.spirits[i].type == 'background') {
- this.spirits[i].position.y = -this.canvas.height;
- drawedSpirits.unshift(this.spirits[i]);
- }
- if (this.spirits[i].type == 'aircraft') {
- this.spirits[i].previousPosition();
- drawedSpirits.push(this.spirits[i]);
- }
- }
- }
- this.spirits = drawedSpirits;
- // 调用碰撞检测,确定哪些精灵可以被绘制
- this.collisionDectection();
- for (i = 0; i < this.spirits.length; i++) {
- if (this.spirits[i].type == 'boom') {
- if (this.spirits[i].hp > 0) {
- this.spirits[i].draw(this.ctx);
- this.spirits[i].hp -= 0.3;
- }else {
- this.spirits.splice(i, 1);
- i--;
- }
- }else {
- this.spirits[i].draw(this.ctx);
- }
- }
- this.ctx.beginPath();
- this.ctx.font = '45px Chalkduster';
- this.ctx.fillStyle = 'rgba(0,0,0, 0.51)';
- this.ctx.fillText('score:' + this.score, 0, 35);
- this.ctx.closePath();
- // 如果游戏结束则绘制game over
- if (!this.start) {
- this.ctx.font = '80px Chalkduster';
- this.ctx.fillStyle = 'rgb(172, 34, 34)';
- this.ctx.fillText('GAME OVER', 45, 450);
- this.ctx.rect(220,520,200,60);
- this.ctx.fillStyle = 'rgba(0,0,0,0.7)';
- this.ctx.fill();
- this.ctx.font = '36px Chalkduster';
- this.ctx.fillStyle = 'white';
- this.ctx.fillText('RESTART', 230, 564);
- }
- };
- this.boundsDetection = function (role){
- switch (role.type) {
- case 'brolly':
- case 'background':
- case 'flivver':
- if (role.position.y > this.canvas.height) {
- return false;
- } else {
- return true;
- }
- break;
- case 'aircraft':
- if (role.position.x < 0 || role.position.y < 0 || role.maxPosition.x > this.canvas.width || role.maxPosition.y > this.canvas.height) {
- return false;
- } else {
- return true;
- }
- break;
- case 'bullet':
- if (role.position.y < -role.size.height) {
- return false;
- } else {
- return true;
- }
- break;
- default:
- return true;
- }
- };
- // 定义碰撞检测
- this.collisionDectection = function (){
- var bullets = []; // 场景中所有的子弹
- var enemys = []; // 场景中所有的敌机
- var brollys = []; // 降落伞的数组
- var aircraft = null; // 暂存我方战机
- var airctaftindex = 0; // 暂存我方战机在精灵数组中的下标
- for (var i = 0; i < this.spirits.length; i++) {
- switch (this.spirits[i].type) {
- case 'bullet':
- bullets.push(this.spirits[i]);
- break;
- case 'flivver':
- enemys.push(this.spirits[i]);
- break;
- case 'aircraft':
- aircraft = this.spirits[i];
- aircraftIndex = i;
- break;
- case 'brolly':
- brollys.push(this.spirits[i]);
- break;
- default:
- }
- }
- for (i = 0; i < bullets.length; i++) {
- for (var j = 0; j < enemys.length; j++) {
- if (bullets[i].position.x > enemys[j].position.x && bullets[i].position.x < enemys[j].maxPosition.x &&
- bullets[i].position.y > enemys[j].position.y && bullets[i].position.y < enemys[j].maxPosition.y) {
- var bulletsIndex = this.spirits.indexOf(bullets[i]);
- this.spirits.splice(bulletsIndex, 1);
- if(--enemys[j].hp <= 0) {
- this.score += enemys[j].score;
- var enemyIndex = this.spirits.indexOf(enemys[j]);
- this.spirits.splice(enemyIndex, 1);
- }
- // 创建子弹爆炸精灵
- var size = new Size(41, 39);
- var position = new Position(bullets[i].position.x - size.width / 2, bullets[i].position.y - size.height / 2);
- var velocity = new Velocity(0, 0);
- var boom = new Spirit(position, size, velocity, 'images/boo1.png', 'boom');
- boom.hp = 2;
- this.spirits.push(boom);
- // 子弹打到飞机
- document.querySelector('#down').play();
- break;
- }
- }
- }
- // 进行我方战机跟敌机的碰撞检测
- for (i = 0; i < enemys.length; i++) {
- var centerx = enemys[i].position.x + enemys[i].size.width / 2;
- var centery = enemys[i].position.y + enemys[i].size.height / 2;
- if (centerx > (aircraft.position.x - enemys[i].size.width / 2 + 10) && centerx < (aircraft.maxPosition.x + enemys[i].size.width / 2 - 10) &&
- centery > (aircraft.position.y - enemys[i].size.height / 2 + 10) && centery < (aircraft.maxPosition.y + enemys[i].size.height / 2 - 10)) {
- this.start = false;
- this.spirits = [this.spirits[0], this.spirits[1]];
- document.querySelector('#gameMusic').pause();
- document.querySelector('#gameOver').play();
- // document.querySelector('#gameOver').loop = 'loop';
- break;
- }
- }
- // 进行装备包的碰撞检测
- for (i = 0; i < brollys.length; i++) {
- var centerX = brollys[i].position.x + brollys[i].size.width / 2;
- var centerY = brollys[i].position.y + brollys[i].size.height / 2;
- if (centerX > (aircraft.position.x - brollys[i].size.width / 2 + 10) && centerX < (aircraft.maxPosition.x + brollys[i].size.width / 2 - 10) &&
- centerY > (aircraft.position.y - brollys[i].size.height / 2 + 10) && centerY < (aircraft.maxPosition.y + brollys[i].size.height / 2 - 10)) {
- this.spirits.splice(this.spirits.indexOf(brollys[i]),1);
- this.buttles++;
- break;
- }
- }
- };
- }
- // 构建 制造子弹的函数
- function bullet ( count, aircraft, scene, left, speed1, speed2, speed3){
- if (count % speed1 === 0) {
- var size = new Size(7, 17);
- var position = new Position(aircraft.position.x + aircraft.size.width / 2 - size.width / 2 - left, aircraft.position.y - size.height);
- var velocity = new Velocity(speed3, -speed2);
- var bullet = new Spirit(position, size, velocity, 'images/bullet.png', 'bullet');
- document.querySelector('#bullet').play();
- document.querySelector('#bullet').volume = 0.2;
- scene.addRole(bullet);
- }
- }
canvas画板基础应用的学习的更多相关文章
- QML学习笔记(二)-纯qml画图实现canvas画板-鼠标画图
作者: 狐狸家的鱼 Github: 八至 版权声明:如需转载请获取授权和联系作者 用纯qml实现canvas画板功能,用鼠标进行画图,可以画直线,画圆,画矩形,画弧线. 由于canvas画图会有延迟和 ...
- 零基础如何系统学习Java Web
零基础如何系统学习Java Web? 我来给你说一说 你要下决心,我要转行做开发,这样你才能学成. 你要会打字,我公司原来有一个程序员,打字都是两个手一指禅,身为程序员你一指禅怎么写出的代码,半个 ...
- ASP.NET基础之HttpHandler学习
ASP.NET基础之HttpHandler学习 经过前两篇[ASP.NET基础之HttpModule学习]和[ASP.NET基础之HttpContext学习]文章的学习我们对ASP.NET的基础内容有 ...
- Android中Canvas绘图基础详解(附源码下载) (转)
Android中Canvas绘图基础详解(附源码下载) 原文链接 http://blog.csdn.net/iispring/article/details/49770651 AndroidCa ...
- canvas绘画基础(一):认识canvas画布
html5提供了一个<canvas>标签,结合javascript的canvas api接口可以用来绘制图形和动画.最近工作中涉及到画图的任务,下面来了解一下canvas的基础:canva ...
- C#区块链零基础入门,学习路线图 转
C#区块链零基础入门,学习路线图 一.1分钟短视频<区块链100问>了解区块链基本概念 http://tech.sina.com.cn/zt_d/blockchain_100/ 二.C#区 ...
- (转)ASP.NET基础之HttpHandler学习
原文地址:http://www.cnblogs.com/wujy/archive/2013/08/18/3266009.html 经过前两篇[ASP.NET基础之HttpModule学习]和[ASP. ...
- (转)零基础入门深度学习(6) - 长短时记忆网络(LSTM)
无论即将到来的是大数据时代还是人工智能时代,亦或是传统行业使用人工智能在云上处理大数据的时代,作为一个有理想有追求的程序员,不懂深度学习(Deep Learning)这个超热的技术,会不会感觉马上就o ...
- 【转载】salesforce 零基础开发入门学习(六)简单的数据增删改查页面的构建
salesforce 零基础开发入门学习(六)简单的数据增删改查页面的构建 VisualForce封装了很多的标签用来进行页面设计,本篇主要讲述简单的页面增删改查.使用的内容和设计到前台页面使用的 ...
随机推荐
- js中split,splice,slice方法之间的差异。
首先我们先来林格斯双击翻译一下: split 劈开, 使分裂: splice 接合; 使结合: slice 切成薄片, 切: 我先是这么区分的:这三个方法最后一个字母是t的是字符串方法,是e的 ...
- 紫书 例题 9-4 UVa 116 ( 字典序递推顺序)
这道题在递推方式和那个数字三角形有一点相像,很容易推出来 但是这道题要求的是字典序,这里就有一个递推顺序的问题 这里用逆推,顺推会很麻烦,为什么呢? 如果顺推的话,最后一行假设有种情况是最小值,那么你 ...
- XTUOJ 1205 Range
Range Time Limit : 1000 MS Memory Limit : 65536 KB Problem Description For an array, the range funct ...
- jquery事件 【mousedown与mouseup ----keydown与keypress与keyup】focus--blur--orrer--pageX-pageY
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> ...
- Oracle-02-数据库概述
一.数据库用途 用于存放数据的软件 当中Application server重要,将数据存在表中每一个表关系就能够反映不同表之间数据的关系,比方淘宝用户注冊.商品买卖等数据存在操作系统的目录中,不便于 ...
- ios in-house 公布整个过程(startssl认证)
首先大体说一下步骤: 1.申请苹果enterprise 账号 为应用生成app id,provision profile等 详见:http://www.th7.cn/Program/IOS/20131 ...
- vue ---- 组件传值之间使用 v-model
父子组件通信,都是单项的,很多时候需要双向通信.方法如下: 1.父组件使用:msg.sync="aa" 子组件使用$emit('update:msg', 'msg改变后的值xxx ...
- POJ 2459 模拟
题意: 思路: 按照题意模拟即可 //By SiriusRen #include <cstdio> using namespace std; int c,f1,f2,d,xx,yy,vis ...
- CHARINDEX,REPLACE,LEFT+四大系统函数+模糊查询
select CHARINDEX('bob','my name is bob',1)--返回12 bob的第一个b在字符串中排第12(从1开始数) select CEILING(456.4)--45 ...
- 小程序中关于获取app实例与当前组件
1.getApp()来获取 App 实例 2.getCurrentPages()获取前页面栈