报错信息:[Vue warn]: Error in mounted hook: "RangeError: Maximum call stack size exceeded"
例子是参考张鑫旭老师的博客的一个例子canvas图形绘制之星空、噪点与烟雾效果想在vue里面使用
这是组件代码index.vue
直接引入你的vue项目即可:
<template>
<canvas id="canvas"></canvas>
</template>
<script>
import Star from './star'
export default {
name: "StarrySky",
data() {
return {
stars: {},
starsIndex: 0,
density: 400,
context: null
}
},
computed: {
WIDTH() {
return window.innerWidth
},
HEIGHT() {
return window.innerHeight
}
},
mounted() {
const canvas = document.getElementById('canvas')
this.context = canvas.getContext('2d')
canvas.width = this.WIDTH
canvas.height = this.HEIGHT
this.init()
},
methods: {
init () {
this.context.clearRect(0, 0, this.WIDTH, this.HEIGHT)
this.context.fillStyle = '#000'
this.context.fillRect(0, 0, this.WIDTH, this.HEIGHT)
const length = 400
if (Object.keys(this.stars).length > length) {
this.density = 0
}
for (let i = 0; i < this.density; i++) {
if (Math.random() > 0.97) {
this.starsIndex++
this.stars[this.starsIndex] = new Star()
}
}
// 星星移动
for (let i in this.stars) {
this.stars[i].draw(this.context)
}
requestAnimationFrame(this.init())
}
}
}
</script>
star.js
:
const WIDTH = window.innerWidth
const HEIGHT = window.innerHeight
const settings = {
r: 1400, // 圆形轨迹半径
height: 260, // 围绕旋转的圆露出的圆弧的高度
alpha: 0.0, // 当前透明度
maxAlpha: 1 // 最大透明度
}
function Star () {
// 圆的轨迹方程式为:(x-a)²+(y-b)²=r²
// 因此,已知x, 则y = Math.sqrt(r² - (x-a)²) + b
// 其中,圆心是(a, b)
// 在本例子中
// 圆心坐标是(WIDTH/2, HEIGHT - 600 + r)
var a = WIDTH/2, b = HEIGHT - settings.height + settings.r;
// 因此,已知横坐标随机
this.x = Math.floor(Math.random() * WIDTH);
// 纵坐标需要在圆弧以上
// 越往上,越稀疏
this.offsety = getMinRandom() * (HEIGHT - settings.height);
this.y = b - Math.sqrt(settings.r * settings.r - (this.x - a) * (this.x - a)) - this.offsety;
this.vx = Math.random() * 0.05 + 0.05; // 水平偏移,也是移动速度
// 星星的尺寸
this.particleSize = 0.5 + (Math.random() + 0.1 / 4);
this.alpha = 0.0;
this.maxAlpha = 0.2 + (this.y/HEIGHT) * Math.random() * 0.8;
this.alphaAction = 1;
}
Star.prototype.draw = function (context) {
// 横坐标移动
this.x += this.vx;
// 根据切线方向进行偏移
// y坐标
this.y = HEIGHT - settings.height + settings.r - Math.sqrt(settings.r * settings.r - (this.x - WIDTH/2) * (this.x - WIDTH/2)) - this.offsety;
// 透明度慢慢起来
if (this.alphaAction == 1) {
if (this.alpha < this.maxAlpha ) {
this.alpha += 0.005;
} else {
this.alphaAction = -1;
}
} else {
if (this.alpha > 0.2 ) {
this.alpha -= 0.002;
} else {
this.alphaAction = 1;
}
}
if (this.x + (this.particleSize*2) >= WIDTH) {
// x到左侧
this.x = this.x - WIDTH;
}
// 绘制星星
context.beginPath();
context.fillStyle="rgba(255,255,255," + this.alpha.toString() + ")";
context.arc(this.x, this.y, this.particleSize, 0, Math.PI * 2, true);
context.closePath();
context.fill();
}
// 挑选一个随机数
function getMinRandom () {
const rand = Math.random()
// step的大小决定了星星靠近地球的聚拢程度,
// step = Math.ceil(2 / (1 - rand))就聚拢很明显
const step = Math.ceil(1 / (1 - rand))
let rands = []
for (let i = 0; i < step; i++) {
rands.push(Math.random())
}
return Math.min.apply(null, rands)
}
export default Star
这是我修改张鑫旭老师的代码,运行起来没有影响:
<!DOCTYPE html>
<html>
<head>
<title>canvas 粒子</title>
<style type="text/css">
*{
padding: 0;
margin:0;
}
</style>
</head>
<body>
<canvas id="starCanvas" width="1920" height="1000"></canvas>
<script>
(function() {
var canvas = document.querySelector("#starCanvas");
var context = canvas.getContext("2d");
var stars = {},
particleIndex = 0, // 粒子索引
settings = {
r: 1400, // 根据是设计稿确定的轨迹半径
height: 260, // 露出的圆弧的高度
density: 300, // 密度
maxLife: 100,
leftWall: 0,
rightWall: canvas.width, // 右边界限值
groundLevel: canvas.height,
alpha: 0.0, // 当前透明度
maxAlpha: 1 // 最大透明度
};
var getMinRandom = function() {
var rand = Math.random();
// step的大小决定了星星靠近地球的聚拢程度,
// step = Math.ceil(2 / (1 - rand))就聚拢很明显
var step = Math.ceil(1 / (1 - rand));
var arr = [];
for (var i=0; i<step; i++) {
arr.push(Math.random());
}
return Math.min.apply(null, arr);
};
function resizeCanvas() {
canvas.width = 1920;
canvas.height = 800;
settings.rightWall = canvas.width;
settings.height = 260 + (canvas.height - 800) / 2;
redraw();
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
function redraw() {
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "#000";
context.fillRect(0, 0, canvas.width, canvas.height);
}
function Star() {
// 圆的轨迹方程式为:(x-a)²+(y-b)²=r²
// 因此,已知x, 则y = Math.sqrt(r² - (x-a)²) + b;
// 其中,圆心是(a, b)
// 在本例子中
// 圆心坐标是(canvas.width/2, canvas.height - 600 + r);
var a = canvas.width/2, b = canvas.height - settings.height + settings.r;
// 因此,已知横坐标随机
this.x = Math.floor(Math.random() * canvas.width);
// 纵坐标需要在圆弧以上
// 越往上,越稀疏
this.offsety = getMinRandom() * (canvas.height - settings.height);
this.y = b - Math.sqrt(settings.r * settings.r - (this.x - a) * (this.x - a)) - this.offsety;
this.vx = Math.random() * 0.05 + 1.00; // 水平偏移,也是移动速度
// 星星的尺寸
this.particleSize = 0.5 + (Math.random() + 0.1 / 4);
particleIndex++;
stars[particleIndex] = this;
this.alpha = 0.0;
this.maxAlpha = 0.2 + (this.y/canvas.height) * Math.random() * 0.8;
this.alphaAction = 1;
}
Star.prototype.draw = function() {
// 横坐标移动
this.x += this.vx;
// 根据切线方向进行偏移
// y坐标
this.y = canvas.height - settings.height + settings.r - Math.sqrt(settings.r * settings.r - (this.x - canvas.width/2) * (this.x - canvas.width/2)) - this.offsety;
// 透明度慢慢起来
if (this.alphaAction == 1) {
if (this.alpha < this.maxAlpha ) {
this.alpha += 0.005;
} else {
this.alphaAction = -1;
}
} else {
if (this.alpha > 0.2 ) {
this.alpha -= 0.002;
} else {
this.alphaAction = 1;
}
}
if ( this.x + (this.particleSize*2) >= settings.rightWall ) {
// x到左侧
this.x = this.x - settings.rightWall;
}
// 绘制星星
context.beginPath();
context.fillStyle="rgba(255,255,255," + this.alpha.toString() + ")";
context.arc(this.x, this.y, this.particleSize, 0, Math.PI*2, true);
context.closePath();
context.fill();
}
function render() {
redraw();
// 星星的数目
// IE下CUP性能有限,数目小
var length = 400;
if (!history.pushState) {
// IE9
length = 200;
} else if (document.msHidden != undefined) {
// IE10+
length = 300;
}
if ( Object.keys(stars).length > length ) {
settings.density = 0;
console.log('length', length, settings.density)
}
for ( let i = 0; i < settings.density; i++ ) {
console.log('length1111')
if ( Math.random() > 0.97 ) {
new Star();
}
}
// 星星实时移动
for ( let i in stars ) {
stars[i].draw();
}
requestAnimationFrame(render);
}
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function(fn) {
setTimeout(fn, 17);
};
}
render();
})();
</script>
</body>
</html>
请求大佬指点一下!