决战canvas中国象棋设计之动画基础(连载二)

标签: 前端开发 Canvas Javascript 中国象棋 动画 | 发表时间:2011-12-19 08:30 | 作者:hfliu
出处:http://ued.ctrip.com/blog

Canvas做动画与普通JS控制的动画有所不同。本篇着重介绍其中的特殊之处,并实现中国象棋的棋子拖动及撤回动画。

普通JS动画一般只需要控制一些页面元素,改变它们的位置或透明度、色彩等属性,其余的浏览器会帮我们完成。但到了Canvas里面,所有绘制出来的图像元素,并不是各自独立的DOM节点。它们共同做为一个Canvas节点存在。而我们的动画则要求Canvas里的图像元素发生运动。

摆在面前的障碍就是,我们无法像控制DOM节点那样直接控制图像元素的位置等属性。

那么Canvas怎么做动画呢?答案只有一个:不停地重绘。你无法用style.left之类的属性控制图像元素,但你可以设定自己的变量,并利用这些变量绘制图形。这样,只要变量在变,不断重绘的结果就形成了我们所需的动画。

不要对重绘感到恐惧。重绘普遍存在于显示技术中。即使你用JS控制DOM节点进行移动,实际上浏览器也在悄悄的用重绘来实现。

让我们结合上一篇的例子,略做改进,给棋子加上鼠标事件(加在Canvas节点上,通过坐标判断来确定点击等事件是否发生在棋子上),实现棋子的拖动效果。

onmousedown与onmouseup是拖拽的开始与结束事件,我们在这两个事件里所需做的主要工作是进行拖拽状态的标记。onmousemove是拖拽的具体实现,也就是在这里进行重绘。来看下代码:

if (chess.isDragging != true)
return;
var pos = fixMousePoint(e, canvasNode);
chess.offsetRect.moveTo(pos.x - layout.cell / 2, pos.y - layout.cell / 2);
drawBoard(ctx);
chess.drawChess(ctx);

这里首先判断是否处于拖拽状态,如果不是则不做处理。对拖拽的处理也很简单,首先取出鼠标位置;然后更新棋子的offsetRect对象,使之指向当前鼠标位置;最后进行重绘,先绘棋盘再绘棋子(这里为演示方便只使用了一个棋子)。

棋子的移动

棋子的移动(截图没能截到棋子上的鼠标光标)

怎么样,是不是棋子已经能跟随鼠标移动了?是不是挺简单的?当然很简单,本系列的深度内容都在后面,这篇及前篇只是开路先锋。

对于非鼠标拖拽的运动效果,只需要将onmousemove换成setInterval就可以了,道理就是这么简单。不过,让我们把效果玩得更好一些吧。

你一定见过很多动感十足的运动效果,有没有研究过它们的规律呢?比如我们想实现拖拽结束后,让棋子潇洒地飞回原地,这个动作怎么样实现呢?细心的人可能已经发现,多数很酷的滑动效果都是用缓来实现的。缓动也就是,速度从慢到快变化。当然也可以反过来,更可以组合。我们将计划实现一个速度从慢到快再到慢的棋子返回原地的动画。

如何达到这种平滑的速度变化呢?你可以自定义规则来实现,但推荐你在脑海里搜索一下各种数学函数,这些函数真的很优美,也很简单,像我这样把数学还给老师的人也能看懂。最常用的动画函数是幂函数,常用的几种如下图所示:

常用幂函数图像

常用幂函数图像

观察一下x, y都大于零的时候,四个函数的特点。如果把x看作时间,把y看作位移,则y=x时是匀速运动,其它指数为正整数的情况下,速度都是先慢后快,并且指数越高,速度变化幅度越大。

如果我们要实现慢速启动和缓慢停止,则可以将一正一反两个函数拼接起来。有了这些基础概念,剩下的就是将这个函数映射到实际问题中了,只需要“放大”或“缩小”,使选定的图像片段调整到和我们需要的运动距离及时间相对应,就可以实现我们的目的了。

让我们在onmouseup里添加处理,实现缓动画效果:

canvasNode.onmouseup = function(e) {
	if (chess.isDragging) {
		chess.isDragging = false;
		moveChessBack();
	}
}
function moveChessBack() {
	var left = layout.padding + layout.cell * chess.pos.x–layout.cell / 2,
	top = layout.padding + layout.cell * chess.pos.y–layout.cell / 2;
	var dx = left–chess.offsetRect.left,
	dy = top–chess.offsetRect.top;
	var t = 0,
	c = 20;
	var timer = setInterval(function() {
		if (++t > c) {
			clearInterval(timer);
			chess.offsetRect.moveTo(left, top);
			return;
		}
		var ratio = 0;
		if (t <= c / 2) {
			ratio = 2 * t / c;
			ratio = 1–0.5 * Math.pow(ratio, 4);
		} else {
			ratio = 2–2 * t / c;
			ratio = 0.5 * Math.pow(ratio, 4);
		}
		chess.offsetRect.moveTo(left–dx * ratio, top–dy * ratio);
		drawBoard(ctx);
		chess.drawChess(ctx);
	},
	40);
}

