Javascript shake html element

I am trying to shake an html element for my game.

I found this code here:

shake = function (sprite, magnitude = 16, angular = false) { //A counter to count the number of shakes var counter = 1; //The total number of shakes (there will be 1 shake per frame) var numberOfShakes = 10; //Capture the sprite position and angle so you can //restore them after the shaking has finished var startX = sprite.x, startY = sprite.y, startAngle = sprite.rotation; // Divide the magnitude into 10 units so that you can // reduce the amount of shake by 10 percent each frame var magnitudeUnit = magnitude / numberOfShakes; //The `randomInt` helper function var randomInt = (min, max) => { return Math.floor(Math.random() * (max - min + 1)) + min; }; //Add the sprite to the `shakingSprites` array if it //isn't already there if(shakingSprites.indexOf(sprite) === -1) { //console.log("added") shakingSprites.push(sprite); //Add an `updateShake` method to the sprite. //The `updateShake` method will be called each frame //in the game loop. The shake effect type can be either //up and down (x/y shaking) or angular (rotational shaking). sprite.updateShake = () => { if(angular) { angularShake(); } else { upAndDownShake(); } }; } //The `upAndDownShake` function function upAndDownShake() { //Shake the sprite while the `counter` is less than //the `numberOfShakes` if (counter < numberOfShakes) { //Reset the sprite position at the start of each shake sprite.x = startX; sprite.y = startY; //Reduce the magnitude magnitude -= magnitudeUnit; //Randomly change the sprite position sprite.x += randomInt(-magnitude, magnitude); sprite.y += randomInt(-magnitude, magnitude); //Add 1 to the counter counter += 1; } //When the shaking is finished, restore the sprite to its original //position and remove it from the `shakingSprites` array if (counter >= numberOfShakes) { sprite.x = startX; sprite.y = startY; shakingSprites.splice(shakingSprites.indexOf(sprite), 1); } } //The `angularShake` function //First set the initial tilt angle to the right (+1) var tiltAngle = 1; function angularShake() { if (counter < numberOfShakes) { //Reset the sprite rotation sprite.rotation = startAngle; //Reduce the magnitude magnitude -= magnitudeUnit; //Rotate the sprite left or right, depending on the direction, //by an amount in radians that matches the magnitude sprite.rotation = magnitude * tiltAngle; counter += 1; //Reverse the tilt angle so that the sprite is tilted //in the opposite direction for the next shake tiltAngle *= -1; } //When the shaking is finished, reset the sprite angle and //remove it from the `shakingSprites` array if (counter >= numberOfShakes) { sprite.rotation = startAngle; shakingSprites.splice(shakingSprites.indexOf(sprite), 1); //console.log("removed") } } } 

However, it only works for sprites on canvas. How can I make it work with HTML elements? Thanks.

+6
source share
5 answers

I adapted your function so that it works on DOM elements. This is a pretty healthy shake, although you might want to play around with the options to damp it out a bit:

 var shakingElements = []; var shake = function (element, magnitude = 16, angular = false) { //First set the initial tilt angle to the right (+1) var tiltAngle = 1; //A counter to count the number of shakes var counter = 1; //The total number of shakes (there will be 1 shake per frame) var numberOfShakes = 15; //Capture the element position and angle so you can //restore them after the shaking has finished var startX = 0, startY = 0, startAngle = 0; // Divide the magnitude into 10 units so that you can // reduce the amount of shake by 10 percent each frame var magnitudeUnit = magnitude / numberOfShakes; //The `randomInt` helper function var randomInt = (min, max) => { return Math.floor(Math.random() * (max - min + 1)) + min; }; //Add the element to the `shakingElements` array if it //isn't already there if(shakingElements.indexOf(element) === -1) { //console.log("added") shakingElements.push(element); //Add an `updateShake` method to the element. //The `updateShake` method will be called each frame //in the game loop. The shake effect type can be either //up and down (x/y shaking) or angular (rotational shaking). if(angular) { angularShake(); } else { upAndDownShake(); } } //The `upAndDownShake` function function upAndDownShake() { //Shake the element while the `counter` is less than //the `numberOfShakes` if (counter < numberOfShakes) { //Reset the element position at the start of each shake element.style.transform = 'translate(' + startX + 'px, ' + startY + 'px)'; //Reduce the magnitude magnitude -= magnitudeUnit; //Randomly change the element position var randomX = randomInt(-magnitude, magnitude); var randomY = randomInt(-magnitude, magnitude); element.style.transform = 'translate(' + randomX + 'px, ' + randomY + 'px)'; //Add 1 to the counter counter += 1; requestAnimationFrame(upAndDownShake); } //When the shaking is finished, restore the element to its original //position and remove it from the `shakingElements` array if (counter >= numberOfShakes) { element.style.transform = 'translate(' + startX + ', ' + startY + ')'; shakingElements.splice(shakingElements.indexOf(element), 1); } } //The `angularShake` function function angularShake() { if (counter < numberOfShakes) { console.log(tiltAngle); //Reset the element rotation element.style.transform = 'rotate(' + startAngle + 'deg)'; //Reduce the magnitude magnitude -= magnitudeUnit; //Rotate the element left or right, depending on the direction, //by an amount in radians that matches the magnitude var angle = Number(magnitude * tiltAngle).toFixed(2); console.log(angle); element.style.transform = 'rotate(' + angle + 'deg)'; counter += 1; //Reverse the tilt angle so that the element is tilted //in the opposite direction for the next shake tiltAngle *= -1; requestAnimationFrame(angularShake); } //When the shaking is finished, reset the element angle and //remove it from the `shakingElements` array if (counter >= numberOfShakes) { element.style.transform = 'rotate(' + startAngle + 'deg)'; shakingElements.splice(shakingElements.indexOf(element), 1); //console.log("removed") } } }; 

Demo

Look at the demo in the violin. The red block is a regular upAndDownShake , while green uses angularShake :

https://jsfiddle.net/12aueufy/1/

+3
source

You can use css animation like in this example

 @-webkit-keyframes shake { 0% { -webkit-transform: translate(2px, 1px) rotate(0deg); } 10% { -webkit-transform: translate(-1px, -2px) rotate(-1deg); } 20% { -webkit-transform: translate(-3px, 0px) rotate(1deg); } 30% { -webkit-transform: translate(0px, 2px) rotate(0deg); } 40% { -webkit-transform: translate(1px, -1px) rotate(1deg); } 50% { -webkit-transform: translate(-1px, 2px) rotate(-1deg); } 60% { -webkit-transform: translate(-3px, 1px) rotate(0deg); } 70% { -webkit-transform: translate(2px, 1px) rotate(-1deg); } 80% { -webkit-transform: translate(-1px, -1px) rotate(1deg); } 90% { -webkit-transform: translate(2px, 2px) rotate(0deg); } 100% { -webkit-transform: translate(1px, -2px) rotate(-1deg); } } .shake:hover { -webkit-animation-name: shake; -webkit-animation-duration: 0.5s; -webkit-transform-origin:50% 50%; -webkit-animation-iteration-count: infinite; } .shake { display:inline-block } 
 <div class="shake">Shake me</div> <img class="shake" src="https://www.w3.org/2008/site/images/logo-w3c-screen-lg" /> 

To change the speed of shaking, change the values โ€‹โ€‹of animation-duration , translate() , rotate() .

If you want to shake an element using javascript see jsfiddle

+21
source

Maybe you should take a look at Animate.css, https://daneden.imtqy.com/animate.css/ , this is a css library that provides a lot of animations, including shake one ... I hope this can work for your problem!

+2
source
 function shake(e, oncomplete, distance, time) { var time = 500; var distance = 5; var start = (new Date()).getTime(); animate(); function animate() { var now = (new Date()).getTime(); // Get current time var elapsed = now - start; // How long since we started var fraction = elapsed / time; // What fraction of total time? if (fraction < 1) { var x = distance * Math.sin(fraction * 4 * Math.PI); e.style.left = x + "px"; // We're aiming for a smooth 40 frames/second animation. setTimeout(animate, Math.min(25, time - elapsed)); } else { // Otherwise, the animation is complete if (oncomplete) oncomplete(e); // Invoke completion callback } } } function shakeme(event1) { shake(event1.target); } document.getElementById("wood").addEventListener("mouseover", shakeme, false); 

HTML element

 <button id="wood">Hello World</button> 

Source

http://javascriipt.blogspot.com/2015/02/how-to-mimic-shake-animation-effect.html

0
source

You can use some library for javascript animation like Velocity

It is truly flexible and easy to use.

Please check this working sample , I am sure you can create the desired effect in minutes

Hope this helps

0
source

All Articles