Can't stop explosion animation in javascript - javascript

I've made an explosion animation but I can't stop it from executing. I've tried using setInterval but it doesn't seem to work. What might be wrong with this code?
function grow() {
setInterval(function() {
balloon = document.querySelector('.balloon');
balloon.style.width = '200px';
balloon.style.height = '200px';
balloon.style.transition = '3s';
setInterval(function() {
balloon.style.display = 'none';
explode(balloon);
}, 2000);
}, 2000);
};
grow();
var anchors = document.querySelectorAll('.balloon');
function explode(e) {
var x = e.clientX
var y = e.clientY
var c = document.createElement('canvas')
var ctx = c.getContext('2d')
var ratio = window.devicePixelRatio
var particles = []
document.body.appendChild(c)
c.style.position = 'absolute'
c.style.left = (x - 100) + 'px'
c.style.top = (y - 100) + 'px'
c.style.pointerEvents = 'none'
c.style.width = 200 + 'px'
c.style.height = 200 + 'px'
c.width = 200 * ratio
c.height = 200 * ratio
function Particle() {
return {
x: c.width / 2,
y: c.height / 2,
radius: r(20, 30),
color: 'rgb(' + [r(0, 255), r(0, 255), r(0, 255)].join(',') + ')',
rotation: r(0, 360, true),
speed: r(8, 12),
friction: 0.9,
opacity: r(0, 0.5, true),
yVel: 0,
gravity: 0.1
}
}
for (var i = 0; ++i < 25;) {
particles.push(Particle())
}
console.log(particles[0])
function render() {
ctx.clearRect(0, 0, c.width, c.height)
particles.forEach(function(p, i) {
angleTools.moveOnAngle(p, p.speed)
p.opacity -= 0.01
p.speed *= p.friction
p.radius *= p.friction
p.yVel += p.gravity
p.y += p.yVel
if (p.opacity < 0) return
if (p.radius < 0) return
ctx.beginPath()
ctx.globalAlpha = p.opacity
ctx.fillStyle = p.color
ctx.arc(p.x, p.y, p.radius, 0, 2 * Math.PI, false)
ctx.fill()
})
}
;
(function renderLoop() {
requestAnimationFrame(renderLoop)
render()
})()
}
var angleTools = {
getAngle: function(t, n) {
var a = n.x - t.x,
e = n.y - t.y;
return Math.atan2(e, a) / Math.PI * 180
},
getDistance: function(t, n) {
var a = t.x - n.x,
e = t.y - n.y;
return Math.sqrt(a * a + e * e)
},
moveOnAngle: function(t, n) {
var a = this.getOneFrameDistance(t, n);
t.x += a.x, t.y += a.y
},
getOneFrameDistance: function(t, n) {
return {
x: n * Math.cos(t.rotation * Math.PI / 180),
y: n * Math.sin(t.rotation * Math.PI / 180)
}
}
};
function r(a, b, c) {
return parseFloat((Math.random() * ((a ? a : 1) - (b ? b : 0)) + (b ? b : 0)).toFixed(c ? c : 0));
}
body {
margin: 20px;
background: hsl(70, 31%, 85%);
}
.explosion {
position: absolute; // required if positioned on click else 'relative'
width: 600px;
height: 600px;
pointer-events: none; // make it clickable trhough
// particle styling
.particle {
position: absolute; // required
width: 10px;
height: 10px;
border-radius: 50%;
animation: pop 1s reverse forwards; // required
}
}
// animation for particle fly away from the cursor
#keyframes pop {
from {
opacity: 0;
}
to {
top: 50%;
left: 50%;
opacity: 1;
}
}
.balloon {
display: inline-block;
width: 103px;
height: 125px;
background: hsl(215, 50%, 65%);
border-radius: 80%;
position: relative;
box-shadow: inset -10px -10px 0 rgba(0, 0, 0, 0.07);
margin: 20px 30px;
transition: transform 0.5s ease;
z-index: 10;
animation: balloons 4s ease-in-out infinite;
transform-origin: bottom center;
}
#keyframes balloons {
0%,
100% {
transform: translateY(0) rotate(-4deg);
}
50% {
transform: translateY(-25px) rotate(4deg);
}
}
.balloon:before {
content: "▲";
font-size: 20px;
color: hsl(215, 30%, 50%);
display: block;
text-align: center;
width: 100%;
position: absolute;
bottom: -12px;
z-index: -100;
}
<div class="balloon"></div>

setTimeout instead of setInterval
function grow() {
setTimeout(function() {
balloon = document.querySelector('.balloon');
balloon.style.width = '200px';
balloon.style.height = '200px';
balloon.style.transition = '3s';
setTimeout(function() {
balloon.style.display = 'none';
explode(balloon);
}, 2000);
}, 2000);
};
grow();
var anchors = document.querySelectorAll('.balloon');
function explode(e) {
var x = e.clientX
var y = e.clientY
var c = document.createElement('canvas')
var ctx = c.getContext('2d')
var ratio = window.devicePixelRatio
var particles = []
document.body.appendChild(c)
c.style.position = 'absolute'
c.style.left = (x - 100) + 'px'
c.style.top = (y - 100) + 'px'
c.style.pointerEvents = 'none'
c.style.width = 200 + 'px'
c.style.height = 200 + 'px'
c.width = 200 * ratio
c.height = 200 * ratio
function Particle() {
return {
x: c.width / 2,
y: c.height / 2,
radius: r(20, 30),
color: 'rgb(' + [r(0, 255), r(0, 255), r(0, 255)].join(',') + ')',
rotation: r(0, 360, true),
speed: r(8, 12),
friction: 0.9,
opacity: r(0, 0.5, true),
yVel: 0,
gravity: 0.1
}
}
for (var i = 0; ++i < 25;) {
particles.push(Particle())
}
console.log(particles[0])
function render() {
ctx.clearRect(0, 0, c.width, c.height)
particles.forEach(function(p, i) {
angleTools.moveOnAngle(p, p.speed)
p.opacity -= 0.01
p.speed *= p.friction
p.radius *= p.friction
p.yVel += p.gravity
p.y += p.yVel
if (p.opacity < 0) return
if (p.radius < 0) return
ctx.beginPath()
ctx.globalAlpha = p.opacity
ctx.fillStyle = p.color
ctx.arc(p.x, p.y, p.radius, 0, 2 * Math.PI, false)
ctx.fill()
})
}
;
(function renderLoop() {
requestAnimationFrame(renderLoop)
render()
})()
}
var angleTools = {
getAngle: function(t, n) {
var a = n.x - t.x,
e = n.y - t.y;
return Math.atan2(e, a) / Math.PI * 180
},
getDistance: function(t, n) {
var a = t.x - n.x,
e = t.y - n.y;
return Math.sqrt(a * a + e * e)
},
moveOnAngle: function(t, n) {
var a = this.getOneFrameDistance(t, n);
t.x += a.x, t.y += a.y
},
getOneFrameDistance: function(t, n) {
return {
x: n * Math.cos(t.rotation * Math.PI / 180),
y: n * Math.sin(t.rotation * Math.PI / 180)
}
}
};
function r(a, b, c) {
return parseFloat((Math.random() * ((a ? a : 1) - (b ? b : 0)) + (b ? b : 0)).toFixed(c ? c : 0));
}
body {
margin: 20px;
background: hsl(70, 31%, 85%);
}
.explosion {
position: absolute; // required if positioned on click else 'relative'
width: 600px;
height: 600px;
pointer-events: none; // make it clickable trhough
// particle styling
.particle {
position: absolute; // required
width: 10px;
height: 10px;
border-radius: 50%;
animation: pop 1s reverse forwards; // required
}
}
// animation for particle fly away from the cursor
#keyframes pop {
from {
opacity: 0;
}
to {
top: 50%;
left: 50%;
opacity: 1;
}
}
.balloon {
display: inline-block;
width: 103px;
height: 125px;
background: hsl(215, 50%, 65%);
border-radius: 80%;
position: relative;
box-shadow: inset -10px -10px 0 rgba(0, 0, 0, 0.07);
margin: 20px 30px;
transition: transform 0.5s ease;
z-index: 10;
animation: balloons 4s ease-in-out infinite;
transform-origin: bottom center;
}
#keyframes balloons {
0%,
100% {
transform: translateY(0) rotate(-4deg);
}
50% {
transform: translateY(-25px) rotate(4deg);
}
}
.balloon:before {
content: "▲";
font-size: 20px;
color: hsl(215, 30%, 50%);
display: block;
text-align: center;
width: 100%;
position: absolute;
bottom: -12px;
z-index: -100;
}
<div class="balloon"></div>

Related

Trying to run one function after the other using JS

