canvas js 写的 怎么运用在 vue中

新手上路,请多包涵

<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
<style>

body {
  display: flex;
  flex-flow: column wrap;
  justify-content: center;
  align-items: center;
}

#c {
    margin: 0 auto;
    margin-top:10px;
    margin-bottom: 10px;
    margin-top: 20px;   
    position: absolute;
    left: -32px;
    top:-51px;

}
.ball{
    width:120px;
    height:120px;
    background:rgba(124,68,209,1);
    box-shadow:0px 1px 8px 0px rgba(0,0,0,0.2),0px 0px 13px 0px rgba(255,255,255,0.3);
    border-radius: 50%;
    position: relative;
}

</style>
</head>
<body>

<div class="ball">
        <canvas id="c">当前浏览器不支持canvas 请升级!</canvas>
</div>

<!-- <input type="range" name="range" min="0" max="100" step="1"> -->
</body>

<script>
canvas = document.getElementById("c");
ctx = canvas.getContext("2d");

M = Math;
Sin = M.sin;
Cos = M.cos;
Sqrt = M.sqrt;
Pow = M.pow;
PI = M.PI;
Round = M.round;

oW = canvas.width =184;
oH = canvas.height = 184;

// 线宽
lineWidth = 2

// 大半径
r = (oW / 2);
console.log("r",r)

cR = r - 8*lineWidth;
console.log("cr",cR)

ctx.beginPath();

ctx.lineWidth = lineWidth;

// 水波动画初始参数
axisLength = 2r - 16lineWidth; // Sin 图形长度
unit = axisLength / 9; // 波浪宽
range = .4 // 浪幅
nowrange = range;
xoffset = 8 * lineWidth; // x 轴偏移量
data = 55 / 100; // 数据量
sp = 0; // 周期偏移量
nowdata = 0;
waveupsp = 0.009; // 水波上涨速度

// 圆动画初始参数
arcStack = []; // 圆栈
bR = r-8*lineWidth;
soffset = -(PI/2); // 圆动画起始位置
circleLock = true; // 起始动画锁

cStartPoint = arcStack.shift(); // 圆起始点

ctx.strokeStyle = "#1c86d1";

render(); // 开始渲染

function drawSine () {
ctx.beginPath();
ctx.save();
var Stack = []; // 记录起始点和终点坐标
for (var i = xoffset; i<=xoffset + axisLength; i+=20/axisLength) {

var x = sp + (xoffset + i) / unit;
var y = Sin(x) * nowrange;

var dx = i;

var dy = 2*cR*(1-nowdata) + (r - cR) - (unit * y);

ctx.lineTo(dx, dy);
Stack.push([dx,dy])

}

// 获取初始点和结束点
var startP = Stack[0]
var endP = Stack[Stack.length - 1]

ctx.lineTo(xoffset + axisLength,oW);
ctx.lineTo(xoffset,oW);
ctx.lineTo(startP[0], startP[1])
var grd = ctx.createLinearGradient(0, 0, 200, 0);
grd.addColorStop(0, "#FAD961");
grd.addColorStop(1, "#F76B1C");
ctx.fillStyle = grd
ctx.fill()
ctx.restore();
}

function render () {
ctx.clearRect(0,0,oW,oH);

if (circleLock) {

if (arcStack.length) {
  var temp = arcStack.shift();
  ctx.lineTo(temp[0],temp[1])
  ctx.stroke();
} else {
  circleLock = false;
  ctx.stroke();
  arcStack = null;

  ctx.globalCompositeOperation = 'destination-over';
  ctx.beginPath();
  ctx.lineWidth = lineWidth;
  ctx.arc(r,r, bR, 0, 2*PI, 1);

  ctx.beginPath();  
  ctx.save();
  ctx.arc(r,r, r-16*lineWidth, 0, 2*PI, 1);
  ctx.restore()
  ctx.clip();

}

} else {

// 开始水波动画
// 控制波幅
if (data >= 0.85) {
  if (nowrange > range/4) {
    var t = range * 0.01;
    nowrange -= t;   
  }
} else if (data <= 0.1) {
  if (nowrange < range*1.5) {
    var t = range * 0.01;
    nowrange += t;   
  }
} else {
  if (nowrange <= range) {
    var t = range * 0.01;
    nowrange += t;   
  }      

  if (nowrange >= range) {
    var t = range * 0.01;
    nowrange -= t;
  }
}

if((data - nowdata) > 0) {
  nowdata += waveupsp;      
}

if((data - nowdata) < 0){
  nowdata -= waveupsp
}

sp += 0.07;
drawSine();

}
requestAnimationFrame(render)
}
</script>

阅读 2.2k
2 个回答

把操作 canvas 的 js 代码放到 Vue 的生命周期钩子函数 mounted 中即可,因为操作 canvas 需要获取 DOM 节点,而 mounted 是 Vue 的生命周期中最早能够获取到 DOM 节点的时期。

把上面的渲染函数写在 mounted 中。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题