《HTML5 Canvas核心技术——图形、动画与游戏开发》第三章要点汇总

笔记点

  • 使用context.measure("W").width可以获取当前context下W的绘制在canvas上的宽度
  • 通过指定fillText、strokeText中的最后一个参数就可以实现插入canvas的字段指定宽度
  • 使用context.createLinearGradient来实现绘制文本的颜色渐变
  • 使用context.createPattern来实现绘制文本用image来填充在线演示
  • 对context.font的设置是需要按照如下顺序的
1、font-style(normal/italic/oblique)(实测中Firefox对此属性貌似不支持)
2、font-variant(normal/small-caps)
3、font-weight(normal/bold/bolder/lighter/100/200...)字符的笔画粗细
4、font-size(xx-small/x-small/medium/large/x-large/xx-large)字型的大小
5、line-height:(书中)浏览器会将该属性强制设定为其默认值,如果你设置了该值,浏览器会忽略你所制定的值(那为什么还要指定)
6、font-family
  • 使用textAlign来实现文本的左右对齐,使用textBaseline来实现文本的上下对齐

在canvas中实现对文本的输入

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			#canvas {
				border: thin solid red;
			}
		</style>
	</head>

	<body>
		<div id="controls">
			<select name="fontSelect" id="fontSelect">
				<option value="幼圆">幼圆</option>
				<option value="宋体">宋体</option>
				<option value="黑体">黑体</option>
			</select>
			<select name="sizeSelect" id="sizeSelect">
				<option value="24">24</option>
				<option value="48">48</option>
				<option value="96">96</option>
				<option value="192">192</option>
			</select>
			<select name="strokeStyleSelect" id="strokeStyleSelect">
				<option value="lightred">lightred</option>
				<option value="lightgreen">lightgreen</option>
				<option value="lightblue">lightblue</option>
				<option value="lightgray">lightgray</option>
			</select>
			<select name="fillStyleSelect" id="fillStyleSelect">
				<option value="lightred">lightred</option>
				<option value="lightgreen">lightgreen</option>
				<option value="lightblue">lightblue</option>
				<option value="lightgray">lightgray</option>
			</select>
		</div>
		<canvas id="canvas" width="800" height="600"></canvas>
	</body>
	<script type="text/javascript">
		/* 这是书中代码自带的一个TextCursor对象的代码
		 * Copyright (C) 2012 David Geary. This code is from the book
		 * Core HTML5 Canvas, published by Prentice-Hall in 2012.
		 *
		 * License:
		 *
		 * Permission is hereby granted, free of charge, to any person
		 * obtaining a copy of this software and associated documentation files
		 * (the "Software"), to deal in the Software without restriction,
		 * including without limitation the rights to use, copy, modify, merge,
		 * publish, distribute, sublicense, and/or sell copies of the Software,
		 * and to permit persons to whom the Software is furnished to do so,
		 * subject to the following conditions:
		 *
		 * The above copyright notice and this permission notice shall be
		 * included in all copies or substantial portions of the Software.
		 *
		 * The Software may not be used to create training material of any sort,
		 * including courses, books, instructional videos, presentations, etc.
		 * without the express written consent of David Geary.
		 *
		 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
		 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
		 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
		 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
		 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
		 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
		 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
		 * OTHER DEALINGS IN THE SOFTWARE.
		 */
		 // Cursor.........................................................
		TextCursor = function(fillStyle, width) {
			this.fillStyle = fillStyle || 'rgba(0, 0, 0, 0.7)';
			this.width = width || 2;
			this.left = 0;
			this.top = 0;
		};
		TextCursor.prototype = {
			getHeight: function(context) {
				var h = context.measureText('M').width;
				return h + h / 6;
			},
			createPath: function(context) {
				context.beginPath();
				context.rect(this.left, this.top,
					this.width, this.getHeight(context));
			},
			draw: function(context, left, bottom) {
				context.save();
				this.left = left;
				this.top = bottom - this.getHeight(context);
				this.createPath(context);
				context.fillStyle = this.fillStyle;
				context.fill();
				context.restore();
			},
			erase: function(context, imageData) {
				context.putImageData(imageData, 0, 0,
					this.left, this.top,
					this.width, this.getHeight(context));
			}
		};
		 // Text lines.....................................................
		TextLine = function(x, y) {
			this.text = '';
			this.left = x;
			this.bottom = y;
			this.caret = 0;
		};
		TextLine.prototype = {
			insert: function(text) {
				this.text = this.text.substr(0, this.caret) + text +
					this.text.substr(this.caret);
				this.caret += text.length;
			},
			removeCharacterBeforeCaret: function() {
				if (this.caret === 0)
					return;
				//此处this.caret-1意思就是把最后一个字符给去掉
				this.text = this.text.substring(0, this.caret - 1) +
					this.text.substring(this.caret);
				this.caret--;
			},
			getWidth: function(context) {
				return context.measureText(this.text).width;
			},
			getHeight: function(context) {
				var h = context.measureText('W').width;
				return h + h / 6;
			},
			draw: function(context) {
				context.save();
				context.textAlign = 'start';
				context.textBaseline = 'bottom';
				context.strokeText(this.text, this.left, this.bottom);
				context.fillText(this.text, this.left, this.bottom);
				context.restore();
			},
			erase: function(context, imageData) {
				context.putImageData(imageData, 0, 0);
			}
		};
	</script>
	<script type="text/javascript">
		var canvas = document.getElementById("canvas");
		var context = canvas.getContext("2d");
		var fontSelect = document.getElementById("fontSelect");
		var sizeSelect = document.getElementById("sizeSelect");
		var strokeStyleSelect = document.getElementById("strokeStyleSelect");
		var fillStyleSelect = document.getElementById("fillStyleSelect");
		var cursor = new TextCursor();
		var line;
		var blinkingInterval;
		var BLINK_TIME = 1000;
		var BLINK_OFF = 300;

		function drawBackground() {
			var STEP_Y = 12,
				TOP_MARGIN = STEP_Y * 4,
				LEFT_MARGIN = 35,
				i = context.canvas.height;
			context.save();
			context.strokeStyle = 'lightgray';
			context.lineWidth = 0.5;
			while (i > TOP_MARGIN) { // Draw horizontal lines from bottom up
				context.beginPath();
				context.moveTo(0, i);
				context.lineTo(context.canvas.width, i);
				context.stroke();
				i -= STEP_Y;
			}
			// Draw vertical line
			context.strokeStyle = 'rgba(100,0,0,0.3)';
			context.lineWidth = 1;
			context.beginPath();
			context.moveTo(LEFT_MARGIN, 0);
			context.lineTo(LEFT_MARGIN, context.canvas.height);
			context.stroke();
			context.restore();
		}

		function windowToCanvas(x, y) {
			var bbox = canvas.getBoundingClientRect();
			return {
				x: x - bbox.left * (canvas.width / bbox.width),
				y: y - bbox.top * (canvas.height / bbox.height)
			};
		}

		function saveDrawingSurface() {
			drawingSurfaceImageData = context.getImageData(0, 0, canvas.width, canvas.height);
		}

		function setFont() {
			//易错点:px左边有一个空格键,在font中设置的时候是在字号和字体之间有一个空格键的
			context.font = sizeSelect.value + "px " + fontSelect.value;
		}

		function blinkCursor(x, y) {
			clearInterval(blinkingInterval);
			blinkingInterval = setInterval(function(e) {
				cursor.erase(context, drawingSurfaceImageData);
				setTimeout(function(e) {
					//当光标需要闪动的时候触发
					//我们在输入的状态下是不会触发这个if中的内容的
					//我还不懂为什么在输入的状态下不会触发if中的内容
					//这个if中的条件到底是用来做什么的-->应该是判定是否要闪动的,但是为什么是这样写呢?
					if (cursor.left == x && cursor.top + cursor.getHeight(context) == y) {
						cursor.draw(context, x, y);
					}
				}, 300);
			}, 1000);
		}

		function moveCursor(x, y) {
			cursor.erase(context, drawingSurfaceImageData);
			saveDrawingSurface();
			context.putImageData(drawingSurfaceImageData, 0, 0);
			cursor.draw(context, x, y);
			blinkCursor(x, y);
		}
		canvas.onmousedown = function(e) {
			var loc = windowToCanvas(e.clientX, e.clientY);
			var fontHeight = context.measureText("W").width;
			fontHeight += fontHeight / 6;
			line = new TextLine(loc.x, loc.y);
			moveCursor(loc.x, loc.y);
		};
		fillStyleSelect.onchange = function(e) {
			//此处为什么还要对cursor的style进行设置
			//因为光标也要跟着变颜色的,你选了lightblue,那么当前的光标的颜色就是lightblue
			cursor.fillStyle = fillStyleSelect.value;
			context.fillStyle = fillStyleSelect.value;
		}
		strokeStyleSelect.onchange = function(e) {
				cursor.strokeStyleSelect = strokeStyleSelect.value;
				context.strokeStyle = strokeStyleSelect.value;
			}
			//按下任意键触发
		document.onkeydown = function(e) {
			//8是BackSpace,13是Enter 
			//这里的作用何在?~本来他也会触发默认的情况的嘛~
			if (e.keyCode === 8 || e.keyCode === 13) {
				e.preventDefault();
			}
			if (e.keyCode === 8) {
				context.save();
				line.erase(context, drawingSurfaceImageData);
				//删去最后一个字符
				line.removeCharacterBeforeCaret();
				//光标移动
				moveCursor(line.left + line.getWidth(context), line.bottom);
				line.draw(context);
				context.restore();
			}
		};
		 //按下字母数字键是触发
		document.onkeypress = function(e) {
			var key = String.fromCharCode(e.which);
			//e.ctrlKey是判断Ctrl键是否被按下了
			//e.metaKay是判断meta键是否被按下,这个键现代的键盘上已经很少了---by2015年
			if (e.keyCode !== 8 && !e.ctrlKey && !e.metaKey) {
				e.preventDefault();
				context.save();
				line.erase(context, drawingSurfaceImageData);
				line.insert(key);
				moveCursor(line.left + line.getWidth(context), line.bottom);
				context.shadowColor = "rgba(0, 0, 0, 0.5)";
				context.shadowOffsetX = 1;
				context.shadowOffsetY = 1;
				context.shadowBlur = 2;
				line.draw(context);
				context.restore();
			}
		};
		fontSelect.onchange = setFont;
		sizeSelect.onchange = setFont;
		cursor.fillStyle = fillStyleSelect.value;
		cursor.strokeStyle = strokeStyleSelect.value;
		context.fillStyle = fillStyleSelect.value;
		context.strokeStyle = strokeStyleSelect.value;
		context.lineWidth = 2.0;
		setFont();
		drawBackground();
		saveDrawingSurface();
	</script>