I've been having some trouble running one function that slowly displays a message, waits, then fades out. However, you'll notice when the button is clicked to drop the confetti and display the message, the confetti doesn't stop.
I'm still learning Javascript, and am not that experienced with it yet. But I pieced this together to get what I'm looking for as an end result.
What I'd like to happen is when the button is clicked, the message fades in, confetti falls, message fades and confetti stops falling but allows the last bit of confetti to fall until its off screen...
It's probably because I don't understand Javascript to this level yet, but I'm having a really hard time getting the JS to do what I'm wanting...
Can anyone give me some pointers in my code to help guide me in the right direction?
Thanks!!
(function() {
// globals
var canvas;
var ctx;
var W;
var H;
var mp = 200; //max particles
var particles = [];
var angle = 0;
var tiltAngle = 0;
var confettiActive = false;
var animationComplete = true;
var deactivationTimerHandler;
var reactivationTimerHandler;
var animationHandler;
// objects
var particleColors = {
colorOptions: ["Aqua", "Aquamarine ", "DarkViolet", "DodgerBlue", "Lime", "Yellow", "DeepPink", "SlateBlue", "AliceBlue", "Fuchsia", "PaleGreen", "SteelBlue", "SandyBrown", "Chocolate", "Crimson"],
colorIndex: 0,
colorIncrementer: 0,
colorThreshold: 10,
getColor: function() {
if (this.colorIncrementer >= 10) {
this.colorIncrementer = 0;
this.colorIndex++;
if (this.colorIndex >= this.colorOptions.length) {
this.colorIndex = 0;
}
}
this.colorIncrementer++;
return this.colorOptions[this.colorIndex];
}
}
function confettiParticle(color) {
this.x = Math.random() * W; // x-coordinate
this.y = (Math.random() * H) - H; //y-coordinate
this.r = RandomFromTo(10, 30); //radius;
this.d = (Math.random() * mp) + 10; //density;
this.color = color;
this.tilt = Math.floor(Math.random() * 10) - 10;
this.tiltAngleIncremental = (Math.random() * 0.07) + .05;
this.tiltAngle = 0;
this.draw = function() {
ctx.beginPath();
ctx.lineWidth = this.r / 2;
ctx.strokeStyle = this.color;
ctx.moveTo(this.x + this.tilt + (this.r / 4), this.y);
ctx.lineTo(this.x + this.tilt, this.y + this.tilt + (this.r / 4));
return ctx.stroke();
}
}
$(document).ready(function() {
SetGlobals();
InitializeButton();
$(window).resize(function() {
W = window.innerWidth;
H = window.innerHeight;
canvas.width = W;
canvas.height = H;
});
});
function InitializeButton() {
$('#stopButton').click(DeactivateConfetti);
$('#startButton').click(RestartConfetti);
}
function SetGlobals() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
W = window.innerWidth;
H = window.innerHeight;
canvas.width = W;
canvas.height = H;
}
function InitializeConfetti() {
particles = [];
animationComplete = false;
for (var i = 0; i < mp; i++) {
var particleColor = particleColors.getColor();
particles.push(new confettiParticle(particleColor));
}
StartConfetti();
}
function Draw() {
ctx.clearRect(0, 0, W, H);
var results = [];
for (var i = 0; i < mp; i++) {
(function(j) {
results.push(particles[j].draw());
})(i);
}
Update();
return results;
}
function RandomFromTo(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}
function Update() {
var remainingFlakes = 0;
var particle;
angle += 0.01;
tiltAngle += 0.1;
for (var i = 0; i < mp; i++) {
particle = particles[i];
if (animationComplete) return;
if (!confettiActive && particle.y < -15) {
particle.y = H + 100;
continue;
}
stepParticle(particle, i);
if (particle.y <= H) {
remainingFlakes++;
}
CheckForReposition(particle, i);
}
if (remainingFlakes === 0) {
StopConfetti();
}
}
function CheckForReposition(particle, index) {
if ((particle.x > W + 20 || particle.x < -20 || particle.y > H) && confettiActive) {
if (index % 5 > 0 || index % 2 == 0) //66.67% of the flakes
{
repositionParticle(particle, Math.random() * W, -10, Math.floor(Math.random() * 10) - 10);
} else {
if (Math.sin(angle) > 0) {
//Enter from the left
repositionParticle(particle, -5, Math.random() * H, Math.floor(Math.random() * 10) - 10);
} else {
//Enter from the right
repositionParticle(particle, W + 5, Math.random() * H, Math.floor(Math.random() * 10) - 10);
}
}
}
}
function stepParticle(particle, particleIndex) {
particle.tiltAngle += particle.tiltAngleIncremental;
particle.y += (Math.cos(angle + particle.d) + 3 + particle.r / 2) / 2;
particle.x += Math.sin(angle);
particle.tilt = (Math.sin(particle.tiltAngle - (particleIndex / 3))) * 15;
}
function repositionParticle(particle, xCoordinate, yCoordinate, tilt) {
particle.x = xCoordinate;
particle.y = yCoordinate;
particle.tilt = tilt;
}
function StartConfetti() {
W = window.innerWidth;
H = window.innerHeight;
canvas.width = W;
canvas.height = H;
(function animloop() {
if (animationComplete) return null;
animationHandler = requestAnimFrame(animloop);
return Draw();
})();
}
function ClearTimers() {
clearTimeout(reactivationTimerHandler);
clearTimeout(animationHandler);
}
function DeactivateConfetti() {
confettiActive = false;
ClearTimers();
}
function StopConfetti() {
animationComplete = true;
}
function RestartConfetti() {
ClearTimers();
StopConfetti();
reactivationTimerHandler = setTimeout(function() {
confettiActive = true;
animationComplete = false;
InitializeConfetti();
}, 100);
}
window.requestAnimFrame = (function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
return window.setTimeout(callback, 1000 / 60);
};
})();
})();
/* Styles go here */
html,
body,
canvas {
height: 100%;
width: 100%;
margin: 0;
background-color: #1a1a1a;
}
canvas {
display: block;
position: relative;
zindex: 1;
pointer-events: none;
}
button {
padding: 5px 10px;
font-size: 20px;
}
.scene {
display: flex;
position: relative;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
}
.scene>canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.scene-content {
position: relative;
text-align: center;
width: auto;
height: auto;
font-size: 10rem;
font-family: Roboto;
font-weight: 200;
color: hsla(255, 50%, 100%, 1);
animation: hue-shift 2s infinite linear;
}
.scene-content1 {
position: relative;
text-align: center;
width: auto;
height: auto;
font-size: 10rem;
font-family: Roboto;
font-weight: 200;
color: hsla(255, 50%, 100%, 1);
animation: hue-shift 2s infinite linear;
}
.scene-content2 {
position: relative;
text-align: center;
width: auto;
height: auto;
font-size: 6rem;
font-family: Roboto;
font-weight: 100;
color: hsla(255, 50%, 50%, 1);
animation: hue-shift 2s infinite linear;
}
.devices {
margin-left: auto;
margin-right: auto;
text-align: center;
color: hsla(255, 50%, 100%, 1);
animation: hue-shift 2s infinite linear;
}
#keyframes hue-shift {
0% {
color: hsla(0, 80%, 80%, 1);
}
25% {
color: hsla(120, 80%, 80%, 1);
}
75% {
color: hsla(240, 80%, 80%, 1);
}
100% {
color: hsla(360, 80%, 80%, 1);
}
}
.buttonContainer {
display: inline-block;
}
button {
padding: 5px 10px;
font-size: 20px;
}
.clicker+.circle {
-webkit-animation: rotor 1.5s linear 0s infinite normal;
-mox-animation: rotor 1.5s linear 0s infinite normal;
-o-animation: rotor 1.5s linear 0s infinite normal;
animation: rotor 1.5s linear 0s infinite normal;
}
.paused {
-webkit-animation-play-state: paused !important;
-moz-animation-play-state: paused !important;
-o-animation-play-state: paused !important;
animation-play-state: paused !important;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href='http://fonts.googleapis.com/css?family=Roboto:400,100,300,500,700,900' rel='stylesheet'>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link href="https://unpkg.com/ionicons#4.2.0/dist/css/ionicons.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
<link rel="stylesheet" href="css/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<audio id="bubble_pop">
<source src="mp3/pop.mp3" type="audio/mp3">
Your browser does not support the audio element.
</audio>
<div class="scene">
<canvas id="canvas"></canvas>
<div class="scene-content">
<div class="devices">
<i class="icon ion-ios-phone-portrait" style="font-size: 1.8em;"></i>
<i class="icon ion-ios-watch" style="font-size: 1.6em;"></i>
</div>
<p class="scene-content1">Success!</p>
<p class="scene-content2">Way to go! You can now use your device!</p>
</div>
<!--Hiding the message on initial page load-->
<script type="text/javascript">
$('.scene-content').hide();
</script>
</div>
<p>
<button id="stopButton">Stop</button>
<button id="startButton" onclick="playAudio();">Drop it like its hot</button>
</p>
</body>
<script>
var pop = document.getElementById("bubble_pop");
function playAudio() {
pop.play();
}
document.getElementById('startButton').addEventListener('click', function() {
function complete() {
$("<div>").text(this.class).appendTo(".scene-content");
}
$(".scene-content").fadeIn(500).delay(2500).fadeOut(500, "linear", function() {});
});
</script>
</html>
The fadeOut() has one callback where you pass what should happen when animation is over.You must have tried this but reason why it didn't work is that most of your js code is in a self executing function which forms a different scope so you cannot call any method inside this scope from outside.I have moved the stuff inside now it works.Not much change there just changed a few lines; marked with NEWLY ADDED
(function() {
// globals
var canvas;
var ctx;
var W;
var H;
var mp = 200; //max particles
var particles = [];
var angle = 0;
var tiltAngle = 0;
var confettiActive = false;
var animationComplete = true;
var deactivationTimerHandler;
var reactivationTimerHandler;
var animationHandler;
// objects
var particleColors = {
colorOptions: ["Aqua", "Aquamarine ", "DarkViolet", "DodgerBlue", "Lime", "Yellow", "DeepPink", "SlateBlue", "AliceBlue", "Fuchsia", "PaleGreen", "SteelBlue", "SandyBrown", "Chocolate", "Crimson"],
colorIndex: 0,
colorIncrementer: 0,
colorThreshold: 10,
getColor: function() {
if (this.colorIncrementer >= 10) {
this.colorIncrementer = 0;
this.colorIndex++;
if (this.colorIndex >= this.colorOptions.length) {
this.colorIndex = 0;
}
}
this.colorIncrementer++;
return this.colorOptions[this.colorIndex];
}
}
function confettiParticle(color) {
this.x = Math.random() * W; // x-coordinate
this.y = (Math.random() * H) - H; //y-coordinate
this.r = RandomFromTo(10, 30); //radius;
this.d = (Math.random() * mp) + 10; //density;
this.color = color;
this.tilt = Math.floor(Math.random() * 10) - 10;
this.tiltAngleIncremental = (Math.random() * 0.07) + .05;
this.tiltAngle = 0;
this.draw = function() {
ctx.beginPath();
ctx.lineWidth = this.r / 2;
ctx.strokeStyle = this.color;
ctx.moveTo(this.x + this.tilt + (this.r / 4), this.y);
ctx.lineTo(this.x + this.tilt, this.y + this.tilt + (this.r / 4));
return ctx.stroke();
}
}
$(document).ready(function() {
SetGlobals();
InitializeButton();
$(window).resize(function() {
W = window.innerWidth;
H = window.innerHeight;
canvas.width = W;
canvas.height = H;
});
});
function InitializeButton() {
$('#stopButton').click(DeactivateConfetti);
$('#startButton').click(RestartConfetti);
}
function SetGlobals() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
W = window.innerWidth;
H = window.innerHeight;
canvas.width = W;
canvas.height = H;
}
function InitializeConfetti() {
particles = [];
animationComplete = false;
for (var i = 0; i < mp; i++) {
var particleColor = particleColors.getColor();
particles.push(new confettiParticle(particleColor));
}
StartConfetti();
}
function Draw() {
ctx.clearRect(0, 0, W, H);
var results = [];
for (var i = 0; i < mp; i++) {
(function(j) {
results.push(particles[j].draw());
})(i);
}
Update();
return results;
}
function RandomFromTo(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}
function Update() {
var remainingFlakes = 0;
var particle;
angle += 0.01;
tiltAngle += 0.1;
for (var i = 0; i < mp; i++) {
particle = particles[i];
if (animationComplete) return;
if (!confettiActive && particle.y < -15) {
particle.y = H + 100;
continue;
}
stepParticle(particle, i);
if (particle.y <= H) {
remainingFlakes++;
}
CheckForReposition(particle, i);
}
if (remainingFlakes === 0) {
StopConfetti();
}
}
function CheckForReposition(particle, index) {
if ((particle.x > W + 20 || particle.x < -20 || particle.y > H) && confettiActive) {
if (index % 5 > 0 || index % 2 == 0) //66.67% of the flakes
{
repositionParticle(particle, Math.random() * W, -10, Math.floor(Math.random() * 10) - 10);
} else {
if (Math.sin(angle) > 0) {
//Enter from the left
repositionParticle(particle, -5, Math.random() * H, Math.floor(Math.random() * 10) - 10);
} else {
//Enter from the right
repositionParticle(particle, W + 5, Math.random() * H, Math.floor(Math.random() * 10) - 10);
}
}
}
}
function stepParticle(particle, particleIndex) {
particle.tiltAngle += particle.tiltAngleIncremental;
particle.y += (Math.cos(angle + particle.d) + 3 + particle.r / 2) / 2;
particle.x += Math.sin(angle);
particle.tilt = (Math.sin(particle.tiltAngle - (particleIndex / 3))) * 15;
}
function repositionParticle(particle, xCoordinate, yCoordinate, tilt) {
particle.x = xCoordinate;
particle.y = yCoordinate;
particle.tilt = tilt;
}
function StartConfetti() {
W = window.innerWidth;
H = window.innerHeight;
canvas.width = W;
canvas.height = H;
(function animloop() {
if (animationComplete) return null;
animationHandler = requestAnimFrame(animloop);
return Draw();
})();
}
function ClearTimers() {
clearTimeout(reactivationTimerHandler);
clearTimeout(animationHandler);
}
function DeactivateConfetti() {
confettiActive = false;
ClearTimers();
}
function StopConfetti() {
animationComplete = true;
}
function RestartConfetti() {
playAudio(); // <-- NEWLY ADDED
ClearTimers();
StopConfetti();
reactivationTimerHandler = setTimeout(function() {
confettiActive = true;
animationComplete = false;
InitializeConfetti();
}, 100);
}
window.requestAnimFrame = (function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
return window.setTimeout(callback, 1000 / 60);
};
})();
/**** NEWLY ADDED ****/
var pop = document.getElementById("bubble_pop");
function playAudio() {
pop.play();
}
document.getElementById('startButton').addEventListener('click', function() {
function complete() {
$("<div>").text(this.class).appendTo(".scene-content");
}
$(".scene-content").fadeIn(500).delay(2500).fadeOut(500, "linear", function() { DeactivateConfetti(); });
});
/**** *********** ****/
})();
/* Styles go here */
html,
body,
canvas {
height: 100%;
width: 100%;
margin: 0;
background-color: #1a1a1a;
}
canvas {
display: block;
position: relative;
zindex: 1;
pointer-events: none;
}
button {
padding: 5px 10px;
font-size: 20px;
}
.scene {
display: flex;
position: relative;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
}
.scene>canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.scene-content {
position: relative;
text-align: center;
width: auto;
height: auto;
font-size: 10rem;
font-family: Roboto;
font-weight: 200;
color: hsla(255, 50%, 100%, 1);
animation: hue-shift 2s infinite linear;
}
.scene-content1 {
position: relative;
text-align: center;
width: auto;
height: auto;
font-size: 10rem;
font-family: Roboto;
font-weight: 200;
color: hsla(255, 50%, 100%, 1);
animation: hue-shift 2s infinite linear;
}
.scene-content2 {
position: relative;
text-align: center;
width: auto;
height: auto;
font-size: 6rem;
font-family: Roboto;
font-weight: 100;
color: hsla(255, 50%, 50%, 1);
animation: hue-shift 2s infinite linear;
}
.devices {
margin-left: auto;
margin-right: auto;
text-align: center;
color: hsla(255, 50%, 100%, 1);
animation: hue-shift 2s infinite linear;
}
#keyframes hue-shift {
0% {
color: hsla(0, 80%, 80%, 1);
}
25% {
color: hsla(120, 80%, 80%, 1);
}
75% {
color: hsla(240, 80%, 80%, 1);
}
100% {
color: hsla(360, 80%, 80%, 1);
}
}
.buttonContainer {
display: inline-block;
}
button {
padding: 5px 10px;
font-size: 20px;
}
.clicker+.circle {
-webkit-animation: rotor 1.5s linear 0s infinite normal;
-mox-animation: rotor 1.5s linear 0s infinite normal;
-o-animation: rotor 1.5s linear 0s infinite normal;
animation: rotor 1.5s linear 0s infinite normal;
}
.paused {
-webkit-animation-play-state: paused !important;
-moz-animation-play-state: paused !important;
-o-animation-play-state: paused !important;
animation-play-state: paused !important;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href='http://fonts.googleapis.com/css?family=Roboto:400,100,300,500,700,900' rel='stylesheet'>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link href="https://unpkg.com/ionicons#4.2.0/dist/css/ionicons.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
<link rel="stylesheet" href="css/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<audio id="bubble_pop">
<source src="mp3/pop.mp3" type="audio/mp3">
Your browser does not support the audio element.
</audio>
<div class="scene">
<canvas id="canvas"></canvas>
<div class="scene-content">
<div class="devices">
<i class="icon ion-ios-phone-portrait" style="font-size: 1.8em;"></i>
<i class="icon ion-ios-watch" style="font-size: 1.6em;"></i>
</div>
<p class="scene-content1">Success!</p>
<p class="scene-content2">Way to go! You can now use your device!</p>
</div>
<!--Hiding the message on initial page load-->
<script type="text/javascript">
$('.scene-content').hide();
</script>
</div>
<p>
<button id="stopButton">Stop</button>
<button id="startButton">Drop it like its hot</button>
</p>
</body>
<script>
</script>
</html>

Canvas responsive scroll

I use sketch.js plugin in my website but If I use it will be not responsive and the horizontal scroll will be appear I don't need to depend on body { overflow: hidden }so what is the solution:
Here my code:
// ----------------------------------------
// Particle
// ----------------------------------------
function Particle(x, y, radius) {
this.init(x, y, radius);
}
Particle.prototype = {
init: function (x, y, radius) {
this.alive = true;
this.radius = radius || 10;
this.wander = 0.15;
this.theta = random(TWO_PI);
this.drag = 0.92;
this.color = '#fff';
this.x = x || 0.0;
this.y = y || 0.0;
this.vx = 0.0;
this.vy = 0.0;
},
move: function () {
this.x += this.vx;
this.y += this.vy;
this.vx *= this.drag;
this.vy *= this.drag;
this.theta += random(-0.5, 0.5) * this.wander;
this.vx += sin(this.theta) * 0.1;
this.vy += cos(this.theta) * 0.1;
this.radius *= 0.96;
this.alive = this.radius > 0.5;
},
draw: function (ctx) {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, TWO_PI);
ctx.fillStyle = this.color;
ctx.fill();
}
};
// ----------------------------------------
// Example
// ----------------------------------------
var MAX_PARTICLES = 280;
var COLOURS = ['#69D2E7', '#A7DBD8', '#E0E4CC', '#F38630', '#FA6900', '#FF4E50', '#F9D423'];
var particles = [];
var pool = [];
var demo = Sketch.create({
container: document.getElementById('particles'),
retina: 'auto'
});
demo.setup = function () {
// Set off some initial particles.
var i, x, y;
for (i = 0; i < 20; i++) {
x = (demo.width * 0.5) + random(-100, 100);
y = (demo.height * 0.5) + random(-100, 100);
demo.spawn(x, y);
}
};
demo.spawn = function (x, y) {
var particle, theta, force;
if (particles.length >= MAX_PARTICLES)
pool.push(particles.shift());
particle = pool.length ? pool.pop() : new Particle();
particle.init(x, y, random(5, 40));
particle.wander = random(0.5, 2.0);
particle.color = random(COLOURS);
particle.drag = random(0.9, 0.99);
theta = random(TWO_PI);
force = random(2, 8);
particle.vx = sin(theta) * force;
particle.vy = cos(theta) * force;
particles.push(particle);
};
demo.update = function () {
var i, particle;
for (i = particles.length - 1; i >= 0; i--) {
particle = particles[i];
if (particle.alive) particle.move();
else pool.push(particles.splice(i, 1)[0]);
}
};
demo.draw = function () {
demo.globalCompositeOperation = 'lighter';
for (var i = particles.length - 1; i >= 0; i--) {
particles[i].draw(demo);
}
};
demo.mousemove = function () {
var particle, theta, force, touch, max, i, j, n;
for (i = 0, n = demo.touches.length; i < n; i++) {
touch = demo.touches[i], max = random(1, 4);
for (j = 0; j < max; j++) {
demo.spawn(touch.x, touch.y);
}
}
};
html, body{
height:100%;
}
ul{
margin:0;
padding:0;
}
section {
padding: 50px 0;
}
#home {
width: 100%;
height:100%;
position: relative;
padding: 50px;
background-image: url(../images/cover1.jpg);
background-position:center center;
background-size: cover;
}
#home #particles {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left:0;
background-color:#333333;
}
#home .overlay {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.60);
}
#home .text-content {
width: 65%;
margin: auto;
padding: 10px;
position: absolute;
top: 50%;
right: 0;
left: 0;
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
color:#ffffff;
text-align: center;
}
<script src="http://soulwire.github.io/sketch.js/js/sketch.js"></script>
<section id="home" >
<div class="overlay">
<div id="particles">
</div>
<div class="text-content">
content
</div>
</div>
</section>
Please run code snippet in full screen
try this, I fixed it with negative margin on canvas
#particles canvas{
margin:-15px -15px 0 0;
}
https://jsfiddle.net/mkdizajn/pLohsbnu/

