<!-- Use preprocessors via the lang attribute! e.g. <template lang="pug"> -->
<template>
  <div id="app" class="container mx-auto">
    <div class="flex flex-col justify-center">
      <h1 class="text-3xl mb-4">Box Shadows</h1>
      <h2 class="text-xl mb-4">Angle & Distance to X & Y</h2>
      <div class="flex-grow-0">
        <label>Angle</label>
        <input
          v-model="angle"
          v-on:change="calculateXandY"
          class="rounded-md shadow-md border-4"
          type="number"
        />
      </div>
      <br />
      <div class="flex-grow-0">
        <label>Distance</label>
        <input
          v-model="distance"
          v-on:change="calculateXandY"
          @input="calculateUsingXY"
          class="rounded-md shadow-md border-4"
          type="number"
        />
      </div>

      <p class="my-8">x: {{ x }} y: {{ y }}</p>

      <p
        class="w-3/6 mx-12 rounded-md py-10 text-center bg-green-200"
        :style="shadow"
      >
        Our shadow
      </p>
      <br />
      <br />
    </div>
    <p class="my-8">
      angle: {{ reversed.angle }} dist: {{ reversed.distance }}
    </p>

    <hr />
    <h2 class="text-xl mb-4">X & Y to Angle & Distance</h2>
    <div class="flex-grow-0">
      <label>X</label>
      <input
        v-model="xy.x"
        v-on:change="calculateUsingXY"
        class="rounded-md shadow-md border-4"
        type="number"
      />
    </div>
    <br />
    <div class="flex-grow-0">
      <label>Y</label>
      <input
        v-model="xy.y"
        v-on:change="calculateUsingXY"
        v-on:keyPress="calculateUsingXY"
        class="rounded-md shadow-md border-4"
        type="number"
      />
    </div>
    <br />

    <p class="my-8">angle: {{ xy.angle }} distance: {{ xy.distance }}</p>

    <button
      class="border-2 border-green-200 rounded-lg px-8 py-4"
      @click="calculateXandY"
    >
      Calculate
    </button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      angle: 70,
      distance: 8,

      x: 0,
      y: 0,
      blur: 1,
      spread: 1,

      xy: {
        x: 0,
        y: 0,
        angle: 0,
        distance: 0
      },
      reversed: {
        angle: 0,
        distance: 0
      }
    };
  },
  computed: {
    shadow() {
      return `box-shadow: ${this.x}px ${this.y}px 3px -2px rgba(0,0,0,0.2), ${this.x}px ${this.y}px 4px 0px rgba(0,0,0,0.14), ${this.x}px ${this.y}px 8px 0px rgba(0,0,0,0.12)`;
    }
  },
  methods: {
    calculateXandY() {
      let radians = (this.angle * Math.PI) / 180;
      let x = Math.cos(radians) * this.distance;
      let y = Math.sin(radians) * this.distance;

      this.x = Math.round(x);
      this.y = Math.round(y);
      this.calculateReverse();
    },

    calculateReverse() {
      let a = this.y;
      let b = this.x;
      let c = Math.sqrt(a * a + b * b);

      this.reversed.distance = Math.round(c);

      let angle = Math.asin(a / c);
      // need to convert from radians to degrees
      this.reversed.angle = Math.round((angle * 180) / Math.PI);
    },

    calculateUsingXY() {
      let a = this.xy.y;
      let b = this.xy.x;
      let c = Math.sqrt(a * a + b * b);

      this.xy.distance = Math.round(c);

      let angle = Math.asin(a / c);
      // need to convert from radians to degrees
      this.xy.angle = Math.round((angle * 180) / Math.PI);
    }
  },
  mounted() {
    this.calculateXandY();
  }
};
</script>

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.0.2/tailwind.min.css

External JavaScript

This Pen doesn't use any external JavaScript resources.