</html>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
One of HTML5,s most exciting features, Canvas provides a powerful 2D graphics API that lets you implement everything from word processors to video games. In Core HTML5 Canvas, best-selling author David Geary presents a code-fueled, no-nonsense deep dive into that API, covering everything you need to know to implement rich and consistent web applications that run on a wide variety of operating systems and devices. Succinctly and clearly written, this book examines dozens of real-world uses of the Canvas API, such as interactively drawing and manipulating shapes, saving and restoring the drawing surface to temporarily draw shapes and text, and implementing text controls. You,ll see how to keep your applications responsive with web workers when you filter images, how to implement smooth animations, and how to create layered, 3D scrolling backgrounds with parallax. In addition, you,ll see how to implement video games with extensive coverage of sprites, physics, collision detection, and the implementation of a game engine and an industrial-strength pinball game. The book concludes by showing you how to implement Canvas-based controls that you can use in any HTML5 application and how to use Canvas on mobile devices, including iOS5. This authoritative Canvas reference covers * The canvas element-using it with other HTML elements, handling events, printing a canvas, and using offscreen canvases* Shapes-drawing, dragging, erasing, and editing lines, arcs, circles, curves, and polygons; using shadows, gradients, and patterns* Text-drawing, positioning, setting font properties; building text controls* Images-drawing, scaling, clipping, processing, and animating* Animations-creating smooth, efficient, and portable animations* Sprites-implementing animated objects that have painters and behaviors* Physics-modeling physical systems (falling bodies, pendulums, and projectiles), and implementing tweening for nonlinear motion and animation* Collision detection-advanced techniques, clearly explained* Game development-all aspects of game development, such as time-based motion and high score support, implemented in a game engine* Custom controls-infrastructure for implementing custom controls; implementing progress bars, sliders, and an image panner* Mobile applications-fitting Canvas apps on a mobile screen, using media queries, handling touch events, and specifying iOS5 artifacts, such as app icons Throughout the book, Geary discusses high-quality, reusable code to help professional developers learn everything they really need to know, with no unnecessary verbiage. All of the book,s code and live demonstrations of key techniques are available at corehtml5canvas.com.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值