Calling a function of an external Javascript on button click

I use this SVG Pie Chart on my website. It has a pretty animation on load (as you can see by running the snippet below) but I don't want it to be visible by default. I want it show up with its animation on a button click after the page is loaded.
Its probably controlled by triggerAnimation(); function in pie.js but it gets called automatically when the page is loaded as the script is external.
 <!-- Pie chart JS-->
<script src="js/pie.js"></script>
How can I control the function from a button click? Help would be appreciated.
Below is a live snippet of the pie chart :
PIE.js, PIE.css and PIE.html
$(function(){
$("#pieChart").drawPieChart([
{ title: "Tokyo", value : 180, color: "#02B3E7" },
{ title: "San Francisco", value: 60, color: "#CFD3D6" },
{ title: "London", value : 50, color: "#736D79" },
{ title: "New York", value: 30, color: "#776068" },
{ title: "Sydney", value : 20, color: "#EB0D42" },
{ title: "Berlin", value : 20, color: "#FFEC62" },
{ title: "Osaka", value : 7, color: "#04374E" }
]);
});
/*!
* jquery.drawPieChart.js
* Version: 0.3(Beta)
* Inspired by Chart.js(http://www.chartjs.org/)
*
* Copyright 2013 hiro
* https://github.com/githiro/drawPieChart
* Released under the MIT license.
*/
;(function($, undefined) {
$.fn.drawPieChart = function(data, options) {
var $this = this,
W = $this.width(),
H = $this.height(),
centerX = W/2,
centerY = H/2,
cos = Math.cos,
sin = Math.sin,
PI = Math.PI,
settings = $.extend({
segmentShowStroke : true,
segmentStrokeColor : "#fff",
segmentStrokeWidth : 1,
baseColor: "#fff",
baseOffset: 15,
edgeOffset: 30,//offset from edge of $this
pieSegmentGroupClass: "pieSegmentGroup",
pieSegmentClass: "pieSegment",
lightPiesOffset: 12,//lighten pie's width
lightPiesOpacity: .3,//lighten pie's default opacity
lightPieClass: "lightPie",
animation : true,
animationSteps : 90,
animationEasing : "easeInOutExpo",
tipOffsetX: -15,
tipOffsetY: -45,
tipClass: "pieTip",
beforeDraw: function(){ },
afterDrawed : function(){ },
onPieMouseenter : function(e,data){ },
onPieMouseleave : function(e,data){ },
onPieClick : function(e,data){ }
}, options),
animationOptions = {
linear : function (t){
return t;
},
easeInOutExpo: function (t) {
var v = t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t;
return (v>1) ? 1 : v;
}
},
requestAnimFrame = function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
}();
var $wrapper = $('<svg width="' + W + '" height="' + H + '" viewBox="0 0 ' + W + ' ' + H + '" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"></svg>').appendTo($this);
var $groups = [],
$pies = [],
$lightPies = [],
easingFunction = animationOptions[settings.animationEasing],
pieRadius = Min([H/2,W/2]) - settings.edgeOffset,
segmentTotal = 0;
//Draw base circle
var drawBasePie = function(){
var base = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
var $base = $(base).appendTo($wrapper);
base.setAttribute("cx", centerX);
base.setAttribute("cy", centerY);
base.setAttribute("r", pieRadius+settings.baseOffset);
base.setAttribute("fill", settings.baseColor);
}();
//Set up pie segments wrapper
var pathGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
var $pathGroup = $(pathGroup).appendTo($wrapper);
$pathGroup[0].setAttribute("opacity",0);
//Set up tooltip
var $tip = $('<div class="' + settings.tipClass + '" />').appendTo('body').hide(),
tipW = $tip.width(),
tipH = $tip.height();
for (var i = 0, len = data.length; i < len; i++){
segmentTotal += data[i].value;
var g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
g.setAttribute("data-order", i);
g.setAttribute("class", settings.pieSegmentGroupClass);
$groups[i] = $(g).appendTo($pathGroup);
$groups[i]
.on("mouseenter", pathMouseEnter)
.on("mouseleave", pathMouseLeave)
.on("mousemove", pathMouseMove)
.on("click", pathClick);
var p = document.createElementNS('http://www.w3.org/2000/svg', 'path');
p.setAttribute("stroke-width", settings.segmentStrokeWidth);
p.setAttribute("stroke", settings.segmentStrokeColor);
p.setAttribute("stroke-miterlimit", 2);
p.setAttribute("fill", data[i].color);
p.setAttribute("class", settings.pieSegmentClass);
$pies[i] = $(p).appendTo($groups[i]);
var lp = document.createElementNS('http://www.w3.org/2000/svg', 'path');
lp.setAttribute("stroke-width", settings.segmentStrokeWidth);
lp.setAttribute("stroke", settings.segmentStrokeColor);
lp.setAttribute("stroke-miterlimit", 2);
lp.setAttribute("fill", data[i].color);
lp.setAttribute("opacity", settings.lightPiesOpacity);
lp.setAttribute("class", settings.lightPieClass);
$lightPies[i] = $(lp).appendTo($groups[i]);
}
settings.beforeDraw.call($this);
//Animation start
triggerAnimation();
function pathMouseEnter(e){
var index = $(this).data().order;
$tip.text(data[index].title + ": " + data[index].value).fadeIn(200);
if ($groups[index][0].getAttribute("data-active") !== "active"){
$lightPies[index].animate({opacity: .8}, 180);
}
settings.onPieMouseenter.apply($(this),[e,data]);
}
function pathMouseLeave(e){
var index = $(this).data().order;
$tip.hide();
if ($groups[index][0].getAttribute("data-active") !== "active"){
$lightPies[index].animate({opacity: settings.lightPiesOpacity}, 100);
}
settings.onPieMouseleave.apply($(this),[e,data]);
}
function pathMouseMove(e){
$tip.css({
top: e.pageY + settings.tipOffsetY,
left: e.pageX - $tip.width() / 2 + settings.tipOffsetX
});
}
function pathClick(e){
var index = $(this).data().order;
var targetGroup = $groups[index][0];
for (var i = 0, len = data.length; i < len; i++){
if (i === index) continue;
$groups[i][0].setAttribute("data-active","");
$lightPies[i].css({opacity: settings.lightPiesOpacity});
}
if (targetGroup.getAttribute("data-active") === "active"){
targetGroup.setAttribute("data-active","");
$lightPies[index].css({opacity: .8});
} else {
targetGroup.setAttribute("data-active","active");
$lightPies[index].css({opacity: 1});
}
settings.onPieClick.apply($(this),[e,data]);
}
function drawPieSegments (animationDecimal){
var startRadius = -PI/2,//-90 degree
rotateAnimation = 1;
if (settings.animation) {
rotateAnimation = animationDecimal;//count up between0~1
}
$pathGroup[0].setAttribute("opacity",animationDecimal);
//draw each path
for (var i = 0, len = data.length; i < len; i++){
var segmentAngle = rotateAnimation * ((data[i].value/segmentTotal) * (PI*2)),//start radian
endRadius = startRadius + segmentAngle,
largeArc = ((endRadius - startRadius) % (PI * 2)) > PI ? 1 : 0,
startX = centerX + cos(startRadius) * pieRadius,
startY = centerY + sin(startRadius) * pieRadius,
endX = centerX + cos(endRadius) * pieRadius,
endY = centerY + sin(endRadius) * pieRadius,
startX2 = centerX + cos(startRadius) * (pieRadius + settings.lightPiesOffset),
startY2 = centerY + sin(startRadius) * (pieRadius + settings.lightPiesOffset),
endX2 = centerX + cos(endRadius) * (pieRadius + settings.lightPiesOffset),
endY2 = centerY + sin(endRadius) * (pieRadius + settings.lightPiesOffset);
var cmd = [
'M', startX, startY,//Move pointer
'A', pieRadius, pieRadius, 0, largeArc, 1, endX, endY,//Draw outer arc path
'L', centerX, centerY,//Draw line to the center.
'Z'//Cloth path
];
var cmd2 = [
'M', startX2, startY2,
'A', pieRadius + settings.lightPiesOffset, pieRadius + settings.lightPiesOffset, 0, largeArc, 1, endX2, endY2,//Draw outer arc path
'L', centerX, centerY,
'Z'
];
$pies[i][0].setAttribute("d",cmd.join(' '));
$lightPies[i][0].setAttribute("d", cmd2.join(' '));
startRadius += segmentAngle;
}
}
var animFrameAmount = (settings.animation)? 1/settings.animationSteps : 1,//if settings.animationSteps is 10, animFrameAmount is 0.1
animCount =(settings.animation)? 0 : 1;
function triggerAnimation(){
if (settings.animation) {
requestAnimFrame(animationLoop);
} else {
drawPieSegments(1);
}
}
function animationLoop(){
animCount += animFrameAmount;//animCount start from 0, after "settings.animationSteps"-times executed, animCount reaches 1.
drawPieSegments(easingFunction(animCount));
if (animCount < 1){
requestAnimFrame(arguments.callee);
} else {
settings.afterDrawed.call($this);
}
}
function Max(arr){
return Math.max.apply(null, arr);
}
function Min(arr){
return Math.min.apply(null, arr);
}
return $this;
};
})(jQuery);
.chart {
position: absolute;
width: 250px;
height: 250px;
top: 100%;
left: 50%;
margin: -225px 0 0 -225px;
}
.pieTip {
position: absolute;
float: left;
min-width: 30px;
max-width: 300px;
padding: 5px 18px 6px;
border-radius: 2px;
background: rgba(255,255,255,.97);
color: #444;
font-size: 19px;
text-shadow: 0 1px 0 #fff;
text-transform: uppercase;
text-align: center;
line-height: 1.3;
letter-spacing: .06em;
box-shadow: 0 0 3px rgba(0,0,0,0.2), 0 1px 2px rgba(0,0,0,0.5);
-webkit-transform: all .3s;
-moz-transform: all .3s;
-ms-transform: all .3s;
-o-transform: all .3s;
transform: all .3s;
pointer-events: none;
}
.pieTip:after {
position: absolute;
left: 50%;
bottom: -6px;
content: "";
height: 0;
margin: 0 0 0 -6px;
border-right: 5px solid transparent;
border-left: 5px solid transparent;
border-top: 6px solid rgba(255,255,255,.95);
line-height: 0;
}
.chart path { cursor: pointer; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="pieChart" class="chart"></div>
Call .drawPieChart() on button click event:
$(function() {
$('button').click(function() {
// Clean up old chart contents
$("#pieChart").empty();
// Clean up Tooltips created by chart
$('.pieTip').remove();
// Draw a new chart
$("#pieChart").drawPieChart([{
title: "Tokyo",
value: 180,
color: "#02B3E7"
}, {
title: "San Francisco",
value: 60,
color: "#CFD3D6"
}, {
title: "London",
value: 50,
color: "#736D79"
}, {
title: "New York",
value: 30,
color: "#776068"
}, {
title: "Sydney",
value: 20,
color: "#EB0D42"
}, {
title: "Berlin",
value: 20,
color: "#FFEC62"
}, {
title: "Osaka",
value: 7,
color: "#04374E"
}]);
});
});
/*!
* jquery.drawPieChart.js
* Version: 0.3(Beta)
* Inspired by Chart.js(http://www.chartjs.org/)
*
* Copyright 2013 hiro
* https://github.com/githiro/drawPieChart
* Released under the MIT license.
*/
;
(function($, undefined) {
$.fn.drawPieChart = function(data, options) {
var $this = this,
W = $this.width(),
H = $this.height(),
centerX = W / 2,
centerY = H / 2,
cos = Math.cos,
sin = Math.sin,
PI = Math.PI,
settings = $.extend({
segmentShowStroke: true,
segmentStrokeColor: "#fff",
segmentStrokeWidth: 1,
baseColor: "#fff",
baseOffset: 15,
edgeOffset: 30, //offset from edge of $this
pieSegmentGroupClass: "pieSegmentGroup",
pieSegmentClass: "pieSegment",
lightPiesOffset: 12, //lighten pie's width
lightPiesOpacity: .3, //lighten pie's default opacity
lightPieClass: "lightPie",
animation: true,
animationSteps: 90,
animationEasing: "easeInOutExpo",
tipOffsetX: -15,
tipOffsetY: -45,
tipClass: "pieTip",
beforeDraw: function() {},
afterDrawed: function() {},
onPieMouseenter: function(e, data) {},
onPieMouseleave: function(e, data) {},
onPieClick: function(e, data) {}
}, options),
animationOptions = {
linear: function(t) {
return t;
},
easeInOutExpo: function(t) {
var v = t < .5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t;
return (v > 1) ? 1 : v;
}
},
requestAnimFrame = function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
}();
var $wrapper = $('<svg width="' + W + '" height="' + H + '" viewBox="0 0 ' + W + ' ' + H + '" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"></svg>').appendTo($this);
var $groups = [],
$pies = [],
$lightPies = [],
easingFunction = animationOptions[settings.animationEasing],
pieRadius = Min([H / 2, W / 2]) - settings.edgeOffset,
segmentTotal = 0;
//Draw base circle
var drawBasePie = function() {
var base = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
var $base = $(base).appendTo($wrapper);
base.setAttribute("cx", centerX);
base.setAttribute("cy", centerY);
base.setAttribute("r", pieRadius + settings.baseOffset);
base.setAttribute("fill", settings.baseColor);
}();
//Set up pie segments wrapper
var pathGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
var $pathGroup = $(pathGroup).appendTo($wrapper);
$pathGroup[0].setAttribute("opacity", 0);
//Set up tooltip
var $tip = $('<div class="' + settings.tipClass + '" />').appendTo('body').hide(),
tipW = $tip.width(),
tipH = $tip.height();
for (var i = 0, len = data.length; i < len; i++) {
segmentTotal += data[i].value;
var g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
g.setAttribute("data-order", i);
g.setAttribute("class", settings.pieSegmentGroupClass);
$groups[i] = $(g).appendTo($pathGroup);
$groups[i]
.on("mouseenter", pathMouseEnter)
.on("mouseleave", pathMouseLeave)
.on("mousemove", pathMouseMove)
.on("click", pathClick);
var p = document.createElementNS('http://www.w3.org/2000/svg', 'path');
p.setAttribute("stroke-width", settings.segmentStrokeWidth);
p.setAttribute("stroke", settings.segmentStrokeColor);
p.setAttribute("stroke-miterlimit", 2);
p.setAttribute("fill", data[i].color);
p.setAttribute("class", settings.pieSegmentClass);
$pies[i] = $(p).appendTo($groups[i]);
var lp = document.createElementNS('http://www.w3.org/2000/svg', 'path');
lp.setAttribute("stroke-width", settings.segmentStrokeWidth);
lp.setAttribute("stroke", settings.segmentStrokeColor);
lp.setAttribute("stroke-miterlimit", 2);
lp.setAttribute("fill", data[i].color);
lp.setAttribute("opacity", settings.lightPiesOpacity);
lp.setAttribute("class", settings.lightPieClass);
$lightPies[i] = $(lp).appendTo($groups[i]);
}
settings.beforeDraw.call($this);
//Animation start
triggerAnimation();
function pathMouseEnter(e) {
var index = $(this).data().order;
$tip.text(data[index].title + ": " + data[index].value).fadeIn(200);
if ($groups[index][0].getAttribute("data-active") !== "active") {
$lightPies[index].animate({
opacity: .8
}, 180);
}
settings.onPieMouseenter.apply($(this), [e, data]);
}
function pathMouseLeave(e) {
var index = $(this).data().order;
$tip.hide();
if ($groups[index][0].getAttribute("data-active") !== "active") {
$lightPies[index].animate({
opacity: settings.lightPiesOpacity
}, 100);
}
settings.onPieMouseleave.apply($(this), [e, data]);
}
function pathMouseMove(e) {
$tip.css({
top: e.pageY + settings.tipOffsetY,
left: e.pageX - $tip.width() / 2 + settings.tipOffsetX
});
}
function pathClick(e) {
var index = $(this).data().order;
var targetGroup = $groups[index][0];
for (var i = 0, len = data.length; i < len; i++) {
if (i === index) continue;
$groups[i][0].setAttribute("data-active", "");
$lightPies[i].css({
opacity: settings.lightPiesOpacity
});
}
if (targetGroup.getAttribute("data-active") === "active") {
targetGroup.setAttribute("data-active", "");
$lightPies[index].css({
opacity: .8
});
} else {
targetGroup.setAttribute("data-active", "active");
$lightPies[index].css({
opacity: 1
});
}
settings.onPieClick.apply($(this), [e, data]);
}
function drawPieSegments(animationDecimal) {
var startRadius = -PI / 2, //-90 degree
rotateAnimation = 1;
if (settings.animation) {
rotateAnimation = animationDecimal; //count up between0~1
}
$pathGroup[0].setAttribute("opacity", animationDecimal);
//draw each path
for (var i = 0, len = data.length; i < len; i++) {
var segmentAngle = rotateAnimation * ((data[i].value / segmentTotal) * (PI * 2)), //start radian
endRadius = startRadius + segmentAngle,
largeArc = ((endRadius - startRadius) % (PI * 2)) > PI ? 1 : 0,
startX = centerX + cos(startRadius) * pieRadius,
startY = centerY + sin(startRadius) * pieRadius,
endX = centerX + cos(endRadius) * pieRadius,
endY = centerY + sin(endRadius) * pieRadius,
startX2 = centerX + cos(startRadius) * (pieRadius + settings.lightPiesOffset),
startY2 = centerY + sin(startRadius) * (pieRadius + settings.lightPiesOffset),
endX2 = centerX + cos(endRadius) * (pieRadius + settings.lightPiesOffset),
endY2 = centerY + sin(endRadius) * (pieRadius + settings.lightPiesOffset);
var cmd = [
'M', startX, startY, //Move pointer
'A', pieRadius, pieRadius, 0, largeArc, 1, endX, endY, //Draw outer arc path
'L', centerX, centerY, //Draw line to the center.
'Z' //Cloth path
];
var cmd2 = [
'M', startX2, startY2,
'A', pieRadius + settings.lightPiesOffset, pieRadius + settings.lightPiesOffset, 0, largeArc, 1, endX2, endY2, //Draw outer arc path
'L', centerX, centerY,
'Z'
];
$pies[i][0].setAttribute("d", cmd.join(' '));
$lightPies[i][0].setAttribute("d", cmd2.join(' '));
startRadius += segmentAngle;
}
}
var animFrameAmount = (settings.animation) ? 1 / settings.animationSteps : 1, //if settings.animationSteps is 10, animFrameAmount is 0.1
animCount = (settings.animation) ? 0 : 1;
function triggerAnimation() {
if (settings.animation) {
requestAnimFrame(animationLoop);
} else {
drawPieSegments(1);
}
}
function animationLoop() {
animCount += animFrameAmount; //animCount start from 0, after "settings.animationSteps"-times executed, animCount reaches 1.
drawPieSegments(easingFunction(animCount));
if (animCount < 1) {
requestAnimFrame(arguments.callee);
} else {
settings.afterDrawed.call($this);
}
}
function Max(arr) {
return Math.max.apply(null, arr);
}
function Min(arr) {
return Math.min.apply(null, arr);
}
return $this;
};
})(jQuery);
.chart {
position: absolute;
width: 250px;
height: 250px;
top: 100%;
left: 50%;
margin: -225px 0 0 -225px;
}
.pieTip {
position: absolute;
float: left;
min-width: 30px;
max-width: 300px;
padding: 5px 18px 6px;
border-radius: 2px;
background: rgba(255, 255, 255, .97);
color: #444;
font-size: 19px;
text-shadow: 0 1px 0 #fff;
text-transform: uppercase;
text-align: center;
line-height: 1.3;
letter-spacing: .06em;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.5);
-webkit-transform: all .3s;
-moz-transform: all .3s;
-ms-transform: all .3s;
-o-transform: all .3s;
transform: all .3s;
pointer-events: none;
}
.pieTip:after {
position: absolute;
left: 50%;
bottom: -6px;
content: "";
height: 0;
margin: 0 0 0 -6px;
border-right: 5px solid transparent;
border-left: 5px solid transparent;
border-top: 6px solid rgba(255, 255, 255, .95);
line-height: 0;
}
.chart path {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="pieChart" class="chart"></div>
<button>Animate</button>

Tearable Cloth simulation works on Codepen but not locally

I am trying to include this Codepen into a basic website for school.
The issue is that the code with a few tweaks, will not load locally. I have even put my entire website into Codepen as a test and it worked.
It should just be the cloth simulation and nothing else.
Here is the HTML and CSS in its smallest form.
<!doctype html>
<html>
<head>
<style>
body {
background: #2F4F4F;
}
#c {
display: block;
margin: 20px auto 0;
}
</style>
<meta charset="utf-8">
<title>Test</title>
<script type="text/javascript" src="Website/JavaScript/ClothSimulation.js"></script>
</head>
<body>
<canvas id="c"></canvas>
<div id="top">
<a id="close"></a>
</div>
</body>
</html>
The JS is very big as it is a cloth simulation.
document.getElementById('close').onmousedown = function(e) {
e.preventDefault();
document.getElementById('info').style.display = 'none';
return false;
};
// settings
var physics_accuracy = 3,
mouse_influence = 20,
mouse_cut = 5,
gravity = 1200,
cloth_height = 30,
cloth_width = 50,
start_y = 20,
spacing = 7,
tear_distance = 60;
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
var canvas,
ctx,
cloth,
boundsx,
boundsy,
mouse = {
down: false,
button: 1,
x: 0,
y: 0,
px: 0,
py: 0
};
var Point = function(x, y) {
this.x = x;
this.y = y;
this.px = x;
this.py = y;
this.vx = 0;
this.vy = 0;
this.pin_x = null;
this.pin_y = null;
this.constraints = [];
};
Point.prototype.update = function(delta) {
if (mouse.down) {
var diff_x = this.x - mouse.x,
diff_y = this.y - mouse.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y);
if (mouse.button == 1) {
if (dist < mouse_influence) {
this.px = this.x - (mouse.x - mouse.px) * 1.8;
this.py = this.y - (mouse.y - mouse.py) * 1.8;
}
} else if (dist < mouse_cut) this.constraints = [];
}
this.add_force(0, gravity);
delta *= delta;
nx = this.x + ((this.x - this.px) * .99) + ((this.vx / 2) * delta);
ny = this.y + ((this.y - this.py) * .99) + ((this.vy / 2) * delta);
this.px = this.x;
this.py = this.y;
this.x = nx;
this.y = ny;
this.vy = this.vx = 0
};
Point.prototype.draw = function() {
if (!this.constraints.length) return;
var i = this.constraints.length;
while (i--) this.constraints[i].draw();
};
Point.prototype.resolve_constraints = function() {
if (this.pin_x != null && this.pin_y != null) {
this.x = this.pin_x;
this.y = this.pin_y;
return;
}
var i = this.constraints.length;
while (i--) this.constraints[i].resolve();
this.x > boundsx ? this.x = 2 * boundsx - this.x : 1 > this.x && (this.x = 2 - this.x);
this.y < 1 ? this.y = 2 - this.y : this.y > boundsy && (this.y = 2 * boundsy - this.y);
};
Point.prototype.attach = function(point) {
this.constraints.push(
new Constraint(this, point)
);
};
Point.prototype.remove_constraint = function(constraint) {
this.constraints.splice(this.constraints.indexOf(constraint), 1);
};
Point.prototype.add_force = function(x, y) {
this.vx += x;
this.vy += y;
};
Point.prototype.pin = function(pinx, piny) {
this.pin_x = pinx;
this.pin_y = piny;
};
var Constraint = function(p1, p2) {
this.p1 = p1;
this.p2 = p2;
this.length = spacing;
};
Constraint.prototype.resolve = function() {
var diff_x = this.p1.x - this.p2.x,
diff_y = this.p1.y - this.p2.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y),
diff = (this.length - dist) / dist;
if (dist > tear_distance) this.p1.remove_constraint(this);
var px = diff_x * diff * 0.5;
var py = diff_y * diff * 0.5;
this.p1.x += px;
this.p1.y += py;
this.p2.x -= px;
this.p2.y -= py;
};
Constraint.prototype.draw = function() {
ctx.moveTo(this.p1.x, this.p1.y);
ctx.lineTo(this.p2.x, this.p2.y);
};
var Cloth = function() {
this.points = [];
var start_x = canvas.width / 2 - cloth_width * spacing / 2;
for (var y = 0; y <= cloth_height; y++) {
for (var x = 0; x <= cloth_width; x++) {
var p = new Point(start_x + x * spacing, start_y + y * spacing);
x != 0 && p.attach(this.points[this.points.length - 1]);
y == 0 && p.pin(p.x, p.y);
y != 0 && p.attach(this.points[x + (y - 1) * (cloth_width + 1)])
this.points.push(p);
}
}
};
Cloth.prototype.update = function() {
var i = physics_accuracy;
while (i--) {
var p = this.points.length;
while (p--) this.points[p].resolve_constraints();
}
i = this.points.length;
while (i--) this.points[i].update(.016);
};
Cloth.prototype.draw = function() {
ctx.beginPath();
var i = cloth.points.length;
while (i--) cloth.points[i].draw();
ctx.stroke();
};
function update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
cloth.update();
cloth.draw();
requestAnimFrame(update);
}
function start() {
canvas.onmousedown = function(e) {
mouse.button = e.which;
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left,
mouse.y = e.clientY - rect.top,
mouse.down = true;
e.preventDefault();
};
canvas.onmouseup = function(e) {
mouse.down = false;
e.preventDefault();
};
canvas.onmousemove = function(e) {
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left,
mouse.y = e.clientY - rect.top,
e.preventDefault();
};
canvas.oncontextmenu = function(e) {
e.preventDefault();
};
boundsx = canvas.width - 1;
boundsy = canvas.height - 1;
ctx.strokeStyle = '#888';
cloth = new Cloth();
update();
}
window.onload = function() {
canvas = document.getElementById('c');
ctx = canvas.getContext('2d');
canvas.width = 560;
canvas.height = 350;
start();
};
Thank you for your help.
Assuming you have copy and pasted the website exactly how it is, you're missing opening and closing style tags around the CSS, and script tags around the JS.
Your code works, but you need this tags:
<script type="text/javascript"> YOUR JAVASCRIPT HERE </script>
<style type="text/css"> YOUR CSS HERE </style>
/*
Copyright (c) 2013 dissimulate at Codepen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
document.getElementById('close').onmousedown = function(e) {
e.preventDefault();
document.getElementById('info').style.display = 'none';
return false;
};
// settings
var physics_accuracy = 3,
mouse_influence = 20,
mouse_cut = 5,
gravity = 1200,
cloth_height = 30,
cloth_width = 50,
start_y = 20,
spacing = 7,
tear_distance = 60;
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
var canvas,
ctx,
cloth,
boundsx,
boundsy,
mouse = {
down: false,
button: 1,
x: 0,
y: 0,
px: 0,
py: 0
};
var Point = function(x, y) {
this.x = x;
this.y = y;
this.px = x;
this.py = y;
this.vx = 0;
this.vy = 0;
this.pin_x = null;
this.pin_y = null;
this.constraints = [];
};
Point.prototype.update = function(delta) {
if (mouse.down) {
var diff_x = this.x - mouse.x,
diff_y = this.y - mouse.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y);
if (mouse.button == 1) {
if (dist < mouse_influence) {
this.px = this.x - (mouse.x - mouse.px) * 1.8;
this.py = this.y - (mouse.y - mouse.py) * 1.8;
}
} else if (dist < mouse_cut) this.constraints = [];
}
this.add_force(0, gravity);
delta *= delta;
nx = this.x + ((this.x - this.px) * .99) + ((this.vx / 2) * delta);
ny = this.y + ((this.y - this.py) * .99) + ((this.vy / 2) * delta);
this.px = this.x;
this.py = this.y;
this.x = nx;
this.y = ny;
this.vy = this.vx = 0
};
Point.prototype.draw = function() {
if (!this.constraints.length) return;
var i = this.constraints.length;
while (i--) this.constraints[i].draw();
};
Point.prototype.resolve_constraints = function() {
if (this.pin_x != null && this.pin_y != null) {
this.x = this.pin_x;
this.y = this.pin_y;
return;
}
var i = this.constraints.length;
while (i--) this.constraints[i].resolve();
this.x > boundsx ? this.x = 2 * boundsx - this.x : 1 > this.x && (this.x = 2 - this.x);
this.y < 1 ? this.y = 2 - this.y : this.y > boundsy && (this.y = 2 * boundsy - this.y);
};
Point.prototype.attach = function(point) {
this.constraints.push(
new Constraint(this, point)
);
};
Point.prototype.remove_constraint = function(constraint) {
this.constraints.splice(this.constraints.indexOf(constraint), 1);
};
Point.prototype.add_force = function(x, y) {
this.vx += x;
this.vy += y;
};
Point.prototype.pin = function(pinx, piny) {
this.pin_x = pinx;
this.pin_y = piny;
};
var Constraint = function(p1, p2) {
this.p1 = p1;
this.p2 = p2;
this.length = spacing;
};
Constraint.prototype.resolve = function() {
var diff_x = this.p1.x - this.p2.x,
diff_y = this.p1.y - this.p2.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y),
diff = (this.length - dist) / dist;
if (dist > tear_distance) this.p1.remove_constraint(this);
var px = diff_x * diff * 0.5;
var py = diff_y * diff * 0.5;
this.p1.x += px;
this.p1.y += py;
this.p2.x -= px;
this.p2.y -= py;
};
Constraint.prototype.draw = function() {
ctx.moveTo(this.p1.x, this.p1.y);
ctx.lineTo(this.p2.x, this.p2.y);
};
var Cloth = function() {
this.points = [];
var start_x = canvas.width / 2 - cloth_width * spacing / 2;
for (var y = 0; y <= cloth_height; y++) {
for (var x = 0; x <= cloth_width; x++) {
var p = new Point(start_x + x * spacing, start_y + y * spacing);
x != 0 && p.attach(this.points[this.points.length - 1]);
y == 0 && p.pin(p.x, p.y);
y != 0 && p.attach(this.points[x + (y - 1) * (cloth_width + 1)])
this.points.push(p);
}
}
};
Cloth.prototype.update = function() {
var i = physics_accuracy;
while (i--) {
var p = this.points.length;
while (p--) this.points[p].resolve_constraints();
}
i = this.points.length;
while (i--) this.points[i].update(.016);
};
Cloth.prototype.draw = function() {
ctx.beginPath();
var i = cloth.points.length;
while (i--) cloth.points[i].draw();
ctx.stroke();
};
function update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
cloth.update();
cloth.draw();
requestAnimFrame(update);
}
function start() {
canvas.onmousedown = function(e) {
mouse.button = e.which;
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left,
mouse.y = e.clientY - rect.top,
mouse.down = true;
e.preventDefault();
};
canvas.onmouseup = function(e) {
mouse.down = false;
e.preventDefault();
};
canvas.onmousemove = function(e) {
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left,
mouse.y = e.clientY - rect.top,
e.preventDefault();
};
canvas.oncontextmenu = function(e) {
e.preventDefault();
};
boundsx = canvas.width - 1;
boundsy = canvas.height - 1;
ctx.strokeStyle = '#888';
cloth = new Cloth();
update();
}
window.onload = function() {
canvas = document.getElementById('c');
ctx = canvas.getContext('2d');
canvas.width = 560;
canvas.height = 350;
start();
};
#charset "utf-8";
body {
line-height: 1.4;
font-size: 100%;
font-family: allerta;
margin-right: auto;
margin-left: auto;
margin-bottom: 0;
padding: 0;
color: #646464;
font-style: normal;
font-weight: 400;
background-color: #2F4F4F;
}
.center {
margin-bottom: 40px;
display: flex;
justify-content: center;
height: 50px;
padding-top: 132px;
}
.button-wrap {
margin-right: 25px;
top: 133px;
margin-top: -139px;
}
.rad-button {
white-space: nowrap;
border-radius: 4px;
position: relative;
border: none;
background: none;
font-family: allerta;
width: 200px;
height: 200px;
cursor: pointer;
transition: 0.1s all ease;
font-size: 32px;
font-weight: 400;
color: #777;
border-bottom: 1px solid #ccc;
box-shadow: 0px 0px 0px 0px #B8B8B8;
font-style: normal;
}
.rad-button.good {
background-color: #FAEBD7;
color: #2F4F4F;
border-bottom: 1px solid #759f87;
}
.rad-button.good:hover {
background-color: #caf3db;
top: -2px;
border-bottom: 4px solid #759f87;
box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.25);
}
.rad-button.good:active {
top: 0px;
border: 1px solid #759f87;
background-color: #a5dabc;
box-shadow: inset 0px 0px 4px rgba(0, 0, 0, 0.25);
}
.fade {
margin-top: 25px;
font-size: 21px;
text-align: center;
-webkit-animation: fadein 2s; /* Safari, Chrome and Opera > 12.1 */
-moz-animation: fadein 2s; /* Firefox < 16 */
-ms-animation: fadein 2s; /* Internet Explorer */
-o-animation: fadein 2s; /* Opera < 12.1 */
animation: fadein 2s;
}
#keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
/* Firefox < 16 */
#-moz-keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
/* Safari, Chrome and Opera > 12.1 */
#-webkit-keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
/* Internet Explorer */
#-ms-keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
/* Opera < 12.1 */
#-o-keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
ul, ol, dl {
padding: 0;
margin: 0;
}
h1 {
font-size: 200%;
color: #FAEBD7;
font-weight: 400;
font-family: allerta;
font-style: normal;
text-align: center;
margin-left: -26px;
}
h2{
display: table-cell;
text-align: center;
vertical-align: middle;
color: #2F4F4F;
text-shadow: 0px 0px;
font-size: x-large;
}
h3, h4, h5, h6, p {
margin-top: 0;
padding-right: 15px;
padding-left: 15px;
color: #FAEBD7;
font-family: allerta;
font-style: normal;
font-weight: 400;
}
a img {
border: none;
}
a:link {
color: #FAEBD7;
text-decoration: none;
font-family: allerta;
font-style: normal;
font-weight: 400;
}
a:visited {
color: #6E6C64;
text-decoration: underline;
}
a:hover, a:active, a:focus {
text-decoration: none;
color: #CAF3DB;
font-family: allerta;
font-style: normal;
font-weight: 400;
text-align: center;
}
.container {
width: 960px;
background-color: #2F4F4F;
margin: 0 auto;
}
header {
background-color: #2F4F4F;
}
.sidebar1 {
float: right;
width: 180px;
background-color: #2F4F4F;
padding-bottom: 10px;
}
.content {
padding: 10px 0;
width: 780px;
display: inline;
top: 10px;
}
.content ul, .content ol {
padding: 0 15px 15px 40px;
}
nav ul{
list-style: none;
border-top: 1px solid #666;
margin-bottom: 15px;
}
nav li {
border-bottom: 1px solid #666;
}
nav a, nav a:visited {
padding: 5px 5px 5px 15px;
display: block;
width: 160px;
text-decoration: none;
background-color: #2F4F4F;
}
nav a:hover, nav a:active, nav a:focus {
background-color: #2F4F4F;
color: #FFF;
min-width: 0px;
top: 0px;
}
/* ~~ The footer ~~ */
footer {
padding: 10px 0;
background-color: #2F4F4F;
position: relative;
clear: both;
}
header, section, footer, aside, article, figure {
display: block;
color: #FAEBD7;
text-align: center;
left: -14px;
top: 134px;
}
#c {
display: block;
margin: 20px auto 0;
}
<html>
<head>
<meta charset="utf-8">
<title>Ewan Lyon Home</title>
<link href="../CSS/HTML5_twoColFixRtHdr.css" rel="stylesheet" type="text/css"><!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!--The following script tag downloads a font from the Adobe Edge Web Fonts server for use within the web page. We recommend that you do not modify it.-->
<script>var __adobewebfontsappname__="dreamweaver"</script>
<script src="http://use.edgefonts.net/allerta:n4:default.js" type="text/javascript"></script>
</head>
<body>
<div class="container">
<article class="content">
<h1>Ewan Lyon</h1>
<div class = "center">
<div class = "button-wrap">
<button class = "rad-button good flat">Photoshop</button>
</div>
<div class = "button-wrap">
<a href="Illustrator.html">
<button class = "rad-button good flat">Illustrator</button>
</a>
</div>
</div>
<div class = "center">
<div class = "button-wrap">
<button class = "rad-button good flat">About Me</button>
</div>
<div class = "button-wrap">
<button class = "rad-button good flat">RICE</button>
</div>
</div>
<script type="text/javascript" src="../JavaScript/ClothSimulation.js"></script>
<canvas id="c"></canvas>
<div id="top">
<a id="close"></a>
</div>
<footer>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/80x15.png" /></a><br />Ewan Lyon
</footer>
</article>
</div>
</body>
</html>

