Core JavaScript

SVG - Shooting an Arrow Animation

This JavaScript Reference section displays the code for an example program that shows how to animate the shooting of an arrow using scalable vector graphics (SVG).

ShootingArrow.html

<!DOCTYPE html>
<html>
<head>
  <title>XoaX.net's Javascript Shooting an Arrow Animation</title>
  <script type="text/javascript" src="ShootingArrow.js"></script>
  <button onclick="Restart()">Shoot</button>
</head>
<body>
</body>
</html>

ShootingArrow.js

const kiTotalTime = 150;
var iTime = 0;
var qPosition = { mdX:50.0, mdY:400.0};
var qInitVelocity = { mdX:3.3, mdY:10};
var qCurrVelocity = { mdX:0.0, mdY:0.0};
var gqRotationSvg = null;
var gqTranslationSvg = null;
var gbRunning = false;


function UpdateVelocityAndPosition() {
	// Change the velocity and rotation
	qCurrVelocity.mdX = qInitVelocity.mdX;
	qCurrVelocity.mdY = (20*(iTime/kiTotalTime) - qInitVelocity.mdY);
	var dAngle = ((Math.atan2(qCurrVelocity.mdY, qCurrVelocity.mdX)*180)/Math.PI);
    gqRotationSvg.setAttribute('transform', 'rotate('+dAngle+')');
    // Change the position and translation
	qPosition.mdX += qCurrVelocity.mdX;
	qPosition.mdY += qCurrVelocity.mdY;
	gqTranslationSvg.setAttribute('transform', 'translate('+qPosition.mdX+', '+qPosition.mdY+')');
}

function AnimationLoop() {
  UpdateVelocityAndPosition();
  ++iTime;
  // Stop when the arrow hits the ground
  if (qPosition.mdY < 400){
    setTimeout(AnimationLoop, 25);
  } else {
	gbRunning = false;
  }
}

function Restart() {
  if (!gbRunning) {
    qPosition.mdX = 50.0;
    qPosition.mdY = 400.0;
    iTime = 0;
    gbRunning = true;
    AnimationLoop();
  }
}

function Initialize() {
  qpBody = document.getElementsByTagName("body")[0];

  // Create a 600 by 400 pixel region to hold the SVG
  qMainDiv = document.createElement('div');
  qpBody.appendChild(qMainDiv);
  qMainDiv.style.width = '600px';
  qMainDiv.style.height = '400px';
  qMainDiv.style.background = 'linear-gradient(cyan, tan)';

  // The Main SVG Element
  var qMainSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  qMainSvg.style.width="600px";
  qMainSvg.style.height="400px";
  qMainDiv.appendChild(qMainSvg);

  // Add an SVG Translation Element
  gqTranslationSvg = document.createElementNS("http://www.w3.org/2000/svg", "g");
  qMainSvg.appendChild(gqTranslationSvg);
  gqTranslationSvg.setAttribute('transform', 'translate('+qPosition.mdX+', '+qPosition.mdY+')');

  // Add an SVG Rotation Element
  gqRotationSvg = document.createElementNS("http://www.w3.org/2000/svg", "g");
  gqTranslationSvg.appendChild(gqRotationSvg);
  var dAngle = -((Math.atan2(qInitVelocity.mdY, qInitVelocity.mdX)*180)/Math.PI);
  gqRotationSvg.setAttribute('transform', 'rotate('+dAngle+')');

  // The SVG Arrow Element - It is just a line segment.
  var gqArrowLineSvg = document.createElementNS("http://www.w3.org/2000/svg", "line");
  gqRotationSvg.appendChild(gqArrowLineSvg);
  gqArrowLineSvg.setAttribute('x1', -25);
  gqArrowLineSvg.setAttribute('y1', 0);
  gqArrowLineSvg.setAttribute('x2', 25);
  gqArrowLineSvg.setAttribute('y2', 0);
  gqArrowLineSvg.setAttribute('stroke', 'rgb(55, 55, 55)');
  gqArrowLineSvg.setAttribute('stroke-width', 1);
}

window.onload = Initialize;
 

Output

 
 

© 2007–2024 XoaX.net LLC. All rights reserved.