仪表盘拖拽canvas动画

<template>

<div class="canvasBox"style=" background-image: url('../../static/img/Group.png')">

<divclass="levelBox">

<div@click='primary':class="select=='primary'?'select':''"style=" background: #BC4343">专家</div>

<div@click='intermediate':class="select=='intermediate'?'select':''"style=" background: #FF8836">一般</div>

<div@click='advanced':class="select=='advanced'?'select':''"style=" background: #8F5757"></div>

<div@click='specialist':class="select=='specialist'?'select':''"style=" background: #F6687C"></div>

<div class="bingo"@click='!bingo'></div>

</div>

<canvas id="convasChart"width="800"height="800"></canvas>

</template>


<script>

let canvas, ctx1, startCanvas

export default{

name:'chart',

data() {

return{

select:"intermediate",

bingo:true,

tem: {},

target: {},

shape: {

xCoords:0,

yCoords:0

},

sliderR:40,

sliderX:400,

sliderY:45,

pathr:356,//滑动路径半径

num:-1,

x:-1.57,

progress:25,

isDown:true

}

},

computed: {},

components: {},

methods: {

intermediate() {

this.select="intermediate"

this.initCanvas()

this.progress=25

this.draw()

},

specialist() {

this.select="specialist"

this.initCanvas()

this.progress=50

this.draw()

},

advanced() {

this.select="advanced"

this.initCanvas()

this.progress=75

this.draw()

},

primary() {

this.select="primary"

this.initCanvas()

this.progress=99.5

this.draw()

},

clearCanvas() {

ctx1.clearRect(0,0,800,800);

},

drawDate(x,y,o) {//绘图

this.clearCanvas()//清空画布

this.sliderX=x;//滑块坐标x

this.sliderY=y;//滑块坐标y

// this.sliderR = r; //滑块移动路径半径

this.x=o;//橙色圆弧结束弧度值

},

redraw() {

this.num=-1;

this.x=-1.57;

this.draw()

},

getx(ev) {//获取鼠标在canvas内坐标x

returnev.clientX-canvas.getBoundingClientRect().left;

},

gety(ev) {//获取鼠标在canvas内坐标y

returnev.clientY-canvas.getBoundingClientRect().top;

},

spotchange(a) {

if(a.x<200&&a.y<200) {//二象限

this.target.x=-(200-a.x);

this.target.y=200-a.y;

}elseif(a.x>200&&a.y<200) {//一象限

this.target.x=a.x-200;

this.target.y=200-a.y;

}elseif(a.x>200&&a.y>200) {//四象限

this.target.x=a.x-200;

this.target.y=-(a.y-200)

}elseif(a.x<200&&a.y>200) {//三象限

this.target.x=-(200-a.x);

this.target.y=-(a.y-200);

}

returnthis.target;

},

respotchange(a) {

if(a.x>0&&a.y>0) {

this.target.x=400+a.x;

this.target.y=(400-a.y);

}elseif(a.x<0&&a.y>0) {

this.target.x=400+a.x;

this.target.y=400-a.y;

}elseif(a.x<0&&a.y<0) {

this.target.x=400+a.x;

this.target.y=-(a.y-400)

}elseif(a.x>0&&a.y<0) {

this.target.x=400+a.x;

this.target.y=-(a.y-400);

}

returnthis.target;

},

getmoveto(lx,ly) {

if(!this.isDown) {//是否可移动

returnfalse;

}

//存放目标坐标位置

this.tem.o=Math.atan(ly/lx);//鼠标移动点圆形角

this.tem.x=this.pathr*Math.cos(this.tem.o);

this.tem.y=this.pathr*Math.sin(this.tem.o);

if(lx<0) {//坐标点处理(正负)

this.tem.x=-this.tem.x;

this.tem.y=-this.tem.y;

}

if(lx>0) {//弧度值处理

this.tem.z=-Math.atan(this.tem.y/this.tem.x);

}else{

this.tem.z=Math.atan(this.tem.x/this.tem.y)+1.57;

if(ly>0) {

this.tem.z=Math.atan(this.tem.x/this.tem.y)+3.14+1.57;

}

}

returnthis.tem

},

check(x,y) {//限制可拖动范围

varxx=x*x;

varyy=y*y;

varrr=147*147;//最小

varrrr=200*200;//最大

if(xx+yy>rr&&xx+yy

returntrue;

}

returnfalse;

},

OnMouseDown(evt) {

varX=this.getx(evt);//获取当前鼠标位置横坐标

varY=this.gety(evt);//获取当前鼠标位置纵坐标

varminX=(this.sliderX-this.sliderR)/2;

varmaxX=(this.sliderX+this.sliderR)/2;

varminY=(this.sliderY-this.sliderR)/2;

varmaxY=(this.sliderY+this.sliderR)/2;

if(minX

this.isDown=true;

}else{

this.isDown=false;

}

},

drawEndColourCircle() {

this.clearCanvas();

ctx1.beginPath();

ctx1.lineWidth=53;

ctx1.strokeStyle='#EEEEEE';

ctx1.arc(400,400,358,-Math.PI*0.5, Math.PI*1.5,false);// 画圆

ctx1.stroke();

ctx1.closePath();

ctx1.beginPath();

ctx1.strokeStyle='#FF9A44';

ctx1.arc(400,400,358,-Math.PI*0.5, this.x,false);// 画圆

ctx1.stroke();

ctx1.closePath();

},

OnMouseMove(evt) {//

if(this.isDown) {//是否在滑块上按下鼠标

vara={};//存放当前鼠标坐标

a.x=this.getx(evt);//坐标转化

a.y=this.gety(evt);

varb=this.spotchange(a);//坐标转化

varco=this.getmoveto(b.x, b.y);//获取要移动到的坐标点

if(this.check(b.x, b.y)) {//判断移动目标点是否在可拖动范围

varco=this.getmoveto(b.x, b.y);//获取到移动的目标位置坐标()

vartar=this.respotchange(co);//坐标转化

varo=co.z;

this.drawDate(tar.x, tar.y, o);//绘图

this.drawEndColourCircle()

this.drawSlider();

}

}

},

event() {//事件绑定

canvas.addEventListener("mousedown", this.OnMouseDown.bind(this),false);

canvas.addEventListener("mousemove", this.OnMouseMove.bind(this),false);

canvas.addEventListener("mouseup", this.OnMouseUp.bind(this),false);

},

OnMouseUp() {//鼠标释放

this.isDown=false

},

drawSlider() {

ctx1.beginPath();

ctx1.arc(this.sliderX, this.sliderY, this.sliderR,0, Math.PI*2,false);// 绘制滑块

ctx1.fillStyle='#f15a4a';

ctx1.fill();

ctx1.beginPath();

ctx1.arc(this.sliderX, this.sliderY,11,0, Math.PI*2,false);// 绘制滑块内侧白色区域

ctx1.fillStyle='#ffffff';

ctx1.fill();

},

drawGreyCircle() {

ctx1.beginPath();

ctx1.lineWidth=53;

ctx1.strokeStyle='#EEEEEE';

ctx1.arc(400,400,358,-Math.PI*0.5, Math.PI*1.5,false);// 画圆

ctx1.stroke();

ctx1.closePath();

},

drawColourCircle() {

this.clearCanvas();

this.drawGreyCircle()

ctx1.beginPath();

ctx1.lineWidth=56;

ctx1.strokeStyle='#FF9A44';

startCanvas=requestAnimationFrame(()=>{

this.draw()

})

if(this.x<(0.06283*this.progress-1.57)) {

this.x+=0.06283;

this.num+=1;

ctx1.arc(400,400,358,-Math.PI*0.5, this.x,false);// 画圆

ctx1.stroke();

ctx1.closePath();

this.sliderX=400+356*Math.cos(360*this.x/6.28*3.14/180)

this.sliderY=400+356*Math.sin(360*this.x/6.28*3.14/180)

this.drawSlider()

// 写文字

ctx1.beginPath();

ctx1.font=" 60pt PingFang Regular";

ctx1.fillStyle='#F4A522';

ctx1.textAlign='center';

ctx1.textBaseline='middle';

ctx1.fillText(this.num,400,400);

ctx1.closePath();

}else{

console.log("canvs绘制完成")

cancelAnimationFrame(startCanvas);

ctx1.arc(400,400,358,-Math.PI*0.5, this.x,false);// 画圆

ctx1.stroke();

ctx1.closePath();

this.sliderX=400+356*Math.cos(360*this.x/6.28*3.14/180)

this.sliderY=400+356*Math.sin(360*this.x/6.28*3.14/180)

this.drawSlider()

// 写文字

ctx1.beginPath();

ctx1.font=" 60pt PingFang Regular";

ctx1.fillStyle='#F4A522';

ctx1.textAlign='center';

ctx1.textBaseline='middle';

ctx1.fillText(this.num,400,400);

ctx1.closePath();

return;

}

},

initCanvas() {

this.num=-1;

this.x=-1.57;

canvas=document.getElementById("convasChart");

ctx1=canvas.getContext('2d');

},

draw() {

this.clearCanvas();

// this.drawGreyCircle()

this.drawColourCircle()

// this.drawSlider();

}

},

watch: {},

beforeCreate() {},

mounted() {

this.initCanvas()

this.draw()

this.event();

},

};

