首先用一个例子来演示这个效果:

鼠标可以拖曳和投掷小球

 

// > 16 & 0xff,
g = color >> 8 & 0xff,
b = color >> 0xff,
a = (alpha 1) ? 1 : alpha);

if(a === 1) {
return 'rgb('+r+','+g+','+b+')';
} else {
return 'rgba('+r+','+g+','+b+','+a+')';
}
};

window.utils.parseColor = function (color, toNumber) {
if (toNumber === true) {
if (typeof color === 'number') {
return (color | 0); //chop off decimal
}
if (typeof color === 'string' && color[0] === '#') {
color = color.slice(1);
}
return window.parseInt(color, 16);
} else {
if (typeof color === 'number') {
color = '#' + ('00000' + (color | 0).toString(16)).substr(-6); //pad
}
return color;
}
};

window.utils.containsPoint = function (rect, x, y) {
return !(x rect.x + rect.width ||
y rect.y + rect.height);
};

window.utils.intersects = function (rectA, rectB) {
return !(rectA.x + rectA.width 0) {
ctx.stroke();
}
ctx.restore();
};

Ball.prototype.getBounds = function () {
return {
x: this.x - this.radius,
y: this.y - this.radius,
width: this.radius * 2,
height: this.radius * 2
};
};

function Ship () {
this.x = 0;
this.y = 0;
this.width = 25;
this.height = 20;
this.rotation = 0;
this.showFlame = false;
}

Ship.prototype.draw = function (ctx) {
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.rotation);

ctx.lineWidth = 1;
ctx.strokeStyle = "#ffffff";
ctx.beginPath();
ctx.moveTo(10, 0);
ctx.lineTo(-10, 10);
ctx.lineTo(-5, 0);
ctx.lineTo(-10, -10);
//ctx.lineTo(10, 0);
ctx.closePath();
ctx.stroke();

if (this.showFlame) {
ctx.beginPath();
ctx.moveTo(-7.5, -5);
ctx.lineTo(-15, 0);
ctx.lineTo(-7.5, 5);
ctx.stroke();
}
ctx.restore();
};

