Adding click event on a specific div with JavaScript - javascript

I have a snowfall effect in JavaScript, I want the create a click event on the 10th snowflake that falls down. I would also like to add a Class that says "clickable". We want to achieve this, so if user clicks the 10th snowflake only, then they will be redirected to a prize (we also want to add a Class so we can style this nicely via CSS).
I must admit, my JavaScript knowledge isn't as strong as my jQuery, so could someone please help? Here is the codepen that I am using:-
https://codepen.io/scottYg55/pen/GRRzOgO
#snowflakeContainer {
position: absolute;
left: 0px;
top: 0px;
bottom: 0;
right: 0;
background-color: #2c3e50;
}
.snowflake {
padding-left: 15px;
font-family: Cambria, Georgia, serif;
font-size: 14px;
line-height: 24px;
position: fixed;
color: #FFFFFF;
user-select: none;
z-index: 1000;
}
<div id="snowflakeContainer">
<p class="snowflake">*</p>
</div>
JS
// The star of every good animation
var requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
var transforms = ["transform",
"msTransform",
"webkitTransform",
"mozTransform",
"oTransform"];
var transformProperty = getSupportedPropertyName(transforms);
// Array to store our Snowflake objects
var snowflakes = [];
// Global variables to store our browser's window size
var browserWidth;
var browserHeight;
// Specify the number of snowflakes you want visible
var numberOfSnowflakes = 50;
// Flag to reset the position of the snowflakes
var resetPosition = false;
//
// It all starts here...
//
function setup() {
window.addEventListener("DOMContentLoaded", generateSnowflakes, false);
window.addEventListener("resize", setResetFlag, false);
}
setup();
//
// Vendor prefix management
//
function getSupportedPropertyName(properties) {
for (var i = 0; i < properties.length; i++) {
if (typeof document.body.style[properties[i]] != "undefined") {
return properties[i];
}
}
return null;
}
//
// Constructor for our Snowflake object
//
function Snowflake(element, radius, speed, xPos, yPos) {
// set initial snowflake properties
this.element = element;
this.radius = radius;
this.speed = speed;
this.xPos = xPos;
this.yPos = yPos;
// declare variables used for snowflake's motion
this.counter = 0;
this.sign = Math.random() < 0.5 ? 1 : -1;
// setting an initial opacity and size for our snowflake
this.element.style.opacity = .1 + Math.random();
this.element.style.fontSize = 12 + Math.random() * 50 + "px";
}
//
// The function responsible for actually moving our snowflake
//
Snowflake.prototype.update = function () {
// using some trigonometry to determine our x and y position
this.counter += this.speed / 5000;
this.xPos += this.sign * this.speed * Math.cos(this.counter) / 40;
this.yPos += Math.sin(this.counter) / 40 + this.speed / 30;
// setting our snowflake's position
setTranslate3DTransform(this.element, Math.round(this.xPos), Math.round(this.yPos));
// if snowflake goes below the browser window, move it back to the top
if (this.yPos > browserHeight) {
this.yPos = -50;
}
}
//
// A performant way to set your snowflake's position
//
function setTranslate3DTransform(element, xPosition, yPosition) {
var val = "translate3d(" + xPosition + "px, " + yPosition + "px" + ", 0)";
element.style[transformProperty] = val;
}
//
// The function responsible for creating the snowflake
//
function generateSnowflakes() {
// get our snowflake element from the DOM and store it
var originalSnowflake = document.querySelector(".snowflake");
// access our snowflake element's parent container
var snowflakeContainer = originalSnowflake.parentNode;
// get our browser's size
browserWidth = document.documentElement.clientWidth;
browserHeight = document.documentElement.clientHeight;
// create each individual snowflake
for (var i = 0; i < numberOfSnowflakes; i++) {
// clone our original snowflake and add it to snowflakeContainer
var snowflakeCopy = originalSnowflake.cloneNode(true);
snowflakeContainer.appendChild(snowflakeCopy);
// set our snowflake's initial position and related properties
var initialXPos = getPosition(50, browserWidth);
var initialYPos = getPosition(50, browserHeight);
var speed = 5+Math.random()*40;
var radius = 4+Math.random()*10;
// create our Snowflake object
var snowflakeObject = new Snowflake(snowflakeCopy,
radius,
speed,
initialXPos,
initialYPos);
snowflakes.push(snowflakeObject);
}
// remove the original snowflake because we no longer need it visible
snowflakeContainer.removeChild(originalSnowflake);
// call the moveSnowflakes function every 30 milliseconds
moveSnowflakes();
}
//
// Responsible for moving each snowflake by calling its update function
//
function moveSnowflakes() {
for (var i = 0; i < snowflakes.length; i++) {
var snowflake = snowflakes[i];
snowflake.update();
}
// Reset the position of all the snowflakes to a new value
if (resetPosition) {
browserWidth = document.documentElement.clientWidth;
browserHeight = document.documentElement.clientHeight;
for (var i = 0; i < snowflakes.length; i++) {
var snowflake = snowflakes[i];
snowflake.xPos = getPosition(50, browserWidth);
snowflake.yPos = getPosition(50, browserHeight);
}
resetPosition = false;
}
requestAnimationFrame(moveSnowflakes);
}
//
// This function returns a number between (maximum - offset) and (maximum + offset)
//
function getPosition(offset, size) {
return Math.round(-1*offset + Math.random() * (size+2*offset));
}
//
// Trigger a reset of all the snowflakes' positions
//
function setResetFlag(e) {
resetPosition = true;
}
Thank you in advance for your help!
Greatly appreciated