.canvasBox{

.levelBox{

.select{

box-shadow:02px15px2pxrgba(105,105,105,0.50);

}

.bingo{

background-color:#fff;

background-position: center center;

background-repeat: no-repeat;

width:60px;

height:60px;

border-radius:30px;

position: absolute;

top:50%;

left:50%;

transform:translate3d(-50%,-50%,0);

}

position: absolute;

top:50%;

left:50%;

transform:translate3d(-50%,-50%,0);

width:260px;

font-size:0;

height:260px;

border-radius:130px;

overflow: hidden;

div{

text-align: center;// line-height: 100px;

color:#fff;

width:130px;

height:130px;

display: inline-block;

font-size:18px;

}

div:nth-child(1) {

line-height:130px;

}

div:nth-child(2) {

line-height:130px;

}

div:nth-child(3) {

line-height:100px;

}

div:nth-child(4) {

line-height:100px;

}

}

position: fixed;

top:50%;

left:50%;

transform:translate3d(-50%,-50%,0);// display: inline-block;

width:400px;

height:400px;

background-repeat: no-repeat;

background-size:100%100%;

}

#convasChart{

width:100%;

}

.mint-header{

background:#FF6600;

}

.mint-header-title{

font-size:1.7rem!important;

}

.mint-button-text{

font-size:1.4rem!important;

}

