学习canvas(二)
绘制文字
fillText()
在指定的(x,y)位置填充指定的文本,绘制的最大宽度是可选的.
fillText(text, x, y [, maxWidth]);
-
text
使用当前的 font,textAlign, textBaseline和direction值对文本进行渲染。
-
x
文本起点的 x 轴坐标。
-
y
文本起点的 y 轴坐标。
-
maxWidth 可选
绘制的最大宽度。如果指定了值,并且经过计算字符串的值比最大宽度还要宽,字体为了适应会水平缩放(如果通过水平缩放当前字体,可以进行有效的或者合理可读的处理)或者使用小号的字体。
文本的样式
font = value
当前我们用来绘制文本的样式. 这个字符串使用和 CSS font属性相同的语法. 默认的字体是 10px sans-serif。
textAlign = value
文本对齐选项. 可选的值包括:start, end, left, right or center. 默认值是 start。
创建图像
或者我们可以用脚本创建一个新的 HTMLImageElement 对象。要实现这个方法,我们可以使用很方便的Image()构造函数。
var img = new Image(); // 创建一个<img>元素
img.src = 'myImage.png'; // 设置图片源地址
当脚本执行后,图片开始装载。
若调用 drawImage
时,图片没装载完,那什么都不会发生(在一些旧的浏览器中可能会抛出异常)。因此你应该用load事件来保证不会在加载完毕之前使用这个图片:
var img = new Image(); // 创建img元素
img.onload = function(){
// 执行drawImage语句
}
img.src = 'myImage.png'; // 设置图片源地址
如果你只用到一张图片的话,这已经够了。但一旦需要不止一张图片,那就需要更加复杂的处理方法,但图片预加载策略超出本教程的范围。
drawImage()
绘制图像
语法
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
参数
image:绘制的图片
sx(可选):需要绘制到目标上下文中的,image
的矩形(裁剪)选择框的左上角 X 轴坐标。
sy(可选):需要绘制到目标上下文中的,image
的矩形(裁剪)选择框的左上角 Y 轴坐标。
sWidth:image
的矩形(裁剪)选择框的宽度。如果不说明,整个矩形(裁剪)从坐标的sx
和sy
开始,到image
的右下角结束。
sHight:需要绘制到目标上下文中的,image
的矩形(裁剪)选择框的高度。
dx:image的左上角在目标canvas上X轴坐标
dy:image的左上角在目标canvas上Y轴坐标
dWidth(可选):image
在目标canvas上绘制的宽度。 允许对绘制的image
进行缩放。 如果不说明, 在绘制时image
宽度不会缩放。
dHeight(可选):image
在目标canvas上绘制的高度。 允许对绘制的image
进行缩放。 如果不说明, 在绘制时image
高度不会缩放。
window.requestAnimationFrame()
告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
注意:若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()
语法
window.requestAnimationFrame(callback);
参数
callback
下一次重绘之前更新动画帧所调用的函数(即上面所说的回调函数)。该回调函数会被传入DOMHighResTimeStamp参数,该参数与performance.now()的返回值相同,它表示requestAnimationFrame() 开始去执行回调函数的时刻。
返回值
一个 long
整数,请求 ID ,是回调列表中唯一的标识。是个非零值,没别的意义。你可以传这个值给 window.cancelAnimationFrame() 以取消回调函数。
转盘转动案例分析
需要用到的方法:
-
Math.ceil()向上取整
-
Math.random() 生成一个0-1的随机数
-
transform:rotate 旋转
-
window.requestAnimationFrame() 更新动画帧
案例思路:
- 当点击时间触发时调用旋转动画函数
var clickBtn= document.getElementById('button');
clickBtn.addEventListener('click',()=>{
window.requestAnimationFrame(rotate);
});
- 变量声明
// 角度初始为0
var deg = 0;
// 速度即为角度增加的幅度
var speed= 1;
// 生成一个随机的转动圈数
var RandomCircleNum = Math.ceil(Math.random() * 10);
// 随机的角度 (决定奖品 有待于后端根据奖品金额扩展)
var RandomDeg= Math.ceil(Math.random()*60);
RandomDeg = 22.5;
// 计算转动圈数
var CountCircleNum= 0;
// 判断是否转动完成
var isRotated= false;
- 声明旋转函数
- 进去先改变旋转角度
- 判断是否转到了随机生成的圈数
- 如果转到判断是否转到了随机生成的角度,没有转到的话增加角度,如果速度等于0取消动画
- 如果没有转到,增加角度,判断是否转满一圈,如果没有转满一圈调旋转函数,转满一圈就给速度一个固定的值让它匀速执行
案例完整代码
// 角度初始为0
var deg = 0;
// 速度即为角度增加的幅度
var speed= 1;
// 生成一个随机的转动圈数
var RandomCircleNum = Math.ceil(Math.random() * 10);
// 随机的角度 (决定奖品 有待于后端根据奖品金额扩展)
var RandomDeg= Math.ceil(Math.random()*60);
RandomDeg = 22.5;
// 计算转动圈数
var CountCircleNum= 0;
// 判断是否转动完成
var isRotated= false;
function rotate(){
// 改动角度
canvas.style.transform = 'rotate(' + deg + 'deg)';
// 判断是否转到了随机生成的圈数
if(CountCircleNum>=RandomCircleNum){
deg += speed;
// 如果角度还不够 奖品的角度 就继续递归转动
if (deg<RandomDeg){
window.rotateHandler= window.requestAnimationFrame(rotate);
// 速度 也就是角度变动幅度跟随着角度的变化 圆滑的变动
speed= ((360-deg) - RandomDeg)/50;
if (speed+deg>=RandomDeg){
deg = RandomDeg;
}
// 如果速度已经为0那就取消
if(speed==0){
window.cancelAnimationFrame(window.rotateHandler);
}
}
}else{
deg+= speed;
// 判断是否转满
if (deg < 360) { // Stop the animation after 2 seconds
window.requestAnimationFrame(rotate);
// 在第一圈时 转盘转动的幅度跟随角度的变动来变化(效果会更加柔和)
if (CountCircleNum < 1 ) {
speed= deg/50
}
} else{
// 如果不是第一圈了 那就给定匀速的虚拟转动 不会产生结果
speed = 7.2;
window.requestAnimationFrame(rotate)
}
// 总统筹(如果 角度足够360圈数+1 角度回归为1)
if (deg >= 360 ){
CountCircleNum++;
deg=1;
}
}
}
var clickBtn= document.getElementById('button');
clickBtn.addEventListener('click',()=>{
window.requestAnimationFrame(rotate);
});