Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
blob: a8233398ad63cff2a7eebde19878d1fe423e7cbd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<?xml version="1.0" standalone="yes"?>
<svg viewBox="-200 -150 400 300" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <style>
    circle, rect {
      fill-opacity: 0.9;
    }
  </style>

  <g>
    <circle id="pointer" cx="0" cy="0" r="5" fill="red" stroke="maroon"/>
  </g>

  <script type="text/javascript">//<![CDATA[
    const svgns = 'http://www.w3.org/2000/svg',
      svg = document.querySelector('svg'),
      group = svg.querySelector('g'),
      pointerEl = svg.querySelector('#pointer'),
      { x: vbX, y: vbY, width: vbWidth, height: vbHeight } = svg.viewBox.baseVal,

      shapeCount = 100,
      circleRadius = { min: 5, max: 45 },
      rectSideLength = { min: 5, max: 95 },
      colorValRange = { min: 0, max: 255 },
      shadeFactorRange = { min: 0.3, max: 0.7 };

    // source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_integer_between_two_values_inclusive
    function getRandomIntInclusive(min, max) {
      const minCeiled = Math.ceil(min),
        maxFloored = Math.floor(max);

      return Math.floor(Math.random() * (maxFloored - minCeiled + 1) + minCeiled);
    }

    // source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_number_between_two_values
    function getRandomArbitrary(min, max) {
      return Math.random() * (max - min) + min;
    }

    function getRandomColorValue() {
      return getRandomIntInclusive(colorValRange.min, colorValRange.max);
    }

    function getRandomShadeFactor() {
      return getRandomArbitrary(shadeFactorRange.min, shadeFactorRange.max);
    }

    function getRandomOrigin() {
      return {
        x: getRandomIntInclusive(vbX, vbX + vbWidth),
        y: getRandomIntInclusive(vbY, vbY + vbHeight)
      }
    }

    function getRandomFillAndStrokeVals() {
      const fill = ['r', 'g', 'b'].map(() => getRandomColorValue()),
        stroke = fill.map(v => Math.floor(v * getRandomShadeFactor()));

      return {
        fill: fill,
        stroke: stroke
      };
    }

    function getRandomCircle(fill, stroke) {
      const el = document.createElementNS(svgns, 'circle'),
        r = getRandomIntInclusive(circleRadius.max, circleRadius.min),
        origin = getRandomOrigin();

      el.setAttributeNS(null, 'cx', origin.x);
      el.setAttributeNS(null, 'cy', origin.y);
      el.setAttributeNS(null, 'r', r);
      el.setAttributeNS(null, 'fill', fill);
      el.setAttributeNS(null, 'stroke', stroke);

      return el;
    }

    function getRandomRect(fill, stroke) {
      const el = document.createElementNS(svgns, 'rect'),
        [width, height] = ['w', 'h'].map(() =>
          getRandomIntInclusive(rectSideLength.max, rectSideLength.min)
        ),
        origin = getRandomOrigin();

      el.setAttributeNS(null, 'x', origin.x);
      el.setAttributeNS(null, 'y', origin.y);
      el.setAttributeNS(null, 'width', width);
      el.setAttributeNS(null, 'height', height);
      el.setAttributeNS(null, 'fill', fill);
      el.setAttributeNS(null, 'stroke', stroke);

      return el;
    }

    function getRandomShape({ fill: fillVals, stroke: strokeVals }) {
      const shape = [getRandomCircle, getRandomRect][Math.round(Math.random())],
        [fill, stroke] = [fillVals, strokeVals].map(v => `rgb(${v.join(', ')})`);

      return shape(fill, stroke);
    }

    [...Array(shapeCount)]
      .map(() => getRandomFillAndStrokeVals())
      .forEach(fillAndStrokeVal => pointerEl.before(getRandomShape(fillAndStrokeVal)));
  //]]></script>
</svg>