.mintui{

font-size:1.4rem!important;

}

</script>

<style lang="scss"scoped>

.canvasBox{

.levelBox{

.select{

box-shadow:02px15px2pxrgba(105,105,105,0.50);

}

.bingo{

background-color:#fff;

background-position: center center;

background-repeat: no-repeat;

width:60px;

height:60px;

border-radius:30px;

position: absolute;

top:50%;

left:50%;

transform:translate3d(-50%,-50%,0);

}

position: absolute;

top:50%;

left:50%;

transform:translate3d(-50%,-50%,0);

width:260px;

font-size:0;

height:260px;

border-radius:130px;

overflow: hidden;

div{

text-align: center;// line-height: 100px;

color:#fff;

width:130px;

height:130px;

display: inline-block;

font-size:18px;

}

div:nth-child(1) {

line-height:130px;

}

div:nth-child(2) {

line-height:130px;

}

div:nth-child(3) {

line-height:100px;

}

div:nth-child(4) {

line-height:100px;

}

}

position: fixed;

top:50%;

left:50%;

transform:translate3d(-50%,-50%,0);// display: inline-block;

width:400px;

height:400px;

background-repeat: no-repeat;

background-size:100%100%;

}

#convasChart{

width:100%;

}

.mint-header{

background:#FF6600;

}

.mint-header-title{

font-size:1.7rem!important;

}

.mint-button-text{

font-size:1.4rem!important;

}

.mintui{

font-size:1.4rem!important;

}

</style>

上一篇:VUE的ajax拦截器


下一篇:VUE的数据传递