When generating the snowflakes, try to catch the 10th one and apply what you want
...
function generateSnowflakes() {
...
// create each individual snowflake
for (var i = 0; i < numberOfSnowflakes; i++) {
// clone our original snowflake and add it to snowflakeContainer
var snowflakeCopy = originalSnowflake.cloneNode(true);
snowflakeContainer.appendChild(snowflakeCopy);
// <------------------------------------------>
// catch the tenth snowflake and add your changes here
if (i === 9) {
snowflakeCopy.classList.add("clickable");
snowflakeCopy.addEventListener("click",function (e) {
//the stuff you want to do
//when the 10th snowflake is clicked
// for example :
window.location.replace("URL/OF/PRIZE");
})
}
....
}
...
```

Related

How to change the img of a cloned div onClick

Right now I have a lovely code (that was initially for flowing snowflakes) that lets cloned divs fall from the top of the window, to the bottom and repeat. The thing is that I want the content to change on click. However, this is not yet working.
I know how to change content of a div without it being cloned, but I have serious trouble figuring out how to do the same with one div being cloned within the code.
Anyone have any tips what I should do, even a hint in which direction to go. I'm clueless.
This is the fiddle:
http://jsfiddle.net/4yaxvt7h/
the javascript:
function changeImage(){
document.getElementById('toChange').src='https://i.pinimg.com/originals/6e/19/56/6e195649034f042d1dea5230234570a8.gif';
}
// Array to store our Snowflake objects
var snowflakes = [];
// Global variables to store our browser's window size
var browserWidth;
var browserHeight;
// Specify the number of snowflakes you want visible
var numberOfSnowflakes = 15;
// Flag to reset the position of the snowflakes
var resetPosition = false;
// Handle accessibility
var enableAnimations = false;
var reduceMotionQuery = matchMedia("(prefers-reduced-motion)");
// Handle animation accessibility preferences
function setAccessibilityState() {
if (reduceMotionQuery.matches) {
enableAnimations = false;
} else {
enableAnimations = true;
}
}
setAccessibilityState();
reduceMotionQuery.addListener(setAccessibilityState);
//
// It all starts here...
//
function setup() {
if (enableAnimations) {
window.addEventListener("DOMContentLoaded", generateSnowflakes, false);
window.addEventListener("resize", setResetFlag, false);
}
}
setup();
//
// Constructor for our Snowflake object
//
function Snowflake(element, speed, xPos, yPos) {
// set initial snowflake properties
this.element = element;
this.speed = speed;
this.xPos = xPos;
this.yPos = yPos;
this.scale = 1;
// declare variables used for snowflake's motion
this.counter = 0;
this.sign = Math.random() < 0.5 ? 1 : -1;
// setting an initial opacity and size for our snowflake
this.element.style.opacity = 1;
}
//
// The function responsible for actually moving our snowflake
//
Snowflake.prototype.update = function () {
// using some trigonometry to determine our x and y position
this.counter += this.speed / 5000;
this.xPos += this.sign * this.speed * Math.cos(this.counter) / 40;
this.yPos += Math.sin(this.counter) / 40 + this.speed / 30;
this.scale = .5 + Math.abs(10 * Math.cos(this.counter) / 20);
// setting our snowflake's position
setTransform(Math.round(this.xPos), Math.round(this.yPos), this.scale, this.element);
// if snowflake goes below the browser window, move it back to the top
if (this.yPos > browserHeight) {
this.yPos = -50;
}
}
//
// A performant way to set your snowflake's position and size
//
function setTransform(xPos, yPos, scale, el) {
el.style.transform = `translate3d(${xPos}px, ${yPos}px, 0) scale(${scale}, ${scale})`;
}
//
// The function responsible for creating the snowflake
//
function generateSnowflakes() {
// get our snowflake element from the DOM and store it
var originalSnowflake = document.querySelector(".snowflake");
// access our snowflake element's parent container
var snowflakeContainer = originalSnowflake.parentNode;
snowflakeContainer.style.display = "block";
// get our browser's size
browserWidth = document.documentElement.clientWidth;
browserHeight = document.documentElement.clientHeight;
// create each individual snowflake
for (var i = 0; i < numberOfSnowflakes; i++) {
// clone our original snowflake and add it to snowflakeContainer
var snowflakeClone = originalSnowflake.cloneNode(true);
snowflakeContainer.appendChild(snowflakeClone);
// set our snowflake's initial position and related properties
var initialXPos = getPosition(50, browserWidth);
var initialYPos = getPosition(50, browserHeight);
var speed = 5 + Math.random() * 40;
// create our Snowflake object
var snowflakeObject = new Snowflake(snowflakeClone,
speed,
initialXPos,
initialYPos);
snowflakes.push(snowflakeObject);
}
// remove the original snowflake because we no longer need it visible
snowflakeContainer.removeChild(originalSnowflake);
moveSnowflakes();
}
//
// Responsible for moving each snowflake by calling its update function
//
function moveSnowflakes() {
if (enableAnimations) {
for (var i = 0; i < snowflakes.length; i++) {
var snowflake = snowflakes[i];
snowflake.update();
}
}
// Reset the position of all the snowflakes to a new value
if (resetPosition) {
browserWidth = document.documentElement.clientWidth;
browserHeight = document.documentElement.clientHeight;
for (var i = 0; i < snowflakes.length; i++) {
var snowflake = snowflakes[i];
snowflake.xPos = getPosition(50, browserWidth);
snowflake.yPos = getPosition(50, browserHeight);
}
resetPosition = false;
}
requestAnimationFrame(moveSnowflakes);
}
//
// This function returns a number between (maximum - offset) and (maximum + offset)
//
function getPosition(offset, size) {
return Math.round(-1 * offset + Math.random() * (size + 2 * offset));
}
//
// Trigger a reset of all the snowflakes' positions
//
function setResetFlag(e) {
resetPosition = true;
}
html
<div id="snowflakeContainer">
<div class="snowflake"><img src="element1.png"
</div>
css
body{
background-color: black;
}
#snowflakeContainer {
position: absolute;
left: 0px;
top: 0px;
display: none;
}
.snowflake {
position: fixed;
background-color: red;
user-select: none;
z-index: 1000;
pointer-events: none;
border-radius: 50%;
width: 200px;
height: 200px;
}
img{
max-width: 100%;
}
any tips are super welcome!!
You have several different problems here. First, your CSS sets pointer-events: none; for all .snowflake elements. This will stop any clicks from triggering, so you have to remove it if you want mouse interactivity.
Second, your changeImage() function uses document.getElementById('toChange') to get the element to change the source of. No such element exists and even if it did, that would mean that clicking on any of the snowflakes would just change the source of that one image. You need to reference the snowflake that you clicked on. An easy way to do this is by passing this as an argument to the function in the onclick attribute:
HTML:
<div class="snowflake"><img src="https://vignette.wikia.nocookie.net/dragonballfanon/images/7/70/Random.png/revision/latest?cb=20161221030547" onclick="changeImage(this)"></div>
JS:
function changeImage(img) {
img.src = 'https://i.pinimg.com/originals/6e/19/56/6e195649034f042d1dea5230234570a8.gif';
}
Finally, your JSFiddle is configured to delay execution of the JavaScript until after the DOM is ready. This means that the code will be wrapped in a callback function, and therefore the changeImage() function will no longer be in the global scope. This makes it inaccessible to the elements that want to call it in their handlers (the snowflakes). Because you are already listening for the DOMContentLoaded event on your own, you can just change the code to execute normally and it should work. Click on the dropdown that says "JavaScript + jQuery 3.2.1" above your JS code and change the load type to any "No wrap" option and it should work.

Paperjs bounce animation

Theres some wierd behaviour when playing with Paperjs, i was trying to curve a line up with 7 points separately - which works fine once, but when trying to make the link overshoot and return to 3 different points (to create a bounce effect) doesn't seem to play ball. On the second if statement, the 'counter' variable doesnt seem to increase instead of decrease, '+ steps' instead of '- steps'.
Maybe i'm not using if statements properly in this case, or paperjs has some strange behaviour?
Heres the codepen for it in full, click above the blue line to trigger it off. . Following is one setInterval for one of the points of the segment.
var seg6first = true;
var seg6sec = false;
var seg6thir = false;
setInterval(function() {
if (seg6first == true) {
counter = counter - steps;
if (counter >= 230) {
path.segments[6].point.y = counter;
path.smooth(); }
else {
seg6first = false;
seg6sec = true;
}
}
if (seg6sec == true) {
counter = counter + steps;
if (counter <= 260) {
path.segments[6].point.y = counter;
path.smooth();}
else {
seg6sec = false;
seg6thir = true;
}
}
if (seg6sec == true) {
counter = counter - steps;
if (counter >= 250) {
path.segments[6].point.y = counter;
path.smooth(); }
else {
seg6thir = false;
}
}
}, mintiming);
Thanks!
Rather than manually building your bounce effect, you can use an animation library like GSAP.
It has a lot of features that will make your task easier (see easing documentation).
Here is an example of what you are trying to do (click on the canvas to animate the line).
html,
body {
margin: 0;
overflow: hidden;
height: 100%;
}
canvas[resize] {
width: 100%;
height: 100%;
}
<canvas id="canvas" resize></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.11.8/paper-full.min.js"></script>
<script type="text/paperscript" canvas="canvas">
// user defined constants
var SEGMENTS_COUNT = 6;
var CURVE_HEIGHT = 80;
var ANIMATION_DURATION = 2;
// init path
var path = new Path({
fillColor: 'orange',
selected: true
});
// add points
for (var i = 0; i <= SEGMENTS_COUNT; i++) {
path.add([view.bounds.width * i / SEGMENTS_COUNT, view.center.y]);
}
// on mouse down...
function onMouseDown() {
// ...animate points
for (var i = 0, l = path.segments.length; i < l; i++) {
// get a reference to the point
var point = path.segments[i].point;
// calculate offset using sine function to form a curve
var offset = CURVE_HEIGHT * Math.sin(point.x * Math.PI / view.bounds.width);
// register animation
TweenLite.fromTo(
// target
point,
// duration
ANIMATION_DURATION,
// initial value
{ y: view.center.y },
{
// final value
y: view.center.y - offset,
// easing
ease: Elastic.easeOut.config(1, 0.3),
// on update...
onUpdate: function() {
// ...smooth the path
path.smooth();
}
}
);
}
}
</script>

program flow animating in javascript

Hello I am having errors with my code:
https://jsfiddle.net/wzhm2whj/
<script>
//Initial Global variables
var mainloop_frame_time = 34;
var top = 0;
var rootMenu = document.getElementById('menu');
var rootMenuDivs = rootMenu.getElementsByTagName('div')[0];
var rootListDivs = rootMenuDivs.getElementsByTagName('ul')[0];
var childDivs = rootListDivs.getElementsByTagName('div');
var childDiv = childDivs[0];
var childDiv_counter = 0;
var child_change_flag = true;
var child_index_increment = 0;
var child_index_amount = childDivs.length;
//var child_animation_keyframe = 0;
var frame = 0;
var childDiv_tmp1_position = 0;
//finding the web browsers viewport size.
var elem = (document.compatMode === "CSS1Compat") ? document.documentElement : document.body;
var client_height = elem.clientHeight;
var process_array = new Array();
//Initial styling
for (var i = 0; i < childDivs.length; i++) {
var childDiv = childDivs[0];
childDiv.style.backgroundColor = "antiquewhite";
}
var childDiv = childDivs[0];
//rotate function variables
var rotate_div;
var rotate_passed_deg;
var rotate_deg_stop;
var rotate_results;
var rotate_current_deg = 0;
var speed_modifier = 1;
var tmp1_speed = 0;
//case flags
case2_flag = -1;
case3_flag = -1;
//This may not be needed >>> If not, put all code in mainloop.
var processes_logic = function() {
switch (frame) {
case 0:
process_array.push(menu_child0);
break;
//this case is when the previous case is 80% done
case 28:
rootMenu.style.transformOrigin = "top left";
process_array.push(menu_slant);
break;
case 35:
//Added the ability for paramaters, all push paramaters here are: function, menu_index, position, speed, tmp as flag for switching to next menu,
//process_index used to give the process index as refrence to delete..
window.alert(process_array.length);
process_array.push(new Array(menu_div_slide_out, child_index_amount - 1, 0, 0, 0, process_array.length-1));
break;
}
}
var initiate_all_processes = function() {
for (var i = 0; i < process_array.length; i++) {
//Added the ability for paramaters, considerer removing as its not used atm, or revising.
if (process_array[i] != undefined && process_array[i] != null && process_array[i] != "") {
if (process_array[i].length < 6) {
process_array[i]();
} else {
process_array[i][0](process_array[i][5]);
}
}
}
}
function menu_div_slide_out(process_index) {
/*process_array[process_index][
0 = function,
1 = current menu item (index length working backwards)
2 = position,
3 = speed,
4 = tmp,
5 = refrence to this process in array] */
//for debuging purposes to see if a ChildDiv is not devined, what process index is being pointed to.
//window.alert('Process index ' + process_index);
//!!!!!!!! You are probably mixing up how you are setting process index! try +1
process_array[process_index][2] += 3.5 + (process_array[process_index][3] * 1.7);
process_array[process_index][3] += (speed_modifier * .3);
childDivs[process_array[process_index][1]].style.left = process_array[process_index][2] + 'px';
if (process_array[process_index][2] > 100 && process_array[process_index][4] && process_array[process_index][1] > 0) {
// window.alert('CCC');
process_array[process_index][4] = true;
//Add another process at ever 100pxs
process_array.push(new Array(menu_div_slide_out, process_array[process_index][1] - 1, 0, 0, false, process_array.length-1));
//debugger;
} else
if (process_array[process_index][2] >= (900 - (process_array[process_index][2] / 20))) {
childDivs[process_array[process_index][1]].remove();
//process_array.splice(process_array[process_index][5], 1);
}
}
function menu_slant() {
rotate_return = rotate(rootMenu, .1 + (tmp1_speed), 27);
tmp1_speed += (speed_modifier * .5);
if (rotate_return === true) {
/////////////This can be unremoved because there is more animation, perhaps. or can be done in another key frame.
tmp1_speed = 0;
rotate_current_deg = 0;
remove_process(menu_slant);
} else {
if (rotate_return / 27 * 100 >= 60 && case3_flag < 0) {
case2_flag = frame;
}
}
}
var menu_child0 = function() {
childDiv_tmp1_position += 3 + (tmp1_speed * 1.7);
childDiv.style.top = childDiv_tmp1_position + 'px';
rotate(childDiv, .2 + (tmp1_speed), 170);
tmp1_speed += (speed_modifier * .7);
if (childDiv_tmp1_position / client_height * 100 >= 80 && case2_flag < 0) {
case2_flag = frame;
}
if (childDiv_tmp1_position >= client_height) {
childDiv.style.visibility = 'hidden';
tmp1_speed = 0;
childDiv_tmp1_position = 0;
rotate_current_deg = 0;
//may be bloated >>
remove_process(menu_child0);
}
}
function remove_process(index) {
var index_tmp = process_array.indexOf(index);
if (index_tmp >= 0) {
process_array.splice(index_tmp, 1);
}
}
function rotate(rotate_div, rotate_passed_deg, rotate_passed_deg_stop) {
rotate_current_deg += rotate_passed_deg;
rotate_deg = rotate_current_deg < rotate_passed_deg_stop ? rotate_current_deg : rotate_passed_deg_stop;
rotate_div.style.webkitTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.mozTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.msTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.oTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.transform = 'rotate(' + rotate_deg + 'deg)';
if (rotate_current_deg >= rotate_passed_deg_stop) {
return true;
} else {
return rotate_current_deg;
}
}
//main loop for the animation
var mainloop = function() {
processes_logic();
initiate_all_processes();
frame++;
}
var loop_interval = setInterval(mainloop, mainloop_frame_time);
</script>
I am trying to animate my website falling apart but I am having a hard time articulation this into code. I thought of running the animation in a loop, creating events at specific frames and reusing some codes as functions. I have a rotate function which works to rotate several things.
THE PROBLEM:
The problem I am having is sliding my menu items one at a time to the right. I want one to slide a bit and the next to start sliding after. I wrote a function to slide an item and then in that function it adds another process to an array for the next menu item to be called and run the same function (with passed interval of who is calling). I do not know how many menu items there will be, thats why I am trying to make it dynamic.
I can get it so that the first mwnu item falls, the menu falls by rotating it (some times if there is an error in the code then it wont rotate, but when there are no errors it works better).
The issue is sliding each menu item.
my website is here: http://clearlove.ca/89-404-error
Can any one help me with why this isnt working, and if there is a better way to do what I am trying to do?

displaying sprites after Collision detection

So when I shoot the enemies they get wiped from the screen, this works.
However what I want to happen is I want to place an explosion (4 pngs one after another)
basically where the enemy was. The code for the explosion works on its own but im stuck trying to integrate it with my code.
Here is the explosion class, as you can see I am having some trouble with the interval as I have no experience with them. I think the error or wrong logic lies in this object.
Also for some reason it wipes the other canvas layers :/
Try it here: http://www.taffatech.com/DarkOrbit.html
function Explosion()
{
this.srcX = 0;
this.srcY = 1250;
this.drawX = 0;
this.drawY = 0;
this.width = 70;
this.height = 70;
this.currentFrame =0;
this.totalFrames =5;
this.hasHit = false;
}
Explosion.prototype.draw = function() //makes it last 10 frames using total frames
{
if(this.currentFrame <= this.totalFrames)
{
this.currentFrame++;
Exploder(this.drawX,this.drawY);
}
else
{
this.hasHit = false;
currentFrame =0;
}
}
function Exploder(srcX,srcY)
{
whereX = this.srcX;
whereY = this.srcY;
intervalT = setInterval(BulletExplosionAnimate, 80);
}
var bulletExplosionStart = 0;
var whereX =0;
var whereY =0;
function BulletExplosionAnimate(intervalT)
{
var wide = 70;
var high = 70;
if (bulletExplosionStart > 308)
{
bulletExplosionStart = 0;
clearInterval(intervalT);
}
else
{
ctxExplosion.clearRect(0,0,canvasWidth,canvasHeight)
ctxExplosion.drawImage(spriteImage,bulletExplosionStart,1250,wide,high,whereX,whereY,wide,high);
bulletExplosionStart += 77;
}
}
my Bullet object:
function Bullet() //space weapon uses this
{
this.srcX = 0;
this.srcY = 1240;
this.drawX = -20;
this.drawY = 0;
this.width = 11;
this.height = 4;
this.bulletSpeed = 10;
this.bulletReset = -20;
this.explosion = new Explosion();
}
Bullet.prototype.draw = function()
{
this.drawX += this.bulletSpeed;
ctxPlayer.drawImage(spriteImage,this.srcX,this.srcY,this.width,this.height,this.drawX,this.drawY,this.width,this.height);
this.checkHitEnemy();
if (this.drawX > canvasWidth)
{
this.recycle();
}
}
Bullet.prototype.fire = function(startX, startY)
{
this.drawX = startX;
this.drawY = startY;
}
Bullet.prototype.checkHitEnemy = function()
{
for(var i = 0; i < enemies.length; i++)
{
if( this.drawX >= enemies[i].drawX && this.drawX <= enemies[i].drawX + enemies[i].enemyWidth && this.drawY >= enemies[i].drawY && this.drawY <= enemies[i].drawY + enemies[i].enemyHeight)
{
this.explosion.drawX = enemies[i].drawX - (this.explosion.width/2);
this.explosion.drawY = enemies[i].drawY;
this.explosion.hasHit = true;
this.recycle(); //bullet resets after hit enemy
enemies[i].recycleEnemy(); //change this soon to have if loop if health is down
}
}
}
Bullet.prototype.recycle = function()
{
this.drawX = this.bulletReset;
}
In my player object I have a function that checks if it has hit an enemy, it works:
Player.prototype.drawAllBullets = function()
{
for(var i = 0; i < this.bullets.length; i++)
{
if(this.bullets[i].drawX >= 0)
{
this.bullets[i].draw();
}
if(this.bullets[i].explosion.hasHit)
{
this.bullets[i].explosion.draw();
}
}
}
Currently when I shoot an enemy they disappear but not explosion happens, I know my interval is not great coding, so I need some help with it, thanks!
Playing a spritesheet in canvas
It’s becoming best practice to use requestAnimationFrame to do your animations. It does some nice event grouping and performance enhancing. Here’s a good post on requestAnimationFrame: http://creativejs.com/resources/requestanimationframe/
This is how you can use requestAnimationFrame to play a spritesheet:
In this case, it’s a 4x4 spritesheet that will play over 1 second:
var fps = 16;
function explode() {
// are we done? ... if so, we're outta here
if(spriteIndex>15){return;}
// It's good practice to use requestAnimation frame
// We wrap it in setTimeout because we want timed frames
setTimeout(function() {
// queue up the next frame
requestAnimFrame(explode);
// Draw the current frame
var x=spriteIndex%(cols-1)*width;
var y=parseInt(spriteIndex/(rows-1))*height;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(sheet,x,y,width,height,0,0,width,height);
// increment the sprite counter
spriteIndex++;
}, 1000 / fps);
}
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/nSGyx/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// This is Paul Irish's great cross browser shim for requestAnimationFrame
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
// define the spritesheet
var spriteIndex=0;
var width=64;
var height=64;
var rows=4;
var cols=4;
// load the sheet image
var sheet=document.createElement("img");
sheet.onload=function(){
canvas.width=width;
canvas.height=height;
// call the animation
explode();
}
sheet.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/explodeSprite.png";
var fps = 16;
function explode() {
// are we done? ... if so, we're outta here
if(spriteIndex>15){return;}
// It's good practice to use requestAnimation frame
// We wrap it in setTimeout because we want timed frames
setTimeout(function() {
// queue up the next frame
requestAnimFrame(explode);
// Draw the current frame
var x=spriteIndex%(cols-1)*width;
var y=parseInt(spriteIndex/(rows-1))*height;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(sheet,x,y,width,height,0,0,width,height);
// increment the sprite counter
spriteIndex++;
}, 1000 / fps);
}
$("#explode").click(function(){ spriteIndex=0; explode(); });
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=64 height=64></canvas><br>
<button id="explode">Explode</button>
</body>
</html>
.
.
.
[Edited to show more details of how animation fits into your code]
This is a recoding of your explosion functions.
Declare your explosion related variables outside the functions:
var bulletExplosionStart;
var whereX =0;
var whereY =0;
var wide = 70;
var high = 70;
Next, in Exploder(), set where the explosion will occur and reset the sprite index (bulletExplosionStart) to 0
Possible error: Check your Exploder function: you supply srcX,srcY but then do whereX=this.srcX, whereY=this.srcY. I assume you meant to use the srcX,srcY supplied as arguments to Exploder() instead of this.srcX,this.srcY.
function Exploder(srcX,srcY)
{
whereX = srcX;
whereY = srcY;
bulletExplosionStart=0;
BulletExplosionAnimate();
}
This is the recoded bulletExplosionAnimate function that plays the 4 frames of the spritesheet.
After 4 frames this animation automatically stops.
var fps = 2;
function bulletExplosionAnimate() {
// are we done? ... if so, we're outta here
if(bulletExplosionStart>308){return;}
// It's good practice to use requestAnimation frame
// We wrap it in setTimeout because we want timed frames
setTimeout(function() {
// queue up the next frame
requestAnimFrame(bulletExplosionAnimate);
// Draw the current frame
ctxExplosion.clearRect(0,0,canvasWidth,canvasHeight)
ctxExplosion.drawImage(spriteImage,
bulletExplosionStart,1250,wide,high,
whereX,whereY,wide,high);
// increment the sprite position
bulletExplosionStart += 77;
}, 1000 / fps);
}

How to add scroll background effect to multiple elements with different settings?

In this demo http://www.htmldrive.net/items/demo/527/Animated-background-image-with-jQuery
This code is for one background only. I want to add multiple background with different direction and speed.
var scrollSpeed = 70;
var step = 1;
var current = 0;
var imageWidth = 2247;
var headerWidth = 800;
var restartPosition = -(imageWidth - headerWidth);
function scrollBg(){
current -= step;
if (current == restartPosition){
current = 0;
}
$('#header').css("background-position",current+"px 0");
}
var init = setInterval("scrollBg()", scrollSpeed);
Currently it has settings for
$('#header').css("background-position",current+"px 0");
In a website I want to use this effect on #footer or #content background also. but with different speed and direction.
And is there any better and more optimized jquery method to achieve same effect?
And can we get same effect using CSS 3, without javascript?
Just saw the OP's answer, but decided to post anyway:
I've created a jQuery plugin to do this:
(function($) {
$.fn.scrollingBackground = function(options) {
// settings and defaults.
var settings = options || {};
var speed = settings.speed || 1;
var step = settings.step || 1;
var direction = settings.direction || 'rtl';
var animStep;
// build up a string to pass to animate:
if (direction === 'rtl') {
animStep = "-=" + step + "px";
}
else if (direction === 'ltr') {
animStep = '+=' + step + "px";
}
var element = this;
// perform the animation forever:
var animate = function() {
element.animate({
backgroundPosition: animStep + " 0px"
}, speed, animate);
};
animate();
};
})(jQuery);
Usage:
$("#header").scrollingBackground({
speed: 50,
step: 50,
direction: 'ltr'
});
This is pretty basic, and assumes that you're background-repeat is 'repeat-x' on the element you call it on. This way, there's no need to reset the background position every so often.
Working example: http://jsfiddle.net/andrewwhitaker/xmtpr/
I could work out the following solution. Am not sure if it is efficient. Will wait for anyone to comment or provide a better option.
Till then...:
var scrollSpeed = 70;
var step = 1;
var current = 0;
var images =
[
{
imageWidth:2247,
imagePath:"images/image1"
},
{
imageWidth:1200,
imagePath:"images/image2"
}
]
var headerWidth = 800;
var imageRotateCount = 0;
var imagesLength = images.length;
$('#header').css("background-image", images[0].imagePath);
function scrollBg(){
var curIndex = imageRotateCount%imagesLength;
var curImage = images[curIndex];
current -= step;
var restartPosition = -(curImage.imageWidth - headerWidth);
if (current == restartPosition){
current = 0;
imageRotateCount++;
curIndex = imageRotateCount%imagesLength;
curImage = images[curIndex];
$('#header').css("background-image", curImage.imagePath);
}
$('#header').css("background-position",current+"px 0");
}
var init = setInterval("scrollBg()", scrollSpeed);

Categories

Resources