游戏开发之旅-JavaScript绘制图形
myzbx 2024-12-25 14:07 16 浏览
本节是第四讲的第二十二小节,上一节课为大家介绍了Ajax技术,包括XmlHttpRequest对象和FetchAPI的基本用法,本节为大家继续介绍JavaScript绘制图形的方法(Canvas API),有关WebGL的实例请参见视频课程的内容。
网络图形
我们来讨论 HTML 的 多媒体和嵌入式 模块,早先的网页只有单调的文字,后来才引入了图像,起初是通过 <img> 元素的方式,后来出现了类似于 background-image 的 CSS 属性和 SVG 图像等方式。然而,这还不够好。当你能够使用 CSS 和 JavaScript 让 SVG 矢量图动起来时,位图却依然没有相应的支持。同时 SVG 动画的可用工具也少得可怜。有效地生成动画、游戏画面、3D场景和其他的需求依然没有满足,而这些在诸如 C++ 或者 Java 等低级语言中却司空见惯。当浏览器开始支持 HTML 画布元素 <canvas> 和相关的 Canvas API(由苹果公司在 2004 年前后发明,后来其他的浏览器开始跟进)时,形势开始改善。下面你会看到,canvas 提供了许多有用的工具,特别是当捆绑了由网络平台提供的一些其他的 API 时。它们用来生成 2D 动画、游戏画面和数据分析图,以及其他类型的 app。
2D画布基础
以下是绘制图形的基础代码:
<canvas class="myCanvas"></canvas>
var canvas = document.querySelector('.myCanvas');
var width = canvas.width = window.innerWidth;
var height = canvas.height = window.innerHeight;
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgb(0, 0, 0)';
ctx.fillRect(0, 0, width, height);
所有绘画操作都离不开 CanvasRenderingContext2D 对象(这里叫做 ctx)。许多操作都需要提供坐标来指示绘图的确切位置,如下图所示,画布左上角的坐标是(0, 0),横坐标(x)轴向右延伸,纵坐标(y)轴向下延伸。
简单矩形
ctx.fillStyle = 'rgb(255, 0, 0)';
ctx.fillRect(50, 50, 100, 150);
画布上将出现一个红色的矩形。其左边和顶边与画布边缘距离均为 50 像素(由前两个参数指定),宽 100 像素、高 150 像素(由后两个参数指定)。
ctx.fillStyle = 'rgba(255, 0, 255, 0.75)';
ctx.fillRect(25, 100, 175, 50);
通过指定半透明的颜色来绘制半透明的图形,比如使用 rgba()。 a 指定了“α 通道”的值,也就是颜色的透明度。值越高透明度越高,底层的内容就越清晰。
描边(stroke)和线条宽度
ctx.strokeStyle = 'rgb(255, 255, 255)';
ctx.strokeRect(25, 25, 175, 200);
ctx.lineWidth = 5;
目前我们绘制的矩形都是填充颜色的,我们也可以绘制仅包含外部框线(图形设计中称为描边)的矩形。你可以使用 strokeStyle 属性来设置描边颜色,使用 strokeRect 来绘制一个矩形的轮廓。默认的描边宽度是 1 像素,可以通过调整 lineWidth 属性的值来修改。
绘制路径
ctx.fillStyle = 'rgb(255, 0, 0)';
ctx.beginPath();
ctx.moveTo(50, 50);
// 绘制路径
ctx.fill();
可以通过绘制路径来绘制比矩形更复杂的图形。路径中至少要包含钢笔运行精确路径的代码以确定图形的形状。画布提供了许多函数用来绘制直线、圆、贝塞尔曲线等等。
一些通用的方法和属性将贯穿以下全部内容:
beginPath():在钢笔当前所在位置开始绘制一条路径。在新的画布中,钢笔起始位置为 (0, 0)。
moveTo():将钢笔移动至另一个坐标点,不记录、不留痕迹,只将钢笔“跳”至新位置。
fill():通过为当前所绘制路径的区域填充颜色来绘制一个新的填充形状。
stroke():通过为当前绘制路径的区域描边,来绘制一个只有边框的形状。
路径也可和矩形一样使用 lineWidth 和 fillStyle / strokeStyle 等功能。
等边三角形
function degToRad(degrees) {
return degrees * Math.PI / 180;
};
ctx.fillStyle = 'rgb(255, 0, 0)';
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(150, 50);
var triHeight = 50 * Math.tan(degToRad(60));
ctx.lineTo(100, 50+triHeight);
ctx.lineTo(50, 50);
ctx.fill();
首先绘制一条直线,终点坐标为 (150, 50)。此时路径沿 x 轴向右行走 100 像素。然后利用三角函数来计算等边三角形的高。这里我们要绘制的三角形是朝下的。等边三角形每个角均为 60°,为计算高的值,我们可以将三角形从正中心分割为两个直角三角形,每个直角三角形的三个角分别为 90°、60°、30°。
通过基本三角函数可得:临边长度乘以角的正切等于对边长度。于是可得三角形的高为 50 * Math.tan(degToRad(60))。由于 Math.tan() 接受数值的单位为弧度,于是我们用刚才的 degToRad() 函数将 60° 换算为弧度。有了三角形的高,我们来绘制另一条线,终点坐标为 (100, 50+triHeight)。
画圆
ctx.fillStyle = 'rgb(0, 0, 255)';
ctx.beginPath();
ctx.arc(150, 106, 50, degToRad(0), degToRad(360), false);
ctx.fill();
arc() 函数有六个参数。前两个指定圆心的位置坐标,第三个是圆的半径,第四、五个是绘制弧的起、止角度(给定 0° 和 360° 便能绘制一个完整的圆),第六个是绘制方向(false 是顺时针,true 是逆时针)。
ctx.fillStyle = 'yellow';
ctx.beginPath();
ctx.arc(200, 106, 50, degToRad(-45), degToRad(45), true);
ctx.lineTo(200, 106);
ctx.fill();
将 arc() 的最后一个参数设置为 true,意味着弧将逆时针绘制,也就意味着即使起、止角度分别设置为 -45°、45°,我们还是得到了区域外的一条 270° 的弧。
文本
ctx.strokeStyle = 'white';
ctx.lineWidth = 1;
ctx.font = '36px arial';
ctx.strokeText('Canvas text', 50, 50);
ctx.fillStyle = 'red';
ctx.font = '48px georgia';
ctx.fillText('Canvas text', 50, 150);
fillText() :绘制有填充色的文本。
strokeText():绘制文本外边框(描边)。
这两个函数有三个基本的参数:需要绘制的文字、文本框(顾名思义,围绕着需要绘制文字的方框)左上顶点的X、Y坐标。
还有一系列帮助控制文本渲染的属性:比如用于指定字体族、字号的 font,它的值和语法与 CSS 的 font 属性一致。
在画布上绘制图片
var image = new Image();
image.src = 'flower.png';
ctx.drawImage(image, 20, 20, 185, 175, 50, 50, 185, 175);
第一个参数为图片引用。参数 2、3 表示裁切部分左上顶点的坐标,参考原点为原图片本身左上角的坐标。原图片在该坐标左、上的部分均不会绘制出来。参数 4、5 表示裁切部分的长、宽。参数 6、7 表示裁切部分左上顶点在画布中的位置坐标,参考原点为画布左上顶点。参数 8、9 表示裁切部分在画布中绘制的长、宽。
创建一个循环
ctx.translate(width/2, height/2);
function degToRad(degrees) {
return degrees * Math.PI / 180;
};
var length = 250;
var moveOffset = 20;
for(var i = 0; i < length; i++) {
ctx.fillStyle = 'rgba(' + (255-length) + ', 0, ' + (255-length) + ', 0.9)';
ctx.beginPath();
ctx.moveTo(moveOffset, moveOffset);
ctx.lineTo(moveOffset+length, moveOffset);
var triHeight = length/2 * Math.tan(degToRad(60));
ctx.lineTo(moveOffset+(length/2), moveOffset+triHeight);
ctx.lineTo(moveOffset, moveOffset);
ctx.fill();
length--;
moveOffset += 0.7;
ctx.rotate(degToRad(5));
}
translate(),可用于移动画布的原点,将 canvas 按原始 x点的水平方向、原始的 y点垂直方向进行平移变换。
在每次迭代中:设置 fillStyle 为略透明的紫色渐变色。渐变由每次迭代时 length 值的改变实现。随着循环的运行, length 值逐渐变小,从而使连续的三角形颜色逐渐变亮。
开始路径。
将钢笔移动至坐标 (moveOffset, moveOffset);该变量定义了每次要绘制新三角形时需要移动的距离。
画一条直线,终点坐标为 (moveOffset+length, moveOffset)。即一条长度为 length 与 X 轴平行的线。
计算三角形的高,方法同上。
向三角形底部顶点方向绘制一条直线,然后向三角形的起始点绘制一条直线。
调用 fill() 为三角形填充颜色。
更新次序变量,准备绘制下一个三角形。length 的值减一,使三角形每次迭代都变小一些;小幅增加 moveOffset 的值,使得下一个三角形略微错位;用一个新函数 rotate() 来旋转整块画布,在绘制下个三角形前画布旋转 5°。
以上内容部分摘自视频课程04网页游戏编程JavaScript-22绘制图形,更多示例请参见网站示例。跟着张员外讲编程,学习更轻松,不花钱还能学习真本领。
相关推荐
- 炫酷的计时器效果Canvas绘图与动画
-
-----------------------------------------华丽的分割线-----------------------------------------------------...
- 康托尔集合的绘制及其Python绘制(康托尔集合论的概括原则是什么)
-
康托尔三分集(Cantorternaryset)是数学中一个著名的分形例子,由德国数学家格奥尔格·康托尔在1883年引入。它通过不断去掉线段的中间三分之一部分,重复这个过程得到的一个分形集合。康托...
- 一文带你搞懂JS实现压缩图片(js 压缩图片)
-
作者:wuwhs转发链接:https://segmentfault.com/a/1190000023486410前言公司的移动端业务需要在用户上传图片是由前端压缩图片大小,再上传到服务器,这样可以减...
- 数据可视化—Echarts图表应用(数据可视化图表类型)
-
ECharts是一款由百度前端技术部开发的,基于Javascript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。使用JavaScript实现开源的可视化库,可以流畅的...
- ThreeJS中三维世界坐标转换成二维屏幕坐标
-
Threejs全称是“Javascript3Dlibrary”。WebGL则是openGL在浏览器上的一个实现。Threejs对WebGL进行了封装,让前端开发人员在不需要掌握很多数学知识和绘图知...
- 鸿蒙开源第三方件组件——加载动画库
-
前言基于安卓平台的加载动画库AVLoadingIndicatorView(https://github.com/81813780/AVLoadingIndicatorView),实现了鸿蒙化迁移和重构...
- canvas实现下雪背景图(canvas绘制背景图)
-
canvas下雪背景html+css+js实现:1.定义标签:<h1>北极光之夜。</h1><divclass="bg"></...
- 用canvas画简单的“我的世界”人物头像
-
前言:花了4天半终于看完了《HeadFirstHTML5》,这本书的学习给我最大的感受就是,自己知识的浅薄,还有非常多非常棒的技术在等着我呢。[熊本表情]扶朕起来,朕还能学!H5新增标签里面最喜欢...
- Manim-基础图形之点(什么叫图形基点)
-
制作数学演示视频时需要用到各类的集合图形,manim中内置了一些列的图形,本篇就从最简单的点讲起。点作为manim中最简单图形,也是其他所有图形的基,所有图形的绘制都是靠点来定位。manim中的点主...
- 一起学 WebGL:坐标系(坐标系格式)
-
大家好,我是前端西瓜哥,今天我们来学习WebGL。WebGL的世界坐标系是三维的。默认使用笛卡尔坐标系的右手坐标系,满足右手定则,即x轴向右,y轴向上,z轴向着观察者,原点位于画布中心。然...
- 漫画 欣赏 - 聖鬥士星矢 THE.LOST.CANVAS 冥王神話 24
-
《圣斗士星矢THELOSTCANVAS冥王神话》改编自车田正美原作的漫画《圣斗士星矢》,由车田正美原作、手代木史织作画。其外传《圣斗士星矢THELOSTCANVAS冥王神话外传》则在《...
- 漫画 欣赏 - 聖鬥士星矢 THE.LOST.CANVAS 冥王神話 25 - 完结篇
-
《圣斗士星矢THELOSTCANVAS冥王神话》改编自车田正美原作的漫画《圣斗士星矢》,由车田正美原作、手代木史织作画。其外传《圣斗士星矢THELOSTCANVAS冥王神话外传》则在《...
- Eric Fischl 名画录(eric tucker画家)
-
艾瑞克费舍尔(EricFischl,1948——),是美国新表现主义画家,当代国际画坛一位十分活跃的人物,在国际上享有很高的知名度。作为20世纪美国第6次经济衰退时期本土第一个伟大画家艾瑞克·费舍尔...
- canvas绘画板的实现(canvas画布)
-
新项目有一个需求:客户需要在订单确认的时候签名。第一反应就是用html的canvas实现,同事一起商量了下,canvas有三个制约:canvas必须要用鼠标,签名会很难看;手机端webapp怎么实现...
- Python程序开发之简单小程序实例(9)利用Canvas绘制图形和文字
-
Python程序开发之简单小程序实例(9)利用Canvas绘制图形和文字一、项目功能利用Tkinter组件中的Canvas绘制图形和文字。二、项目分析要在窗体中绘制图形和文字,需先导入Tkinter组...
- 一周热门
- 最近发表
- 标签列表
-
- HTML 简介 (30)
- HTML 响应式设计 (31)
- HTML URL 编码 (32)
- HTML Web 服务器 (31)
- HTML 表单属性 (32)
- HTML 音频 (31)
- HTML5 支持 (33)
- HTML API (36)
- HTML 总结 (32)
- HTML 全局属性 (32)
- HTML 事件 (31)
- HTML 画布 (32)
- HTTP 方法 (30)
- 键盘快捷键 (30)
- CSS 语法 (35)
- CSS 选择器 (30)
- CSS 轮廓 (30)
- CSS 轮廓宽度 (31)
- CSS 谷歌字体 (33)
- CSS 链接 (31)
- CSS 中级教程 (30)
- CSS 定位 (31)
- CSS 图片库 (32)
- CSS 图像精灵 (31)
- SVG 文本 (32)