动画
1、小球弹性运动
<script>
const canvas=document.getElementById('canvas');
const [width,height]=[window.innerWidth,window.innerHeight];
canvas.width=width;
canvas.height=height;
//画笔
const ctx=canvas.getContext('2d');
//小球对象化
class Ball{
constructor(r,color='#000'){
this.color=color;
this.r=r;
this.x=0;
this.y=0;
}
draw(ctx){
ctx.save();
ctx.beginPath();
ctx.fillStyle=this.color;
ctx.arc(this.x,this.y,this.r,0,Math.PI*2);
ctx.fill();
ctx.restore();
}
}
//实例化小球
let ball=new Ball(15);
ball.y=50;
ball.x=width/2;
//记录时间 time
let time=new Date();
//重力 gravity
const gravity=0.01;
//弹力
const bounding=-0.8;
//速度/毫秒 vy
let vy=0.3;
let vx=0.3;
//动画方法
function animate(){
//时间差
let now=new Date();
let diff=now-time;
time=now;
//加速度
vy+=gravity;
//设置小球位置
ball.y+=vy*diff;
ball.x+=vx*diff;
//底部碰撞
if(ball.y+ball.r>height){
ball.y=height-ball.r;
vy*=bounding;
}
//左侧碰撞
if(ball.x-ball.r<0){
ball.x=ball.r;
vx*=bounding;
}
//右侧碰撞
if(ball.x+ball.r>width){
ball.x=width-ball.r;
vx*=bounding;
}
}
//渲染方法
!(function render(){
//设置动画
animate();
//擦除
ctx.clearRect(0,0,width,height);
//绘图
ball.draw(ctx);
//递归调用render 函数
window.requestAnimationFrame(render);
})()
</script>
补间动画
颜色渐变
<script src="./js/d3-color.js"></script>
<script src="./js/Tween.js"></script>
<script>
const [width,height]=[window.innerWidth,window.innerHeight];
const canvas=document.getElementById('canvas');
canvas.width=width;
canvas.height=height;
const ctx=canvas.getContext('2d');
//小球对象
class Ball{
constructor(r,color='#000'){
this.color=color;
this.r=r;
this.x=0;
this.y=0;
}
draw(ctx){
ctx.save();
ctx.beginPath();
ctx.fillStyle=this.color;
ctx.arc(this.x,this.y,this.r,0,Math.PI*2);
ctx.fill();
ctx.restore();
}
}
//实例化小球
const ball=new Ball(100,'green');
ball.x=width/2;
ball.y=200;
//实例化Tween 对象,为其添加目标对象
let tween = new TWEEN.Tween(ball);
//设置目标对象一段时间后的状态to({ key:val }, 时间长度)
tween.to({color:'#00acec'}, 2000);
//开始计时 start()
tween.start();
//重复 repeat(Infinity)
tween.repeat(Infinity);
//悠悠球 yoyo(true)
tween.yoyo(true);
//设置插值
//Linear, Quadratic, Cubic, Quartic, Quintic, Sinusoidal, Exponential, Circular, Elastic, Back, Bounce
tween.easing(TWEEN.Easing.Bounce.Out);
//事件监听
//onUpdate,onStart,onStop,onComplete
tween.onUpdate(function(){
//console.log(this.x)
});
//渲染方法
!(function render(){
//更新目标目标对象的状态
TWEEN.update();
//擦除
ctx.clearRect(0,0,width,height);
//绘图
ball.draw(ctx);
//递归调用render 函数
window.requestAnimationFrame(render);
})()
</script>
图形的拖拽
1、矩形的拖拽
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
const ctx=canvas.getContext('2d');
//矩形对象
class Rectangle{
constructor(width=0,height=0,color='#000'){
this.width=width;
this.height=height;
this.color=color;
this.x=0;
this.y=0;
}
draw(ctx){
const {x,y,width,height,color}=this;
ctx.save();
ctx.fillStyle=color;
ctx.fillRect(x,y,width,height);
ctx.restore();
}
}
//实例化矩形对象
const rect = new Rectangle(200,100);
rect.x=100;
rect.y=100;
//鼠标位减图形位
let subPos=null;
//图形是否被选择
let selected=false;
//点击事件
canvas.addEventListener('mousedown',mousedownFn);
//移动
canvas.addEventListener('mousemove',mousemoveFn);
//鼠标抬起
canvas.addEventListener('mouseup',mouseupFn);
function mousedownFn(event){
//鼠标位置
const mousePos=getMousePos(event);
//鼠标位减图形位
subPos={
x:mousePos.x-rect.x,
y:mousePos.y-rect.y
}
//判断鼠标是否在图形中
selected=containPoint(rect,mousePos);
console.log(selected);
}
function mousemoveFn(event){
//鼠标位置
const mousePos=getMousePos(event);
/*如果鼠标选择了图形
* 让图形跟着鼠标动
* 按需渲染
* */
if(selected){
rect.x=mousePos.x-subPos.x;
rect.y=mousePos.y-subPos.y;
render();
}
}
function mouseupFn(event){
//鼠标抬起,取消拖拽
selected=false;
}
//判断点是否在图形中
function containPoint(obj,mousePos){
//解构图形位置和尺寸
const {x,y,width,height}=obj;
//解构鼠标位置
const {x:mx,y:my}=mousePos;
//计算鼠标和图形上、下、左、右边界的关系
const l=mx>x;
const r=mx<x+width;
const t=my>y;
const b=my<y+height;
return l&&r&&t&&b;
}
//获取鼠标在canvas中的位置
function getMousePos(event){
//获取鼠标位置
const {clientX,clientY}=event;
//获取canvas 边界位置
const {top,left}=canvas.getBoundingClientRect();
//计算鼠标在canvas 中的位置
const x=clientX-left;
const y=clientY-top;
return {x,y};
}
//渲染方法
render();
function render(){
ctx.clearRect(0,0,canvas.width,canvas.height);
rect.draw(ctx);
}
</script>
2、圆形的拖拽
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
const ctx=canvas.getContext('2d');
//简单圆形
class Ball{
constructor(r=0,color='#000'){
this.r=r;
this.color=color;
this.x=0;
this.y=0;
}
draw(ctx){
const {x,y,r,color}=this;
ctx.save();
ctx.beginPath();
ctx.arc(x,y,r,0,Math.PI*2);
ctx.fillStyle=color;
ctx.fill();
ctx.restore();
}
}
const ball = new Ball(90);
ball.x=200;
ball.y=200;
render();
/*鼠标拖拽*/
//鼠标位减图形位
let subPos=null;
//图形是否被选择
let selected=false;
//点击事件
canvas.addEventListener('mousedown',mousedownFn);
//移动
canvas.addEventListener('mousemove',mousemoveFn);
//鼠标抬起
canvas.addEventListener('mouseup',mouseupFn);
function mousedownFn(event){
//鼠标位置
const mousePos=getMousePos(event);
//鼠标位减图形位
subPos={
x:mousePos.x-ball.x,
y:mousePos.y-ball.y,
};
//设置选择状态
selected=containPoint(ball);
}
function mousemoveFn(event){
const mousePos=getMousePos(event);
if(selected){
ball.x=mousePos.x-subPos.x;
ball.y=mousePos.y-subPos.y;
render();
}
}
function mouseupFn(){
selected=false;
}
//判断点是否在图形中
function containPoint({r}){
const {x,y}=subPos;
//获取鼠标到圆心的距离 len
const len=Math.sqrt(x*x+y*y);
//判断鼠标到圆心的距离是否小于r
return len<r;
}
//获取鼠标在canvas中的位置
function getMousePos(event){
//获取鼠标位置
const {clientX,clientY}=event;
//获取canvas 边界位置
const {top,left}=canvas.getBoundingClientRect();
//计算鼠标在canvas 中的位置
const x=clientX-left;
const y=clientY-top;
return {x,y};
}
function render(){
ctx.clearRect(0,0,canvas.width,canvas.height);
ball.draw(ctx);
}
</script>
3、扇形的拖拽
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
const ctx=canvas.getContext('2d');
//扇形
class Sector{
constructor(r=0,startAngle=0,endAngle=Math.PI*2,color='#000'){
this.r=r;
this.startAngle=startAngle;
this.endAngle=endAngle;
this.color=color;
this.x=0;
this.y=0;
}
draw(ctx){
const {x,y,r,startAngle,endAngle,color}=this;
ctx.save();
ctx.beginPath();
ctx.moveTo(x,y);
ctx.arc(x,y,r,startAngle,endAngle);
ctx.closePath();
ctx.fillStyle=color;
ctx.fill();
ctx.restore();
}
}
/*扇形弧度设置则:起始弧度和结束弧度都大于0*/
const sector = new Sector(200,0,Math.PI/3);
sector.x=200;
sector.y=200;
render();
/*鼠标拖拽*/
//鼠标位减图形位
let subPos=null;
//图形是否被选择
let selected=false;
//点击事件
canvas.addEventListener('mousedown',mousedownFn);
//移动
canvas.addEventListener('mousemove',mousemoveFn);
//鼠标抬起
canvas.addEventListener('mouseup',mouseupFn);
function mousedownFn(event){
//鼠标位置
const mousePos=getMousePos(event);
//鼠标位减图形位
subPos={
x:mousePos.x-sector.x,
y:mousePos.y-sector.y,
};
//设置选择状态
selected=containPoint(sector,mousePos);
}
function mousemoveFn(event){
const mousePos=getMousePos(event);
if(selected){
sector.x=mousePos.x-subPos.x;
sector.y=mousePos.y-subPos.y;
render();
}
}
function mouseupFn(event){
selected=false;
}
//判断点是否在图形中
function containPoint(obj){
const {r,startAngle,endAngle}=obj;
//获取鼠标到圆心的距离
const {x,y}=subPos;
const len=Math.sqrt(x*x+y*y);
//判断鼠标到圆心的距离是否小于半径
const b1=len<r;
//获取鼠标位减图形位的方向 dir
const dir=Math.atan2(y,x);
//判断鼠标向量的方向是否在扇形的夹角之间
const b2=dir>startAngle&&dir<endAngle;
return b1&&b2;
}
//获取鼠标位置
function getMousePos(event){
//获取鼠标位置
const {clientX,clientY}=event;
//获取canvas 边界位置
const {top,left}=canvas.getBoundingClientRect();
//计算鼠标在canvas 中的位置
const x=clientX-left;
const y=clientY-top;
return {x,y};
}
function render(){
ctx.clearRect(0,0,canvas.width,canvas.height);
sector.draw(ctx);
}
</script>
小结:1)鼠标移动距离的获取;2)判断鼠标是否在图形中;
合成
1、刮刮乐
背景图资源
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,user-scalable=no">
<title>刮刮乐</title>
<style>
body{margin: 0;overflow: hidden}
#canvas{
margin: 100px;
background-image: url("./images/ggl-back.png");
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
const ctx=canvas.getContext('2d');
/*图像尺寸,遮罩图和背景图尺寸一样*/
const [width,height]=[395,188];
canvas.width=385;
canvas.height=188;
/*建立图像源*/
const img=new Image();
img.src='./images/ggl-mask.png';
img.onload=function(){
/*绘制遮罩层*/
ctx.drawImage(img,0,0);
};
/*
* 线对象 Line
* ctx 上下文对象
* drawing 是否正在绘图
*
* 鼠标按下 moveTo(x,y)
* 记录正在绘图的状态 drawing
* 保存状态
* 设置全局合成属性globalCompositeOperation 为destination-out
* 线宽lineWidth为30
* moveTo()设置路径起点
* 鼠标移动 lineTo(x,y)
* lineTo()绘制下一个点
* stroke()描边
* 鼠标抬起 restore()
* 状态还原
* 取消正在绘图的状态
* */
class Line{
constructor(ctx){
this.ctx=ctx;
this.drawing=false;
}
moveTo(x,y){
const {ctx}=this;
this.drawing=true;
ctx.save();
ctx.globalCompositeOperation='destination-out';
ctx.lineWidth=20;
ctx.moveTo(x,y);
}
lineTo(x,y){
const {ctx}=this;
ctx.lineTo(x,y);
ctx.stroke();
}
restore(){
this.ctx.restore();
this.drawing=false;
}
}
/*实例化线对象 Line*/
const line=new Line(ctx);
/*==========鼠标事件===========*/
/*鼠标按下*/
canvas.addEventListener('mousedown',function(event){
//鼠标左键按下
if(event.buttons===1) {
//获取鼠标位置
const {x, y} = getMousePos(event);
//绘制起点
line.moveTo(x,y);
}
});
/*鼠标移动*/
canvas.addEventListener('mousemove',function(event){
//鼠标左键按下且处于绘图状态
if(event.buttons===1&&line.drawing) {
//获取鼠标位置
const {x, y} = getMousePos(event);
//绘制下一个点
line.lineTo(x,y);
}
});
/*鼠标抬起*/
canvas.addEventListener('mouseup',function(event){
//鼠标左键按下
if(event.buttons===1) {
//状态还原
line.restore();
}
});
//获取鼠标在canvas中的位置
function getMousePos(event){
//获取鼠标位置
const {clientX,clientY}=event;
//获取canvas 边界位置
const {top,left}=canvas.getBoundingClientRect();
//计算鼠标在canvas 中的位置
const x=clientX-left;
const y=clientY-top;
return {x,y};
}
</script>
</body>
</html>
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!