Removing mousemove

I'm developing an app to help autistic children prepare to learn to write. It's very straight forward. They just need to draw a line straight down. I have it working very similar to "connect the dots" where they start at a green light, progress to yellow and then to red. However, on my webpage using a mouse everything works great because the "dots" are "touched" using the mouseover, like so:
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script src="jquery.min.js" type="text/javascript"></script>
<script src="jquery.jplayer.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
var dots = [13, 15, 13, 25, 13, 55, -1, -1,
45, 15, 45, 40, -1, -1,
70, 15, 70, 40, -1, -1,
80, 15, 80, 40, 80, 60, -1, -1];
function contains(arr, value) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] == value) {
return true;
}
}
return false;
}
function getRandomPoints(totalPoints) {
var indexes = new Array();
for (var i = 0; i < totalPoints; i++) {
var done = false;
while (!done) {
var index = Math.floor(Math.random() * dots.length);
if (index % 2 != 0) {
index++;
if (index > dots.length) {
continue;
}
}
if (!contains(indexes, index)) {
indexes.push(index);
done = true;
}
}
}
return indexes.sort(function(a, b) {
return a - b;
});
}
function displayGrid(ctx) {
var gridSize = 20, width = 900;
for (var ypos = 0; ypos < width; ypos += gridSize) {
ctx.moveTo(0, ypos);
ctx.lineTo(width, ypos);
}
for (var xpos = 0; xpos < width; xpos += gridSize) {
ctx.moveTo(xpos, 0);
ctx.lineTo(xpos, width);
}
ctx.strokeStyle = "#eee";
ctx.lineWidth = .7;
ctx.stroke();
}
function addPoint(index, x1, y1) {
for (var i = 0; i < points.length; i++) {
var x2 = points[i].x, y2 = points[i].y;
var d1 = Math.sqrt(Math.pow(y2 - y1, 2) + Math.pow(x2 - x1, 2));
var d2 = radius * 2 + 2;
if (d2 > d1) {
return false;
}
}
points.push({ 'x': x1, 'y': y1, 'index': index });
return true;
}
//Initialization....
var $graph = $('#graph'), gpos = $graph.position();
var $timer = $('#timer');
var points = new Array();
var ctx = $graph.get(0).getContext("2d");
//Parameters...
var indexes = getRandomPoints(7), ratio = 3, hops = 0, point = 0, maxTotalHops = 60, radius = 12;
var lineWidth = 11.5;
var xDisplacement = 0, yDisplacement = 0;
var borderColor = 'rgb(0,102,204)';
//Display the character's fixed lines...
ctx.beginPath();
ctx.translate(xDisplacement, yDisplacement);
ctx.lineWidth = lineWidth;
for (var i = 0; i < dots.length; i += 2) {
var newLine = dots[i] == -1;
if (newLine) {
i += 2;
}
var x = ratio * dots[i], y = ratio * dots[i + 1];
if (hops == 0 && contains(indexes, i)) {
hops++;
ctx.moveTo(x, y);
continue;
}
if (newLine || i == 0) {
ctx.moveTo(x, y);
}
else {
if (hops == 0) {
ctx.lineTo(x, y);
}
else {
ctx.strokeStyle = borderColor;
ctx.stroke();
ctx.beginPath();
if (addPoint(i, x, y)) {
var cx = gpos.left + xDisplacement - radius + 1 + x;
var cy = gpos.top + yDisplacement - radius + 1 + y;
$('<span></span>')
.addClass('circle')
.html(++point)
.data('pos', { 'x': cx, 'y': cy })
.css({ 'top': 0, 'left': 0 })
.insertAfter($graph);
}
}
}
if (hops > maxTotalHops) {
hops = 0;
}
else if (hops > 0) {
hops++;
}
}
ctx.strokeStyle = borderColor;
ctx.stroke();
//Create and initialize hotspots...
var passed = 0;
$('.circle').each(function() {
var pos = $(this).data('pos');
$(this).animate({
left: pos.x,
top: pos.y
}, 700);
}).mousemove(function() { // <====================== this part
var index = parseInt($(this).text());
if (passed != index - 1) {
return;
}
$(this).css({
'color': '#c00',
'font-weight': 'bold'
}).animate({
left: 0,
top: 0,
opacity: 0
}, 1000);
ctx.beginPath();
var start, end, done = passed + 1 == points.length;
if (done) /*The entire hotspots are detected...*/{
start = 0;
end = dots.length - 2;
clearInterval(tid);
$timer.html('Well done, it took ' + $timer.html() + ' seconds!').animate({
left: gpos.left + $graph.width() - $timer.width() - 20
}, 1000);
}
else {
start = passed == 0 ? points[passed].index - 4 : points[passed - 1].index;
end = points[passed].index;
}
for (var i = start; i <= end; i += 2) {
var newLine = dots[i] == -1;
if (newLine) {
i += 2;
}
var x = ratio * dots[i], y = ratio * dots[i + 1];
if (newLine || i == start) {
ctx.moveTo(x, y);
}
else {
ctx.lineTo(x, y);
}
}
ctx.lineWidth = lineWidth;
ctx.strokeStyle = borderColor;
ctx.stroke();
if (done) {
$('.filled').css({
left: gpos.left + xDisplacement + 10,
top: gpos.top + yDisplacement + 150
}).fadeIn('slow');
}
passed++;
});
//Initialize timer...
$timer.css({
top: gpos.top + 10,
left: gpos.left + 10
});
var timer = 0, tid = setInterval(function() {
timer += 30 / 1000;
$timer.html(timer.toFixed(2));
}, 30);
});
</script>
<style type="text/css">
.circle {
background: url('start.png');
width: 24px;
height: 24px;
text-align: center;
font-size: .8em;
line-height: 24px;
display: block;
position: absolute;
cursor: pointer;
color: #333;
z-index: 100;
}
.filled {
background: url('train.gif');
position: absolute;
width: 172px;
height: 251px;
display: none;
}
#timer {
position: absolute;
font-family: Arial;
font-weight: bold;
font-size: 1em;
background: #c00;
color: #fff;
padding: 5px;
text-align: center;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
font-variant: small-caps;
}
#graph {
background: url('vlinesbackground.jpg');
left: 5px;
top: 20px;
position: relative;
border: 1px dotted #ddd;
}
</style>
But I'm trying to replace the mousemove so the app can be used on the iphone. I've worked out everything else but triggering the "dots" and although I've looked at all the touchstart/touchmove info I can google, nothing appears to be working. Suggestions? Thanks!

Categories