看看效果吧,只可惜截图是死的,做视频太烦,随后我把代码附上来供大家参考。本篇解决了基本的动画处理问题,基于这些知识,大家可以发散思维,添枝加叶,让动画更酷些。笔者的示例中改变了正在拖动的棋子的阴影位置,以示区分。我相信大家会有更多更好的主意,欢迎分享出来。

到这里,Canvas动画的制作原理和棋子的运动处理基本解决了,Canvas技术上制作中国象棋游戏的障碍已经扫清,大道前方,你是否看到了光明?哦,不一定,在“花明”之前,总会有些“柳暗”,不知你是否感觉得到。不过没关系,无论世界是黑是白,我们心中要有一个信念,就像尤达大师说的,原力的光明面远比黑暗面强大。对错不重要,把它当做一种信仰就好。

Canvas中国象棋棋子动画演示

相关 [canvas 中国象棋 设计] 推荐:

决战canvas中国象棋设计之动画基础(连载二)

- - 携程UED
Canvas做动画与普通JS控制的动画有所不同. 本篇着重介绍其中的特殊之处,并实现中国象棋的棋子拖动及撤回动画. 普通JS动画一般只需要控制一些页面元素,改变它们的位置或透明度、色彩等属性,其余的浏览器会帮我们完成. 但到了Canvas里面,所有绘制出来的图像元素,并不是各自独立的DOM节点. 它们共同做为一个Canvas节点存在.

html5 canvas入门

- - Marshal's Blog
可以把canvas看做div,不过,它的长和宽不能通过css来定义,要使用标签属性:. 或者javascript对象属性设置:. 使用canvas,只有一种操作方式,使用javascript. 获得canvas对象的上下文对象,该对象是操作canvas的主要对象:. 使用canvas画最简单的线, 点击运行示例,结果看起来是这样:.

html5 canvas 图像处理

- - HTML5研究小组
前两天无意中看了下《pro html5 programming》,发现html5竟然也能很好的支持图像处理,在此稍稍交代一下. 与matlab处理图像类似的是,这里也是采用图像矩阵的形式. 下面就介绍一个简单的例子:. context1.drawImage(image,0,0);//绘制原始图像,(0,0)表示图像的左上角位与canvas画布的位置.

备份:html5 canvas cheat sheet

- - 膘叔
纯备份资料,HTML5的canvas资料.

HTML5 Canvas双缓存实例

- - Web前端 - ITeye博客
转自:http://www.108js.com/article/article3/30046.html?id=255. 下面是用HTML5的标签写的一个视差滚动动画的示例. 采用了制作动画或者游戏编程中常用的双缓冲技术:获取到页面中的Canvas对象之后,创建了一个与页面Canvas同样大小的Canvas对象.

使用 Fabric.js 玩转 H5 Canvas

- - V2EX - 技术
之前使用这个框架写过一个卡片 DIY 的项目,中间遇到很多问题都只能通过 google 或 github issues 才能解决,国内资料较少,所以才想写这篇文章来简单的做下总结,希望可以帮到其他人哈. 附上个人项目地址: vue-card-diy 欢迎 star~ ✨. 什么是 Fabric.js?.

HTML5 Canvas: 测试浏览器是否支持Canvas

- - CSDN博客Web前端推荐文章
本文翻译自Steve Fulton & Jeff Fulton. 在获取HTML页面上Canvas元素的引用后,我们需要测试一下该元素是否包含“上下文”(context). Canvas的上下文指的是由浏览器定义的用于绘画的平面. 简单地说,如果上下文不存在的话,Canvas也就名存实亡了. 测试浏览器是否支持Canvas有好几种方法.

使用JavaScript和Canvas开发游戏(一)

- iVane - 为之漫笔
原文作者:Matthew Casperson • 编辑:Michele McDonough. 原文链接: Game Development with JavaScript and the Canvas element. 3、通过Canvas元素实现高级图像操作. 4、通过Canvas实现视差滚动. 8、JavaScript键盘输入.

HTML5 Canvas开发框架:CasualJS Framework

- Jimmy - ITeye论坛最新讨论
CasualJS Framework是根据ActionScript3?.0的架构开发的一套适用于HTML5 Canvas的面向对象的开发框架. 虽然Canvas提供了强大的绘图功能,但满足不了高级开发的需要. 利用CasualJS的显示对象架构及渲染机制,你可以轻松的在Canvas中操控各种位图、图形、影片剪辑等显示对象.

25 超棒的 HTML5 Canvas 游戏

- 迎客松 - LinuxEden开源社区-Linux伊甸园
Canvas 元素作为HTML5标准的一部分,允许你通过脚本动态渲染点阵图像. 这是为了基于浏览器的矢量图形而设计. HTML Canvas 把一个绘图 API 展现给 JS 客户端,使得脚本能够把想绘制的东西都绘制到一块画布上. 阅读全文 | 邮件推荐 | 评论回复.