Raphael: how do you change properties during an animation? - javascript

I don't know if this is possible but it seems like the sort of thing that should be possible - somehow. What I want to do is change the property of an object while that object is being animated.
Consider a simple example of a clockface with a ticking and animated seconds hand. If the clockface can be freely rotated by the user I would want the second had to follow the rotation while it is being animated between ticks.
Some code that illustrates what I am trying to do:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.10.3.custom.js"></script>
<script type="text/javascript" src="js/jquery.cookie.js"></script>
<script type="text/javascript" src="js/raphael.js"></script>
<script>
$(document).ready(function(){
var paper = Raphael("Display", $("#Display").width(), $("#Display").height());
var centreX = $("#Display").width() / 2;
var centreY = $("#Display").height() / 2;
var radius = 0.9 * Math.min($("#Display").height(), $("#Display").width()) / 2;
var rotation = 0;
var seconds = 0;
var s = "M"+centreX+","+centreY+"L"+centreX+","+(centreY-0.8*radius);
var pointer = paper.path(s);
clockface = paper.set();
for(i=1; i<=12; i++) {
sn=Math.sin(i * 30 * Math.PI / 180);
cs=Math.cos(i * 30 * Math.PI / 180);
t = paper.text(centreX+(0.9*sn*radius), centreY-(0.9*cs*radius), i).attr({"font-size":28});
clockface.push(t);
}
// Non-animated tick every second
// setInterval(function() {
// seconds += 1;
// pointer.transform("r" + (seconds * 6 + rotation) + " " + centreX + " " + centreY);
// }, 1000);
// Animated Tick every 5 seconds
setInterval(function() {
seconds += 5;
pointer.animate({transform: "r" + (seconds * 6 + rotation) + " " + centreX + " " + centreY}, 3000, "backIn");
}, 5000);
$("#Display").mousemove(function(pos) {
rotation = pos.pageX * 360 / 500;
clockface.transform("r" + rotation + "," + centreX + "," + centreY);
pointer.transform("r" + (seconds * 6 + rotation) + " " + centreX + " " + centreY);
});
});
</script>
</head>
<body>
<div id="Display" style="width: 500px; height: 500px;">
</div>
</body>
</html>
While the clock is ticking away wave the mouse over the clockface to rotate it. You will see that the seconds hand does not follow the rotation during the animation. I had thought that I would be able to do this by adding the hand into the set and rotating the whole set while the hand is being animated but that just resets the hand's position.
Is it possible to get to what I am trying tho acheive?

Related

How to make onmouseover happen multiple times

