窗口调整大小时,画布重绘/擦除

时间:2015-04-11 18:24:53

标签: javascript jquery performance canvas

我在窗口重新调整大小或在给定时间后重置我的画布时遇到一些问题。我想完成重置并让它变得新鲜。问题是,如果你等待几分钟(因为刷新运行)或你重新调整窗口大小,一切都开始变得混乱。我相信它是因为它将画布画在现有画布的顶部,而且它是什么样的。关于如何解决这个问题的任何想法?



// Constellations
function constellations() {
	var pr = (function () {
		var ctx = document.createElement("canvas").getContext("2d"),
		dpr = window.devicePixelRatio || 1,
		bsr = ctx.webkitBackingStorePixelRatio ||
		ctx.mozBackingStorePixelRatio ||
		ctx.msBackingStorePixelRatio ||
		ctx.oBackingStorePixelRatio ||
		ctx.backingStorePixelRatio || 1;

		return dpr / bsr;
	})();

	function t() {
		this.x = Math.random() * o.width, this.y = Math.random() * o.height, this.vx = -.5 + Math.random(), this.vy = -.5 + Math.random(), this.radius = Math.random()
	}

	function d() {
		for (a.clearRect(0, 0, o.width, o.height), i = 0; i < r.nb; i++) r.array.push(new t), dot = r.array[i], dot.create();
		dot.line(), dot.animate()
	}

	var o = document.querySelector("#constellations");
	var ratio = pr;
	o.width = $(window).width() * ratio;
	o.height = $(window).height() * ratio;
	o.style.width = $(window).width() + "px";
	o.style.height = $(window).height() + "px";
	o.style.display = "block";

	var n = "#1A2732";
	var linecolor = "#FF535A";

	a = o.getContext("2d");
	a.setTransform(ratio, 0, 0, ratio, 0, 0);
	a.clearRect(0, 0, o.width, o.height);
	a.fillStyle = n;
	a.lineWidth = .1;
	a.strokeStyle = linecolor;

	var e = {
		x: 30 * o.width / 100,
		y: 30 * o.height / 100
	},
	r = {
		nb: o.width / 10,
		distance: 80,
		d_radius: 150,
		array: []
	};
	t.prototype = {
		create: function() {
			a.beginPath(), a.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, !1), a.fill()
		},
		animate: function() {
			for (i = 0; i < r.nb; i++) {
				var t = r.array[i];
				t.y < 0 || t.y > o.height ? (t.vx = t.vx, t.vy = -t.vy) : (t.x < 0 || t.x > o.width) && (t.vx = -t.vx, t.vy = t.vy), t.x += t.vx, t.y += t.vy
			}
		},
		line: function() {
			for (i = 0; i < r.nb; i++)
			for (j = 0; j < r.nb; j++) i_dot = r.array[i], j_dot = r.array[j], i_dot.x - j_dot.x < r.distance && i_dot.y - j_dot.y < r.distance && i_dot.x - j_dot.x > -r.distance && i_dot.y - j_dot.y > -r.distance && i_dot.x - e.x < r.d_radius && i_dot.y - e.y < r.d_radius && i_dot.x - e.x > -r.d_radius && i_dot.y - e.y > -r.d_radius && (a.beginPath(), a.moveTo(i_dot.x, i_dot.y), a.lineTo(j_dot.x, j_dot.y), a.stroke(), a.closePath())
		}
	};

	var refresh = setInterval(d, 1e3 / 30);

	$(window).resize(function() {
		window.clearInterval(refresh);
		constellations();
	});
}constellations();
&#13;
<canvas id="constellations"></canvas>
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

让它看起来有效。只需重新调整分隔线的大小并观察即可。甚至可能是重置功能的情况。我不知道应该怎么做才能解决这个问题。这是一个奇怪的。 https://jsfiddle.net/v4dqgazr/

2 个答案:

答案 0 :(得分:4)

问题是,在调整浏览器大小时,$(window).resize()会在调整大小正在进行时连续触发。您可以使用David Walsh's debounce method来解决此问题。

以下是更新 demo with event logs

debounce方法看起来像这样

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

答案 1 :(得分:0)

只是想了解一下发生了什么:

正在调整窗口大小的每个瞬间,都会调用constellations()。显然,不同的浏览器处理的方式不同,Dhiraj的答案可以帮助你。

我添加了这样的代码,它向您显示正在创建并运行的许多实例:

function constellations(instanceID) {

...

function d() {
    console.log("Draw called from instance id: " + instanceID;
    ...
}


$(window).resize(function() {
    window.clearInterval(refresh);
    constellations(Math.random());
});

一旦调整大小,您就会看到很多日志调用。