Home > front end >  Rotate object in div towards direction of mouse click
Rotate object in div towards direction of mouse click

Time:02-10

I have an image of an arrow that rotates around a fixed central point and I want to make it to where it moves in the direction of a mouse click. So someone can click somewhere on the screen and the arrow will point in the direction of the mouse click.

This is what the arrow looks like:

Arrow example

And this is what the code of the div looks like

content.innerHTML = '<img class = "arrow" style="transform: rotate(' x 'deg)" src="img/arrow.png"</img>'

and the CSS for those interested:

.arrow {
  width: 200px;
  height: 10px;
  position: absolute;
  transform-origin: 100% 50%;
}

Any pointers appreciated! Thanks!

CodePudding user response:

A duplicate question,a duplicate answer

Old Question

Old Answer

The below is a part of answer

let get, post, doc, html, bod, nav, M, I, mobile, S, Q, aC, rC, tC; // for use on other loads
addEventListener('load', () => {
  get = (url, success, context) => {
    const x = new XMLHttpRequest;
    const c = context || x;
    x.open('GET', url);
    x.onload = () => {
      if (success) success.call(c, JSON.parse(x.responseText));
    }
    x.send();
  }
  post = function(url, send, success, context) {
    const x = new XMLHttpRequest;
    const c = context || x;
    x.open('POST', url);
    x.onload = () => {
      if (success) success.call(c, JSON.parse(x.responseText));
    }
    if (typeof send === 'object' && send && !(send instanceof Array)) {
      if (send instanceof FormData) {
        x.send(send);
      } else {
        const fd = new FormData;
        for (let k in send) {
          fd.append(k, JSON.stringify(send[k]));
        }
        x.send(fd);
      }
    } else {
      throw new Error('send argument must be an Object');
    }
    return x;
  }
  doc = document;
  html = doc.documentElement;
  bod = doc.body;
  nav = navigator;
  M = tag => doc.createElement(tag);
  I = id => doc.getElementById(id);
  mobile = nav.userAgent.match(/Mobi/i) ? true : false;
  S = (selector, within) => {
    var w = within || doc;
    return w.querySelector(selector);
  }
  Q = (selector, within) => {
    var w = within || doc;
    return w.querySelectorAll(selector);
  }
  aC = function() {
    const a = [].slice.call(arguments),
      n = a.shift();
    n.classList.add(...a);
    return aC;
  }
  rC = function() {
    const a = [].slice.call(arguments),
      n = a.shift();
    n.classList.remove(...a);
    return rC;
  }
  tC = function() {
    const a = [].slice.call(arguments),
      n = a.shift();
    n.classList.toggle(...a);
    return tC;
  }
  // you can put the following on another page using a load Event - besides the end load
  function Arrow(canvasElement, arrowWidth = 25, arrowHeight = 75, lineWidth = 3, strokeStyle = '#000', lineCap = 'round') {
    let bc = canvasElement.getBoundingClientRect(),
      ctx = canvasElement.getContext('2d');
    const w = bc.width,
      h = bc.height,
      ha = arrowWidth / 2;
    canvasElement.width = w;
    canvasElement.height = h;
    ctx.lineWidth = lineWidth;
    ctx.strokeStyle = strokeStyle;
    ctx.lineCap = lineCap;
    let x = w / 2,
      hh = h / 2,
      y = hh - arrowHeight / 2,
      hit = false;
    this.clear = () => {
      ctx.clearRect(0, 0, w, h);
    }
    const arrowTop = () => {
      ctx.beginPath();
      ctx.moveTo(x, y);
    }
    this.make = () => {
      this.clear();
      arrowTop();
      ctx.lineTo(x, y   arrowHeight);
      ctx.stroke();
      arrowTop();
      ctx.lineTo(x - ha, y   ha);
      ctx.stroke();
      arrowTop();
      ctx.lineTo(x   ha, y   ha);
      ctx.stroke();
      return this;
    }
    this.rotate = deg => {
      ctx.save();
      ctx.translate(x, hh);
      ctx.rotate(Math.PI / 180 * deg);
      ctx.translate(-x, -hh);
      this.make();
      ctx.restore();
      return this;
    }
    const hitRotate = e => {
      if (!hit) {
        return;
      }
      bc = canvasElement.getBoundingClientRect();
      this.rotate(90   Math.atan2(e.clientY - bc.top - hh, e.clientX - bc.left - x) * 180 / Math.PI);
    }
    const hitStart = e => {
      hit = true;
      hitRotate(e);
    }
    const hitStop = () => {
      hit = false;
    }
    this.touch = () => {
      canvasElement.ontouchstart = hitStart;
      canvasElement.ontouchmove = e => {
        hitRotate(e.touches[0]);
      }
      canvasElement.ontouchend = hitStop;
      return this;
    }
    this.mouse = () => {
      canvasElement.onmousedown = hitStart;
      canvasElement.onmousemove = hitRotate;
      canvasElement.onmouseup = canvasElement.onmouseout = hitStop;
      return this;
    }
  }
  const arrow = new Arrow(I('can'));
  arrow.rotate(45);
  if (mobile) {
    arrow.mobile();
  } else {
    arrow.mouse();
  }
}); // end load
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

html,
body {
  width: 100%;
  height: 100%;
  background: #ccc;
}

.main {
  padding: 10px;
}

#can {
  display: block;
  width: 480px;
  height: 270px;
  background: #fff;
  margin: 0 auto;
}
<div class='main'>
  <canvas id='can'></canvas>
</div>

  • (Visit old answer&question for details&explanation )

Kind request

Stackoverflow is not a place to ask just questions, google your doubt and you get old StackOverflow pages where you can find answer

  •  Tags:  
  • Related