var color2;
var color3;
var color1;
var interval;
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
function ColorEverySecond(id){
interval = setInterval(changeColor(id),500);
}
function stopColorEverySecond(){
clearInterval(interval)
}
function changeColor(id){
color1 = getRandomInt(255);
color2 = getRandomInt(255);
color3 = getRandomInt(255);
document.getElementById(id).style = "color: rgb(" + color1 + ", " + color2 + ", " + color3 + ")";
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1 id = "rainbow" onmouseover="ColorEverySecond(id)" onmouseout="stopColorEverySecond()">
When you hover I should change colors every 500 milliseconds, but instead I just change everytime you hover.
</h1>
</body>
</html>
For some reason it won't change color every 500 milliseconds and instead only changes once when you hover. I noticed that it only activates the function 'changeColor' once in the interval and then it stops.
I tried to replicate solutions from this post but they did not work for me. I think it has to with the 'changeColor' function but I do not see the problem. How do I fix it?
You are calling the function instead of passing it as argument for the setInterval. Use this syntax:
var color2;
var color3;
var color1;
var interval;
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
function ColorEverySecond(id) {
interval = setInterval(function() {
changeColor(id)
}, 500);
// also right away
changeColor(id)
}
function stopColorEverySecond() {
clearInterval(interval)
}
function changeColor(id) {
color1 = getRandomInt(255);
color2 = getRandomInt(255);
color3 = getRandomInt(255);
document.getElementById(id).style = "color: rgb(" + color1 + ", " + color2 + ", " + color3 + ")";
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1 id="rainbow" onmouseover="ColorEverySecond(id)" onmouseout="stopColorEverySecond()">
When you hover I should change colors every 500 milliseconds, but instead I just change everytime you hover.
</h1>
</body>
</html>
You faced this problem because of setInterval. setInterval receives a callback. But directly call the changeColor function. As you have to call the changeColor function here that's why you have to use a callback here. Hope you understand.
var color2;
var color3;
var color1;
var interval;
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
function ColorEverySecond(id){
interval = setInterval(()=> changeColor(id), 500);
}
function stopColorEverySecond(){
clearInterval(interval)
}
function changeColor(id){
color1 = getRandomInt(255);
color2 = getRandomInt(255);
color3 = getRandomInt(255);
document.getElementById(id).style = "color: rgb(" + color1 + ", " + color2 + ", " + color3 + ")";
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1 id = "rainbow" onmouseover="ColorEverySecond(id)" onmouseout="stopColorEverySecond()">
When you hover I should change colors every 500 milliseconds, but instead I just change everytime you hover.
</h1>
</body>
</html>
var color2;
var color3;
var color1;
var interval;
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
function ColorEverySecond(id){
interval = setInterval(changeColor,500,id);
}
function stopColorEverySecond(){
clearInterval(interval)
}
function changeColor(id){
color1 = getRandomInt(255);
color2 = getRandomInt(255);
color3 = getRandomInt(255);
document.getElementById(id).style = "color: rgb(" + color1 + ", " + color2 + ", " + color3 + ")";
}
<!DOCTYPE html> <html>
<head>
</head> <body>
<h1 id = "rainbow" onmouseover="ColorEverySecond(id)" onmouseout="stopColorEverySecond()"> When you hover I change colors every 500 milliseconds.
</h1>
</body>
</html>
The Answer

How is it that these squares only translate once instead of multiple times within the setInterval?

var initialCircle;
var i;
var randomXPos;
var randomYPos;
var colorArray;
var interval01;
var circleNodeList;
var circleNodeListIndividual;
var xDirection = 5;
var yDirection = 5;
var dX = xDirection + 5;
var dY = yDirection + 5;
colorArray = [
'aliceblue', 'lavender', 'powderblue', 'lightblue', 'lightskyblue', 'skyblue', 'deepskyblue', 'lightsteelblue', 'dodgerblue', 'cornflowerblue', 'steelblue', 'cadetblue', 'mediumslateblue', 'slateblue', 'darkslateblue', 'royalblue', 'blue', 'mediumblue', 'darkblue', 'navy', 'midnightblue', 'blueviolet', 'indigo'
];
var randomColor;
function startBouncingHoverCircles() {
interval01 = setInterval(function() {
randomXPos = Math.floor(Math.random() * 380) + 31;
randomYPos = Math.floor(Math.random() * 235) + 31;
randomColor = colorArray[Math.floor(Math.random() * colorArray.length)];
initialCircle = document.createElement('div');
document.querySelector("#container").appendChild(initialCircle);
initialCircle.className = "aces";
initialCircle.style = 'height:30px;width:30px;border-radius:50%;box-sizing:border-box;position:absolute;border:3px solid green;background-color:' + randomColor;
initialCircle.style.top = randomYPos + 'px';
initialCircle.style.left = randomXPos + 'px';
}, 1);
setTimeout(function() {
clearInterval(interval01);
movement()
}, 100)
}
function movement() {
setInterval(function() {
circleNodeList = document.querySelectorAll(".aces");
for (i = 0; i < circleNodeList.length; i++) {
circleNodeListIndividual = circleNodeList[i];
circleNodeListIndividual.style.transition = "transform 1s";
circleNodeListIndividual.style.transform = 'translate(' + dX + 'px' + ',' + dY + 'px' + ')'
}
}, 1500)
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/randomcolor/0.6.1/randomColor.min.js" integrity="sha512-vPeZ7JCboHcfpqSx5ZD+/jpEhS4JpXxfz9orSvAPPj0EKUVShU2tgy7XkU+oujBJKnWmu4hU7r9MMQNWPfXsYw==" crossorigin="anonymous"></script>
<style>
#container {
width: 450px;
height: 300px;
position: relative;
border: 1px solid black;
margin: auto;
}
</style>
</head>
<body>
<button onClick="startBouncingHoverCircles()">Start</button>
<div id="container"></div>
<script src="../Js/bouncingHoverCircles.js"></script>
</body>
</html>
I am trying to have these balls bounce off the walls and reverse direction when they hit a wall. the first step is setting up an interval for them to continue to animate across the screen. I am trying to accomplish this without the implementation of a canvas. Any help as to why the interval only runs one time would be awesome. Thanks
Your setInterval runs OK.
The problem is that you always put the circles again at the same point. When you do 'translate(' + dX + 'px' + ',' + dY + 'px' + ')' - The dX and dY are not added to the current location of the circle. They are used as the new location (which always stays 10px.)
2 options for solution:
Increase dX and dY every time you call movement().
Probably better solution: When you set the transform property in your element - Sum the current location with the dX and dY. Code to do that:
Add the next variable before you set the transform in the movement function:
const matrix = new WebKitCSSMatrix(circleNodeListIndividual.style.transform);
then use it in setting the transform:
circleNodeListIndividual.style.transform = 'translate(' + (matrix.m41 + dX) + 'px' + ',' + (matrix.m42 + dY) + 'px' + ')'

storing high score with javascript

I have practiced one question and this is about checking time to click the shape that comes up. I want to save the the high score and compare with the next one coming up. It is just how to store the high score . It would be great help if somebody give the way to do it. Thank you in advance
<!doctype html>
<html>
<head>
<title> Javasript </title>
<style type="text/css">
#shape {
width: 200px;
height: 200px;
display:none;
position : relative;
}
</style>
</head>
<body>
<h1>Test your reaction </h1>
<p>Click on the boxes as soon as possible and win it </p>
<p>Your time taken <span id="timeTaken"></span></p>
<div id="shape"></div>
<script type="text/javascript">
var start = new Date().getTime();
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
function makeShapeAppear() {
var top = Math.random() * 400 ;
var left = Math.random() * 400 ;
var width = (Math.random() * 200) + 100 ;
if (Math.random()> 0.5) {
document.getElementById("shape").style.borderRadius = "50%";
} else {
document.getElementById("shape").style.borderRadius = "0%"; }
document.getElementById("shape").style.backgroundColor = getRandomColor();
document.getElementById("shape").style.height = top + 'px';
document.getElementById("shape").style.width = width + 'px';
document.getElementById("shape").style.top = top + 'px';
document.getElementById("shape").style.left = left + 'px';
document.getElementById("shape").style.height = top + 'px';
document.getElementById("shape").style.display = 'block';
start = new Date().getTime();
}
function appearAfterDelay() {
setTimeout(makeShapeAppear, Math.random() * 2000 );
}
appearAfterDelay();
document.getElementById("shape").onclick = function() {
document.getElementById("shape").style.display = 'none';
var end = new Date().getTime();
var timeTaken = (end - start)/1000;
document.getElementById("timeTaken").innerHTML = timeTaken + "s";
appearAfterDelay();
}
</script>
</body>
</html>

Change div width every 1 second by 5px

I tried to change div width every 1 second by 5px using JavaScript. How can I make this work?
Here's my code:
<html>
<head>
<title>JS Functions</title>
</head>
<body>
<div style="width:100px; height:100px; background:gray" id="box" onclick="bigger()"></div>
<script>
function bigger()
{
var w = 100
var h = 100
while(w < 1000, h < 1000)
{
w = w+5;
h = h+5;
document.getElementById('box').style.width = w
document.getElementById('box').style.height = h
setInterval();
}
}
</script>
</body>
</html>
No while loop needed. You can just use setInterval:
var w = 100;
var h = 100;
var foo = setInterval(function () {
if(w>1000) cancelInterval(foo)
w = w + 5;
h = h + 5;
document.getElementById('box').style.width = w + 'px';
document.getElementById('box').style.height = h + 'px';
}, 1000);
<div style="width:100px; height:100px; background:gray" id="box" onclick="bigger()"></div>
You need to use setInterval to call your code every second, so move it outside of the bigger() function. Also you need the full value for style, including the unit you're using.
try this
<html>
<head>
<title>JS Functions</title>
</head>
<body>
<div style="width:100px; height:100px; background:gray" id="box"></div>
<script>
var w = 100;
var h = 100;
function bigger()
{
if (w < 1000 && h < 1000)
{
w = w+5;
h = h+5;
document.getElementById('box').style.width = w + 'px';
document.getElementById('box').style.height = h + 'px';
} else {
clearInterval(int);
}
}
var int = setInterval(bigger, 1000);
</script>
</body>
</html>
Let's say you have a div wth id='boxToEnlarge'
The JSFiddle: http://jsfiddle.net/7qtb1u8e/1/
And this is the actual code:
function enlargeBox(){
//get current size
var currentWidth = document.getElementById('boxToEnlarge').offsetWidth;
var currentHeight = document.getElementById('boxToEnlarge').offsetHeight;
//add 5 more pixels to current size
document.getElementById('boxToEnlarge').style.width = currentWidth + 5 +'px';
document.getElementById('boxToEnlarge').style.height = currentHeight + 5 +'px';
}
//call the enlargeBox func every 1 sec (1000 milliseconds)
setInterval(function(){enlargeBox()},1000);
We are reading the current size of the div we want to enlarge then we add 5px to that amount and apply it on it's width/height CSS properties.
We wrap the above in a function and using setInterval, we call that function once every n milliseconds, in this case 1000ms which equals 1 second

Nested for loops won't evaluate

I'm making an javascript image converter, just a proof of concept(I know there are another better languages for doing it). My problem is that in the loop section I'm doing some variables don't evaluate to the ones that are in the function loops. The code should work this way:
The HTML button activates the parent function.
Some variables are stated.
The loop that should make a nice gradient all over the and those I'm having trouble with are defined.
A function that triggers the loops in intervals is stated, with some other counter variables.e
I think the problem is in the counter variables I use on the loop() but I can't figure them out.
Here is all my code:
<!DOCTYPE html>
<html>
<head>
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CPBitmap to PNG</title>
<style>
#canvas {
width:512px;
height:384px;
background-color:black;
}
</style>
<script>
function convertir(){
var y =0;
vertC = 10;
var pixelConverter = function(){
for(;y<vertC;y++){
for(var x=0; x<2048;x++){
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var pixel = "rgb(" + y + "," + vertC + "," + x + ")";
ctx.fillStyle = pixel;
ctx.fillRect(x,y,100,100);
}
}
}
intervalos = setInterval(loops,1);
function loops(){
pixelConverter();
vertC = vertC + 10;
console.log("Y= " + y + "Linea " + vertC );
y = y + 10;
x = 0;
console.log(x);
if(x > 2047 && y > 1535)intervalos=window.clearInterval(intervalos);
else pixelConverter();
}
}
</script>
</head>
<body>
<input type="file" id="input" name="file" />
<button onclick=convertir() >¡Convertir!</button>
<button onclick="intervalos=window.clearInterval(intervalos)">Alto</button>
<canvas id="canvas" width="2048px" height="1536px"></canvas>
<div id="Hola"></div>
</body>
</html>

Categories