(function() {
var canvas = document.createElement('canvas'),
a = document.getElementById('a');
canvas.id = 'c1';
canvas.width = 500;
canvas.height = 500;

a.appendChild(canvas);

var canvas = document.getElementById('c1'),
ctx = canvas.getContext('2d');

var ball = new Ball(30,Math.random() * 0xffffff),
mouse = utils.captureMouse(canvas),
vx = Math.random() * 5 - 2,
vy = -10,
g = 0.2,
isMouseDown = false,
oldX,oldY,
bounce = -0.8,
left = 0,
top = 0,
dx,dy,
right = canvas.width,
bottom = canvas.height;

ball.x = canvas.width / 2;
ball.y = canvas.height / 2;

canvas.addEventListener('mousedown',function() {
if(utils.containsPoint(ball.getBounds(),mouse.x,mouse.y)) {
isMouseDown = true;
vx = 0;
vy = 0;
dx = mouse.x - ball.x;
dy = mouse.y - ball.y;
oldX = ball.x;
oldY = ball.y;
canvas.addEventListener('mousemove',onMouseMove,false);
canvas.addEventListener('mouseup',onMouseUp,false);
}
},false);

function onMouseMove() {
ball.x = mouse.x - dx;
ball.y = mouse.y - dy;
}

function trackVelocity() {
vx = ball.x - oldX;
vy = ball.y - oldY;
oldX = ball.x;
oldY = ball.y;
}

function checkBound() {
vy += g;
ball.x += vx;
ball.y += vy;
if(ball.x + ball.radius > right) {
ball.x = right - ball.radius;
vx *= bounce;
} else if(ball.x - ball.radius bottom) {
ball.y = bottom - ball.radius;
vy *= bounce;
} else if(ball.y - ball.radius

拖曳功能比较简单,主要难点在如何计算投掷时的速度。

用一张图来说明:

物体在动画行进一帧的间隔内从a点被鼠标拖动到了b点,很显然在这个过程中物体的运动速度为:

vx = b.x - a.x;
vy = b.y - a.y;

只要在鼠标按下时记录小球的位置,然后在拖动时不断计算小球当前位置与旧位置的距离,就能得到小球的速度:

canvas.addEventListener('mousedown',function() {
oldX = ball.x;
oldY = ball.y; canvas.addEventListener('mousemove',onMouseMove,false);
canvas.addEventListener('mouseup',onMouseUp,false);
},false); function onMouseMove() {
ball.x = mouse.x;
ball.y = mouse.y;
} function onMouseUp() {
canvas.removeEventListener('mousemove',onMouseMove,false);
canvas.removeEventListener('mouseup',onMouseUp,false);
} function trackVelocity() {
vx = ball.x - oldX;
vy = ball.y - oldY;
oldX = ball.x;
oldY = ball.y;
} (function() {
window.requestAnimFrame(arguments.callee,canvas);
ctx.clearRect(0,0,canvas.width,canvas.height);
trackVelocity();
ball.draw(ctx);
})();

Canvas学习笔记——拖曳与投掷物体的更多相关文章

  1. canvas学习笔记、小函数整理

    http://bbs.csdn.net/topics/391493648 canvas实例分享 2016-3-16 http://bbs.csdn.net/topics/390582151 html5 ...

  2. canvas学习笔记,实用知识点总结(上)

    本博客是本人日常学习笔记,作为重要知识点的总结记录,随笔风格可能更倾向于个人的学习习惯和方式,若对您有帮助十分荣幸,若存在问题欢迎互相学习探讨,前端小白一枚在此恭候. 一.基本使用规则 1.创建画布 ...

  3. canvas学习笔记(下篇) -- canvas入门教程--保存状态/变形/旋转/缩放/矩阵变换/综合案例(星空/时钟/小球)

    [下篇] -- 建议学习时间4小时  课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...

  4. canvas学习笔记(中篇) -- canvas入门教程-- 颜色/透明度/渐变色/线宽/线条样式/虚线/文本/阴影/图片/像素处理

    [中篇] -- 建议学习时间4小时  课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...

  5. canvas学习笔记(上篇)-- canvas入门教程 -- canvas标签/方块/描边/路径/圆形/曲线

    [上篇] -- 建议学习时间4小时  课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...

  6. canvas学习笔记一

    为了研究pixi库,就顺带从头到位学习下canvas吧 判断支持力度 var webgl = (function() { try { var canvas = document.createEleme ...

  7. canvas学习笔记:canvas对图片的像素级处理--ImageData的应用

    学习了canvas的基本绘图功能后,惊喜的发现canvas对图片数据也有相当强大的处理功能,能够从像素级别操作位图,当然[lte ie8]不支持. 主要的函数有三个: ctx.createImageD ...

  8. canvas学习笔记(一)-认识canvas

    canvas是html5新增的一个标签,主要用于图形的绘制.我们可以把它理解为是浏览器给我们提供了一个画板,至于要绘制怎样的画卷,就看神笔马良你的主意了.而在canvas上绘制图形使用的笔,就是js了 ...

  9. 【canvas学习笔记一】基本认识

    <canvas>标签定义了一块画布,画布可以在网页中绘制2D和3D图象,现在先学习如何绘制2D图象,绘制3D图象属于WebGL的内容(也就是网页版的OpenGL,3D图形接口). 属性 & ...

随机推荐

  1. 【Bzoj3944】杜教筛模板(狄利克雷卷积搞杜教筛)

    题目链接 哇杜教筛超炫的 有没有见过$O(n^\frac{2}{3})$求欧拉函数前缀和的算法?没有吧?蛤蛤蛤 首先我们来看狄利克雷卷积是什么 首先我们把定义域是整数,陪域是复数的函数叫做数论函数. ...

  2. [luoguP2764] 最小路径覆盖问题(最大流 || 二分图最大匹配)

    传送门 可惜洛谷上没有special judge,不然用匈牙利也可以过的,因为匈牙利在增广上有一个顺序问题,所以没有special judge就过不了了. 好在这个题的测试数据比较特殊,如果是网络流的 ...

  3. POJ3071 Football 【概率dp】

    题目 Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, -, 2n. In eac ...

  4. 瞄一眼LongAdder(jdk11)

    java版本11.0.1,感觉写得太水了,等心情好的时候再重新编辑一下. LongAdder中的核心逻辑主要由java.util.concurrent.atomic.Striped64维护,作为Str ...

  5. el-select绑定值为对象时,报错[Vue warn]: <transition-group> children must be keyed: <ElTag>

    解决方法: <el-select v-model="syncParams.toSlaveList" multiple value-key="ip" pla ...

  6. 解决c#所有单线程单元(STA)线程都应使用泵式等待基元(如 CoWaitForMultipleHandles),并在运行时间很长的操作过程中定期发送消息。 转载

    最近做一个后来程序,启动了事务后有一段操作业务,当运行一段时间后,出现这个异常 CLR 无法从 COM 上下文 0x1b1c38 转换为 COM 上下文 0x1b1da8,这种状态已持续 60 秒.拥 ...

  7. 开始学习es6(二) let 与 const 及 块级作用域

    1.var JavaScript中,我们通常说的作用域是函数作用域,使用var声明的变量,无论是在代码的哪个地方声明的,都会提升到当前作用域的最顶部,这种行为叫做变量提升(Hoisting) cons ...

  8. 标准C程序设计七---105

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  9. 12深入理解C指针之---指针多层间接引用

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 一.指针多层引用 1.定义:指针可以用不同的间接引用层级,通常使用多重指针或字符数组来 ...

  10. The disk contains an unclean file system

    Ubuntu : Status 14: The disk contains an unclean file system By mkyong | July 23, 2014 | Viewed : 10 ...