What's the memory leak in the following script?
function postars(canvas) {
var _this = this,
ctx = canvas.getContext('2d');
_this.config = {
star: {
color: '#ffffff'
},
line: {
color: '#ffffff',
width: 0.1
},
position: {
x: canvas.width * 0.5,
y: canvas.height * 0.5
},
velocity: 0.1,
length: 100,
distance: 120,
radius: 150,
stars: []
};
function Star() {
this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height;
this.vx = (_this.config.velocity - (Math.random() * 0.5));
this.vy = (_this.config.velocity - (Math.random() * 0.5));
this.radius = Math.random();
}
Star.prototype = {
create: function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
ctx.fill();
},
animate: function() {
var i;
for (i = 0; i < _this.config.length; i++) {
var star = _this.config.stars[i];
if (star.y < 0 || star.y > canvas.height) {
star.vx = star.vx;
star.vy = -star.vy;
} else if (star.x < 0 || star.x > canvas.width) {
star.vx = -star.vx;
star.vy = star.vy;
}
star.x += star.vx;
star.y += star.vy;
}
},
line: function() {
var length = _this.config.length,
iStar, jStar, i, j;
for (i = 0; i < length; i++) {
for (j = 0; j < length; j++) {
iStar = _this.config.stars[i];
jStar = _this.config.stars[j];
if ((iStar.x - jStar.x) < _this.config.distance && (iStar.y - jStar.y) < _this.config.distance && (iStar.x - jStar.x) > -_this.config.distance && (iStar.y - jStar.y) > -_this.config.distance) {
if ((iStar.x - _this.config.position.x) < _this.config.radius && (iStar.y - _this.config.position.y) < _this.config.radius && (iStar.x - _this.config.position.x) > -_this.config.radius && (iStar.y - _this.config.position.y) > -_this.config.radius) {
ctx.beginPath();
ctx.moveTo(iStar.x, iStar.y);
ctx.lineTo(jStar.x, jStar.y);
ctx.stroke();
ctx.closePath();
}
}
}
}
}
};
_this.createStars = function() {
var length = _this.config.length,
star, i;
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (i = 0; i < length; i++) {
_this.config.stars.push(new Star());
star = _this.config.stars[i];
star.create();
}
star.line();
star.animate();
};
_this.setCanvas = function() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
};
_this.setContext = function() {
ctx.fillStyle = _this.config.star.color;
ctx.strokeStyle = _this.config.line.color;
ctx.lineWidth = _this.config.line.width;
};
_this.loop = function(callback) {
callback();
reqAnimFrame(function() {
_this.loop(function() {
callback();
});
});
};
_this.bind = function() {
$(window).on('mousemove', function(e) {
_this.config.position.x = e.pageX;
_this.config.position.y = e.pageY;
});
};
_this.init = function() {
_this.setCanvas();
_this.setContext();
_this.loop(function() {
_this.createStars();
});
_this.bind();
};
return _this;
}
var reqAnimFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
window.setTimeout(callback, 1000 / 60);
};
It's working for a few hours and then Chrome crashes (displays an error page saying something went wrong) or outputs "stack overflow" to console.
The answer is not to use new Star() in a function's parameter, instead of that do:
var newStar = new Star()
_this.config.stars.push(newStar)
newStar = null
And to modify the code not to create new stars continously.
Related
I'm trying to resolve circle to circle collisions. The problem is, the balls never settle to the bottom -- they continue to jiggle around. What can I do to make the balls settle to the bottom at the end of their cycle (without jiggling)?
CodePen: https://codepen.io/KriegersVan/pen/gOpXzwE?editors=0010
var _bouncingBalls = (function() {
document.getElementById("canvas").width = window.innerWidth;
document.getElementById("canvas").height = window.innerHeight;
function _randomNumBetween(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function _negativeOrPositiveOne() {
return Math.random() < 0.50 ? -1 : 1;
}
function _random10Chars() {
return Math.random().toString(36).substr(2, 10);
}
var _balls = {
numOf: 10,
colors: ["#6a00ff", "#9500ff", "#d000ff", "#ff00ff", "#00f2ff", "#f59b42", "#e9f542"],
particles: [],
ctx: document.getElementById("canvas").getContext("2d"),
lastFrameTime: 0,
startTime: 0,
inProgress: false,
init: function(x, y) {
for (var i = 0; i < this.numOf; i++) {
this.particles.push({
x: x+(i*(window.innerWidth * 0.02)), //So they don't overlap at the beginning
y: y,
vy: Math.random() * _negativeOrPositiveOne(),
vx: 2 * Math.random() * _negativeOrPositiveOne(),
color: this.colors[_randomNumBetween(0, this.colors.length - 1)],
radius: window.innerWidth * 0.008,
gravity: 0.70,
damping: 0.50,
id: _random10Chars() + _random10Chars()
});
}
this.startTime = window.performance.now();
if (!this.inProgress) {
this.inProgress = true;
window.requestAnimationFrame(this.render);
}
},
isBallCollision: function(particle) {
//https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection
for (var j = 0; j < _balls.particles.length; j++) {
var comparisonParticle = _balls.particles[j];
var dx = particle.x - comparisonParticle.x;
var dy = particle.y - comparisonParticle.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (particle.id === comparisonParticle.id) {
continue;
}
var minDist = comparisonParticle.radius + particle.radius;
if (distance < minDist) {
//https://www.youtube.com/watch?v=nlwtgvZCz0k
var distance_x = dx;
var distance_y = dy;
var radii_sum = particle.radius+comparisonParticle.radius;
var length = Math.sqrt(distance_x * distance_x + distance_y * distance_y) || 1;
var unit_x = distance_x/length;
var unit_y = distance_y/length;
particle.x = comparisonParticle.x+(radii_sum+1)*unit_x;
particle.y = comparisonParticle.y+(radii_sum+1)*unit_y;
return comparisonParticle;
}
}
return null;
},
isBottomHit: function(obj, comparisonObj){
return obj.y+obj.radius > comparisonObj.y-comparisonObj.radius &&
obj.y+obj.radius < comparisonObj.y+comparisonObj.radius;
},
isTopHit: function(obj, comparisonObj){
return obj.y-obj.radius < comparisonObj.y+comparisonObj.radius &&
obj.y-obj.radius > comparisonObj.y-comparisonObj.radius;
},
isLeftHit: function(obj, comparisonObj){
return obj.x-obj.radius < comparisonObj.x+comparisonObj.radius &&
obj.x-obj.radius > comparisonObj.x-comparisonObj.radius;
},
isRightHit: function(obj, comparisonObj){
return obj.x+obj.radius > comparisonObj.x-comparisonObj.radius &&
obj.x+obj.radius < comparisonObj.x+comparisonObj.radius;
},
bottomReached: function(obj) {
return (obj.y + obj.radius) >= window.innerHeight;
},
topReached: function(obj) {
return (obj.y - obj.radius) <= 0;
},
leftSideReached: function(obj) {
return (obj.x - obj.radius) <= 0;
},
rightSideReached: function(obj) {
return (obj.x + obj.radius) >= window.innerWidth;
},
draw: function(deltaNum, timestamp) {
var r = _balls;
var ctx = r.ctx;
var elapsed = timestamp - r.startTime;
for (var i = 0; i < r.particles.length; i++) {
var obj = r.particles[i];
ctx.beginPath();
ctx.fillStyle = obj.color;
ctx.moveTo(
obj.x,
obj.y
);
ctx.arc(
obj.x,
obj.y,
obj.radius,
0,
2 * Math.PI,
false
);
ctx.fill();
ctx.closePath();
obj.y += (obj.vy * deltaNum);
obj.vy += (obj.gravity * deltaNum);
obj.x += (obj.vx * deltaNum);
var otherBall = r.isBallCollision(obj);
if (otherBall) {
if (r.isBottomHit(obj, otherBall)){
//Bounce up
obj.vy = -Math.abs(obj.vy*obj.damping);
} else if (r.isTopHit(obj, otherBall)){
//bounce down
obj.vy = Math.abs(obj.vy*obj.damping);
}
if (r.isLeftHit(obj, otherBall)){
//Bounce right
obj.vx = Math.abs(obj.vx*obj.damping);
} else if (r.isRightHit(obj, otherBall)){
//Bounce left
obj.vx = -Math.abs(obj.vx*obj.damping);
}
}
if (r.bottomReached(obj)) {
obj.y = window.innerHeight - obj.radius;
if (obj.vy > 5){
//Bounce
obj.vy = -(obj.vy * 0.70);
} else {
//Stop bouncing
obj.vy = 0;
if (otherBall) {
obj.vx = -(obj.vx * obj.damping);
}
obj.vx += obj.vx > 0 ? -0.008 : 0.008;
if (obj.vx < 0.010 && obj.vx > -0.010) {
obj.vx = 0;
}
}
} else if (r.topReached(obj)) {
obj.vy = Math.abs(obj.vy);
}
if (r.rightSideReached(obj)) {
obj.vx = -obj.vx;
} else if (r.leftSideReached(obj)) {
obj.vx = Math.abs(obj.vx);
}
}
},
render: function(timestamp) {
var a = _balls;
var delta = timestamp - (a.lastFrameTime || timestamp);
a.lastFrameTime = timestamp;
if (a.particles.length) {
a.ctx.clearRect(
0,
0,
window.innerWidth,
window.innerHeight
);
a.draw(delta / 16.6, timestamp);
}
window.requestAnimationFrame(a.render);
}
};
var _mouseControl = (function() {
var _el = document.getElementById("canvas");
_el.addEventListener("click", function(e) {
_balls.init.call(_balls, e.clientX, e.clientY);
});
}());
}());
I am new to development can anyone help me to to do the progress bar using waveformer.js like audio tag have.
Thanks
I think this example from codepen is very nice!
An output:
HTML code:
<canvas id="cnv" width="140" height="140"></canvas>
CSS code:
body {
background-color: #26292C;
}
#cnv {
border-radius: 50%;
}
Java Script code:
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
|| window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
(function($, _) {
var waveLoader,
drawWave;
$.fn.waveLoader = function() {
var args = arguments;
if(typeof args[0] === 'string') {
$(this).each(function() {
var ldr = $(this).data('waveLoader');
ldr[args[0]].call(ldr, Array.prototype.slice.call(args, [1]));
});
} else {
var options = _.extend({
amp: 6,
len: 10,
color: 'rgba(255,255,255,0.8)'
}, args[1] || {});
$(this).each(function() {
var $el = $(this);
$el.data('waveLoader', waveLoader($el, args[0], options.color, options.amp, options.len));
});
}
};
drawWave = function(t) {
var ctx = this.ctx;
if(this.loop > 2) this.loop = 0;
if(this.progress < 100) {
window.requestAnimationFrame(drawWave.bind(this));
}
ctx.clearRect(0, 0, this.width, this.height);
ctx.drawImage(this.img, 0, 0, this.width, this.height);
if(this.progress >= 100) {
return;
}
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.moveTo(0, this.height/2);
for(var i = 0; i <= this.width; i += 1) {
ctx.lineTo(
i,
Math.sin(i/(this.len / 2) * Math.PI - this.loop * Math.PI) * (this.amp / 2) + (this.height - this.progress * (this.height/100))
);
}
ctx.lineTo(this.width, 0);
ctx.lineTo(0, 0);
ctx.fill();
this.loop += 0.08;
};
waveLoader = function($cnv, img, color, amp, len) {
var that;
that = {
$cnv: $cnv,
img: img,
ctx: null,
width: 0,
height: 0,
loop: 0,
amp: amp,
len: len,
color: color,
progress: 0,
init: function() {
console.log($cnv);
this.ctx = this.$cnv[0].getContext('2d');
this.width = this.$cnv.width();
this.height = this.$cnv.height();
drawWave.call(this);
},
setProgress: function(newProgr) {
this.progress = Math.min(Math.max(0, newProgr), 100);
}
};
that.init();
return that;
};
})(jQuery, _);
var img = new Image();
img.src = 'https://media.wired.com/photos/5926db217034dc5f91becd6b/master/w_582,c_limit/so-logo-s.jpg';
img.onload = function() {
$('#cnv').waveLoader(img, {
amp: 8,
len: 70
});
var progress = 0;
setInterval(function() {
$('#cnv').waveLoader('setProgress', progress);
progress += Math.floor(Math.random() * 2) + 1;
}, 500);
};
It is worth trying it, no harm!
My question is for this plugin: https://codepen.io/bferioli/pen/qEGaPp
I'm trying to use several pictures in this canvas but I can't find how to. Basically, what I want is to display randomly a selection of images (10 or more) instead of only the heart.
I think I have to edit this part of that CodePen snippet:
heartHeight: 60,
heartWidth: 64,
hearts: [],
heartImage: 'http://i58.tinypic.com/ntnw5.png',
maxHearts: 8,
minScale: 0.4,
draw: function() {
this.setCanvasSize();
this.ctx.clearRect(0, 0, this.w, this.h);
for (var i = 0; i < this.hearts.length; i++) {
var heart = this.hearts[i];
heart.image = new Image();
heart.image.style.height = heart.height;
heart.image.src = this.heartImage;
this.ctx.globalAlpha = heart.opacity;
this.ctx.drawImage (heart.image, heart.x, heart.y, heart.width,
heart.height);
}
HERE IS MY CODE visible here: https://codepen.io/Le-future/pen/eKaarK
var imagesArray = ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAABlBMVEX/4AL9+dVNpYF7AAAATElEQVR4nO3BQREAAAwCIO1fein28YB0XQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAvXXdlRQHDJgU7pgAAAABJRU5ErkJggg==", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAA1BMVEUpczS1QJ41AAAASElEQVR4nO3BgQAAAADDoPlTX+AIVQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwDcaiAAFXD1ujAAAAAElFTkSuQmCC", "https://www.apyart.com/2226-thickbox_default/bleu-ciel-500ml.jpg"];
var HeartsBackground = {
heartHeight: 60,
heartWidth: 64,
hearts: [],
heartImage: 'http://i58.tinypic.com/ntnw5.png',
maxHearts: 8,
minScale: 0.4,
draw: function() {
this.setCanvasSize();
this.ctx.clearRect(0, 0, this.w, this.h);
for (var i = 0; i < this.hearts.length; i++) {
var num = Math.floor(Math.random() * 3); // 0...3
var heart = this.hearts[i];
heart.image = new Image();
heart.image.style.height = heart.height;
heart.image.src = imagesArray[num];
this.ctx.globalAlpha = heart.opacity;
this.ctx.drawImage (heart.image, heart.x, heart.y, heart.width, heart.height);
}
this.move();
},
move: function() {
for(var b = 0; b < this.hearts.length; b++) {
var heart = this.hearts[b];
heart.y += heart.ys;
if(heart.y > this.h) {
heart.x = Math.random() * this.w;
heart.y = -1 * this.heartHeight;
}
}
},
setCanvasSize: function() {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
this.w = this.canvas.width;
this.h = this.canvas.height;
},
initialize: function() {
this.canvas = $('#canvas')[0];
if(!this.canvas.getContext)
return;
this.setCanvasSize();
this.ctx = this.canvas.getContext('2d');
for(var a = 0; a < this.maxHearts; a++) {
var scale = (Math.random() * (1 - this.minScale)) + this.minScale;
this.hearts.push({
x: Math.random() * this.w,
y: Math.random() * this.h,
ys: Math.random() + 1,
height: scale * this.heartHeight,
width: scale * this.heartWidth,
opacity: scale,
image: imagesArray[Math.floor(Math.random()*imagesArray.length)]
});
}
setInterval($.proxy(this.draw, this), 30);
}
};
$(document).ready(function(){
HeartsBackground.initialize();
});
My answer is to add an array outside of the heartsBackground loop. it will be used to store the image of each of the 8 objects.
var heartsOutside = ["","","","","","","",""]
I then check to see if the outside array contains data and load if exists
if(heartsOutside[i] != ""){num = heartsOutside[i]}
Then store the data to the outside array for the next loop
heartsOutside[i] = num;
I also added a step to clear the heart image upon reaching the bottom of the fall in the move function
heartsOutside[b] = ""
var imagesArray = ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAABlBMVEX/4AL9+dVNpYF7AAAATElEQVR4nO3BQREAAAwCIO1fein28YB0XQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAvXXdlRQHDJgU7pgAAAABJRU5ErkJggg==", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAA1BMVEUpczS1QJ41AAAASElEQVR4nO3BgQAAAADDoPlTX+AIVQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwDcaiAAFXD1ujAAAAAElFTkSuQmCC", "https://www.apyart.com/2226-thickbox_default/bleu-ciel-500ml.jpg"];
var heartsOutside = ["","","","","","","",""]
var HeartsBackground = {
heartHeight: 60,
heartWidth: 64,
hearts: [],
heartImage: 'http://i58.tinypic.com/ntnw5.png',
maxHearts: 8,
minScale: 0.4,
draw: function() {
this.setCanvasSize();
this.ctx.clearRect(0, 0, this.w, this.h);
for (var i = 0; i < this.hearts.length; i++) {
//else{
var num = Math.floor(Math.random() * 3); // 0...4
if(heartsOutside[i] != ""){num = heartsOutside[i]}
var heart = this.hearts[i];
heartsOutside[i] = num;
heart.image = new Image();
heart.image.style.height = heart.height;
heart.image.src = imagesArray[num];
this.ctx.globalAlpha = heart.opacity;
this.ctx.drawImage (heart.image, heart.x, heart.y, heart.width, heart.height);
}
this.move();
},
move: function() {
for(var b = 0; b < this.hearts.length; b++) {
var heart = this.hearts[b];
heart.y += heart.ys;
if(heart.y > this.h) {
heart.x = Math.random() * this.w;
heart.y = -1 * this.heartHeight;
heartsOutside[b] = ""
}
}
},
setCanvasSize: function() {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
this.w = this.canvas.width;
this.h = this.canvas.height;
},
initialize: function() {
this.canvas = $('#canvas')[0];
if(!this.canvas.getContext)
return;
this.setCanvasSize();
this.ctx = this.canvas.getContext('2d');
for(var a = 0; a < this.maxHearts; a++) {
var scale = (Math.random() * (1 - this.minScale)) + this.minScale;
this.hearts.push({
x: Math.random() * this.w,
y: Math.random() * this.h,
ys: Math.random() + 1,
height: scale * this.heartHeight,
width: scale * this.heartWidth,
opacity: scale,
image: imagesArray[Math.floor(Math.random()*imagesArray.length)]
});
}
setInterval($.proxy(this.draw, this), 30);
}
};
$(document).ready(function(){
HeartsBackground.initialize();
});
body {
background: #B7004E;
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas"></canvas>
I work with this code for show HTML5 canvas animated in over my div:
HTML:
<div class="ls-slide" id="asb">
<div id="smile" style="width:100%;height:359px;">
<canvas style="position: absolute; width: 100%; z-index: 3; display: block;" height="359" width="2111">
</canvas>
</div>
</div>
JS:
window.onload = function() {
travers();
var lastHeight = $("#asb").height();
var canvas = document.querySelector('canvas');
ctx = canvas.getContext('2d');
color = '#aaa';
var check = respondCanvas();
canvas.width = check[1];
canvas.height = lastHeight;
canvas.style.display = 'block';
ctx.fillStyle = color;
ctx.lineWidth = .1;
ctx.strokeStyle = color;
function respondCanvas() {
var width = [];
width[0] = $('#smile').width(); //max width
width[1] = $('canvas').width(); //max width
return width;
//Call a function to redraw other content (texts, images etc)
}
function checkheight() {
var height = $('#asb').height(); //max width
//console.log(height);
// return height;
}
var mousePosition = {
x: 30 * canvas.width / 100,
y: 30 * canvas.height / 100
};
if (canvas.width <= 1000) {
var numdot = 100;
} else if (canvas.width <= 800) {
var numdot = 80;
} else if (canvas.width <= 500) {
var numdot = 35;
} else {
var numdot = 300;
}
var dots = {
nb: numdot,
distance: 70,
d_radius: 50,
array: []
};
function Dot() {
this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height;
this.vx = -.5 + Math.random();
this.vy = -.5 + Math.random();
this.radius = Math.random();
}
Dot.prototype = {
create: function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
ctx.fill();
},
animate: function() {
for (i = 0; i < dots.nb; i++) {
var dot = dots.array[i];
if (dot.y < 0 || dot.y > canvas.height) {
dot.vx = dot.vx;
dot.vy = -dot.vy;
} else if (dot.x < 0 || dot.x > canvas.width) {
dot.vx = -dot.vx;
dot.vy = dot.vy;
}
dot.x += dot.vx;
dot.y += dot.vy;
}
},
line: function() {
for (i = 0; i < dots.nb; i++) {
for (j = 0; j < dots.nb; j++) {
i_dot = dots.array[i];
j_dot = dots.array[j];
if ((i_dot.x - j_dot.x) < dots.distance && (i_dot.y - j_dot.y) < dots.distance && (i_dot.x - j_dot.x) > -dots.distance && (i_dot.y - j_dot.y) > -dots.distance) {
if ((i_dot.x - mousePosition.x) < dots.d_radius && (i_dot.y - mousePosition.y) < dots.d_radius && (i_dot.x - mousePosition.x) > -dots.d_radius && (i_dot.y - mousePosition.y) > -dots.d_radius) {
ctx.beginPath();
ctx.moveTo(i_dot.x, i_dot.y);
ctx.lineTo(j_dot.x, j_dot.y);
ctx.stroke();
ctx.closePath();
}
}
}
}
}
};
function createDots() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (i = 0; i < dots.nb; i++) {
dots.array.push(new Dot());
dot = dots.array[i];
dot.create();
}
dot.line();
dot.animate();
}
$("canvas").mousemove(function(parameter) {
mousePosition.x = parameter.pageX - 0;
mousePosition.y = parameter.pageY - 300;
});
setInterval(createDots, 1000 / 30);
};
But, In action not work and I can't see dotted animation(I checked in chrome,ff). How do fix this?!
demo : https://jsfiddle.net/5pzvh8ko/
You can try it better by giving an ID to you canvas tag, and then use "document.getElementById()", to access your canvas tag, i think it is a better method and even simpler.here is an example:
canvas tag with id:
<canvas ID="canvas_id" style="position: absolute; width: 100%; z-index:3; display: block;" height="359" width="2111">
then use JavaScript to access it this way:
var canvas = document.getElementById("canvas_id");
This might not be all you need but you can at least try it that way.
I need some expert help. When I make canvas background transparent the line colors the whole canvas (shown in code below).
How do I stop/fix this? I want the line stay as a single line that doesn't color the canvas.
Math.clamp = function(x, min, max) {
return x < min ? min : (x > max ? max : x);
};
// canvas settings
var viewWidth = window.innerWidth,
viewHeight = window.innerHeight,
drawingCanvas = document.getElementById("drawing_canvas"),
ctx,
timeStep = (10 / 100),
time = 0;
var lineTension = 0.067,
lineDamping = 0.068,
waveSpreadFactor = 0.1;
var previousMousePosition = {
x: 0,
y: 0
},
currentMousePosition = {
x: 0,
y: 0
},
actualMousePosition = {
x: 0,
y: 0
};
var line,
lineSegmentCount = 64,
lineMaxForce = 32,
lineStrokeGradient;
var audioCtx,
nodeCount = 64,
oscillatorNodes = [],
gainNodes = [];
var segmentsPerNode = lineSegmentCount / nodeCount;
function initGui() {
}
function goBananas() {
lineTension = 0.2;
line.anchors[Math.floor(Math.random() * line.anchors.length)].
vel = lineMaxForce;
}
function resetLine() {
line.reset();
for (var i = 0; i < nodeCount; i++) {
oscillatorNodes[i].detune.value = 100;
gainNodes[i].gain.value = 0;
}
lineTension = 0.0025;
lineDamping = 0.05;
waveSpreadFactor = 0.1;
}
function initDrawingCanvas() {
drawingCanvas.width = viewWidth;
drawingCanvas.height = viewHeight;
window.addEventListener('resize', resizeHandler);
window.addEventListener('mousemove', mouseMoveHandler);
setInterval(updateMousePosition, (1000 / 30));
ctx = drawingCanvas.getContext('2d');
ctx.lineWidth = 5;
line = new Line(0, viewHeight * 0.5, viewWidth, lineSegmentCount);
// line.anchors[0].vel = viewHeight * 0.25;
lineStrokeGradient = ctx.createLinearGradient(0, 0, 0, viewHeight);
lineStrokeGradient.addColorStop(0, '#0ff');
}
function initWebAudio() {
audioCtx = new(window.AudioContext || window.webkitAudioContext)();
for (var i = 0; i < nodeCount; i++) {
var oscillatorNode = audioCtx.createOscillator();
var gainNode = audioCtx.createGain();
oscillatorNode.connect(gainNode);
gainNode.connect(audioCtx.destination);
gainNode.gain.value = 0;
oscillatorNode.type = 'saw';
oscillatorNode.detune.value = 200;
oscillatorNode.frequency.value = 1200 * (i / 60);
oscillatorNode.start();
oscillatorNodes[i] = oscillatorNode;
gainNodes[i] = gainNode;
}
}
function resizeHandler() {
drawingCanvas.width = viewWidth = window.innerWidth;
drawingCanvas.height = viewHeight = window.innerHeight;
if (ctx) {
ctx.lineWidth = 4;
line.resize(viewWidth, viewHeight * 0.5);
}
}
function mouseMoveHandler(event) {
actualMousePosition.x = Math.floor(event.clientX);
actualMousePosition.y = Math.floor(event.clientY);
}
function updateMousePosition() {
previousMousePosition.x = currentMousePosition.x;
previousMousePosition.y = currentMousePosition.y;
currentMousePosition.x = actualMousePosition.x;
currentMousePosition.y = actualMousePosition.y;
}
function update() {
var px = Math.min(previousMousePosition.x, currentMousePosition.x),
py = Math.min(previousMousePosition.y, currentMousePosition.y),
pw = Math.max(1, Math.abs(previousMousePosition.x - currentMousePosition.x)),
ph = Math.max(1, Math.abs(previousMousePosition.y - currentMousePosition.y)),
force = Math.clamp(currentMousePosition.y -
previousMousePosition.y, -lineMaxForce, lineMaxForce);
var pixels = ctx.getImageData(px, py, pw, ph),
data = pixels.data;
for (var i = 0; i < data.length; i += 3) {
var r = data[i + 0],
g = data[i + 1],
b = data[i + 2],
x = (i % ph) + px;
if (r + g + b > 0) {
line.ripple(x, force);
}
}
line.update();
for (var j = 0; j < gainNodes.length; j++) {
var anchor = line.anchors[j * segmentsPerNode],
gain = Math.clamp(Math.abs(anchor.vel) / viewHeight * 0.5, 0, 3),
detune = Math.clamp(anchor.pos / viewHeight * 100, 0, 300);
gainNodes[j].gain.value = gain;
oscillatorNodes[j].detune.value = detune;
}
}
function draw() {
ctx.strokeStyle = lineStrokeGradient;
line.draw();
}
window.onload = function() {
initDrawingCanvas();
initWebAudio();
initGui();
requestAnimationFrame(loop);
};
function loop() {
update();
draw();
time += timeStep;
requestAnimationFrame(loop);
}
Line = function(x, y, length, segments) {
this.x = x;
this.y = y;
this.length = length;
this.segments = segments;
this.segmentLength = this.length / this.segments;
this.anchors = [];
for (var i = 0; i <= this.segments; i++) {
this.anchors[i] = {
target: this.y,
pos: this.y,
vel: 0,
update: function() {
var dy = this.pos - this.target,
acc = -lineTension * dy - lineDamping * this.vel;
this.pos += this.vel;
this.vel += acc;
},
reset: function() {
this.pos = this.target;
this.vel = 0;
}
};
}
};
Line.prototype = {
resize: function(length, targetY) {
this.length = length;
this.segmentLength = this.length / this.segments;
for (var i = 0; i <= this.segments; i++) {
this.anchors[i].target = targetY;
}
},
reset: function() {
for (var i = 0; i <= this.segments; i++) {
this.anchors[i].reset();
}
},
ripple: function(origin, amplitude) {
var i = Math.floor((origin - this.x) / this.segmentLength);
if (i >= 0 && i <= this.segments) {
this.anchors[i].vel = amplitude;
}
},
update: function() {
var lDeltas = [],
rDeltas = [],
i;
for (i = 0; i <= this.segments; i++) {
this.anchors[i].update();
}
for (i = 0; i <= this.segments; i++) {
if (i > 0) {
lDeltas[i] = waveSpreadFactor * (this.anchors[i].pos - this.anchors[i - 1].pos);
this.anchors[i - 1].vel += lDeltas[i];
}
if (i < this.segments) {
rDeltas[i] = waveSpreadFactor * (this.anchors[i].pos - this.anchors[i + 1].pos);
this.anchors[i + 1].vel += rDeltas[i];
}
}
for (i = 0; i <= this.segments; i++) {
if (i > 0) {
this.anchors[i - 1].pos += lDeltas[i];
}
if (i < this.segments) {
this.anchors[i + 1].pos += rDeltas[i];
}
}
},
draw: function() {
ctx.beginPath();
for (var i = 0; i <= this.segments; i++) {
ctx.lineTo(
this.x + this.segmentLength * i,
this.anchors[i].pos
);
}
ctx.stroke();
}
};
From the code you posted, the problem seems to be a missing
ctx.clearRect(0, 0, viewWidth, viewHeight)
at the beginning of your "draw" function.
See a working example here