PageSourceSearch

https://www.edsullivan.com/wp-content/themes/edsullivan_edsullivan/assets/js/tv.js?ver=1

js edsullivan.com collected 2026-10-02 04:10:03 UTC 16,505 bytes, 547 lines download raw bytes

1var Knob;
2Knob = function(input, ui) {
3  var container = document.createElement('div');
4  container.setAttribute('tabindex', 0);
5  input.parentNode.replaceChild(container, input);
6  input.style.cssText = 'position: absolute; top: -10000px';
7  input.setAttribute('tabindex', -1);
8  container.appendChild(input);
9
10  var settings = this.settings = this._getSettings(input);
11
12
13  this.value = input.value = settings.min + settings.range / 2;
14  this.input = input;
15  this.min = settings.min;
16
17  this.ui = ui;
18
19  var events = {
20    keydown: this._handleKeyEvents.bind(this),
21    mousewheel: this._handleWheelEvents.bind(this),
22    DOMMouseScroll: this._handleWheelEvents.bind(this),
23    touchstart: this._handleMove.bind(this, 'touchmove', 'touchend'),
24    mousedown: this._handleMove.bind(this, 'mousemove', 'mouseup')
25  };
26
27  for (var event in events) {
28    container.addEventListener(event, events[event], false);
29  }
30
31  container.style.cssText = 'position: relative; width:' + settings.width + 'px;' + 'height:' + settings.height + 'px;';
32
33  ui.init(container, settings);
34  this.container = container;
35  this.changed(0);
36
37};
38
39Knob.prototype = {
40  _handleKeyEvents: function(e) {
41    var keycode = e.keyCode;
42    if (keycode >= 37 && keycode <= 40) {
43      e.preventDefault();
44      var f = 1 + e.shiftKey * 9;
45      this.changed({37: -1, 38: 1, 39: 1, 40: -1}[keycode] * f);
46    }
47  },
48
49  _handleWheelEvents: function(e) {
50    e.preventDefault();
51    var deltaX = -e.detail || e.wheelDeltaX;
52    var deltaY = -e.detail || e.wheelDeltaY;
53    var val = deltaX > 0 || deltaY > 0 ? 1 : deltaX < 0 || deltaY < 0 ? -1 : 0;
54    this.changed(val);
55  },
56
57  _handleMove: function(onMove, onEnd) {
58    this.centerX = Math.floor(this.container.getBoundingClientRect().left)+  window.pageXOffset + this.settings.width / 2;
59    this.centerY = Math.floor(this.container.getBoundingClientRect().top)+  window.pageYOffset + this.settings.height / 2;
60
61    var fnc = this._updateWhileMoving.bind(this);
62    var body = document.body;
63    body.addEventListener(onMove, fnc, false);
64    body.addEventListener(onEnd, function() {
65      body.removeEventListener(onMove, fnc, false);
66    }, false);
67  },
68
69  _updateWhileMoving: function(event) {
70    event.preventDefault();
71    var e = event.changedTouches ? event.changedTouches[0] : event;
72    var x = this.centerX - e.pageX;
73    var y = this.centerY - e.pageY;
74    var deg = Math.atan2(-y, -x) * 180 / Math.PI + 90 - this.settings.angleoffset;
75    var percent;
76
77    if (deg < 0) {
78      deg += 360;
79    }
80    deg = deg % 360;
81    if (deg <= this.settings.anglerange) {
82      percent = Math.max(Math.min(1, deg / this.settings.anglerange), 0);
83    } else {
84      percent = +(deg - this.settings.anglerange < (360 - this.settings.anglerange) / 2);
85    }
86    var range = this.settings.range;
87    var value = this.min + range * percent;
88
89    var step = (this.settings.max - this.min) / range;
90    this.value = this.input.value = Math.round(value / step) * step;
91    this.ui.update(percent, this.value);
92    this.triggerChange();
93  },
94
95  changed: function(direction) {
96    this.input.value = this.limit(parseFloat(this.input.value) + direction * (this.input.step || 1));
97    this.value = this.input.value;
98    this.ui.update(this._valueToPercent(), this.value);
99    this.triggerChange();
100  },
101
102  update: function(value) {
103    this.input.value = this.limit(value);
104    this.value = this.input.value;
105    this.ui.update(this._valueToPercent(), this.value);
106    this.triggerChange();
107  },
108
109  triggerChange: function  () {
110    if (document.createEventObject) {
111      var evt = document.createEventObject();
112      this.input.fireEvent("onchange", evt);
113    } else {
114      this.input.dispatchEvent(new Event('change'));
115    }
116  },
117
118  _valueToPercent: function() {
119    return  this.value != null ? 100 / this.settings.range * (this.value - this.min) / 100 : this.min;
120  },
121
122  limit: function(value) {
123    return Math.min(Math.max(this.settings.min, value), this.settings.max);
124  },
125
126  _getSettings: function(input) {
127    var labels;
128
129    if(input.dataset.labels){
130      labels = input.dataset.labels.split(',');
131    }
132    var settings = {
133      max: labels ? labels.length-1 : parseFloat(input.max),
134      min: labels ? 0 : parseFloat(input.min),
135      step: parseFloat(input.step) || 1,
136      angleoffset: 0,
137      anglerange: 360,
138      labels: labels
139    };
140    settings.range = settings.max - settings.min;
141    var data = input.dataset;
142    for (var i in data) {
143      if (data.hasOwnProperty(i) && i!=='labels') {
144        var value = +data[i];
145        settings[i] = isNaN(value) ? data[i] : value;
146      }
147    }
148    return settings;
149  }
150};
151
152
153
154var Ui = function() {
155};
156
157Ui.prototype = {
158  init: function(parentEl, options) {
159    this.options || (this.options = {});
160    this.merge(this.options, options);
161    this.width = options.width;
162    this.height = options.height;
163    this.createElement(parentEl);
164    if (!this.components) {
165      return;
166    }
167    this.components.forEach(function(component) {
168      component.init(this.el.node, options);
169    }.bind(this));
170  },
171
172  merge: function(dest, src) {
173    for (var i in src) {
174      if (src.hasOwnProperty(i)) {
175        dest[i] = src[i];
176      }
177    }
178    return dest;
179  },
180
181  addComponent: function(component) {
182    this.components || (this.components = []);
183    this.components.push(component);
184  },
185
186  update: function(percent, value) {
187
188    if (!this.components) {
189      return;
190    }
191    this.components.forEach(function(component) {
192      component.update(percent, value);
193    });
194  },
195
196  createElement: function(parentEl) {
197    this.el = new Ui.El(this.width, this.height);
198    this.el.create("svg", {
199      version: "1.2",
200      baseProfile: "tiny",
201      width: this.width,
202      height: this.height
203    });
204    this.appendTo(parentEl);
205  },
206  appendTo: function(parent) {
207    parent.appendChild(this.el.node);
208  }
209
210};
211
212Ui.Pointer = function(options) {
213  this.options = options || {};
214  this.options.type && Ui.El[this.options.type] || (this.options.type = 'Triangle');
215};
216
217Ui.Pointer.prototype = Object.create(Ui.prototype);
218
219Ui.Pointer.prototype.update = function(percent) {
220  this.el.rotate(this.options.angleoffset + percent * this.options.anglerange, this.width / 2,
221    this.height / 2);
222};
223
224Ui.Pointer.prototype.createElement = function(parentEl) {
225  this.options.pointerHeight || (this.options.pointerHeight = this.height / 2);
226  if (this.options.type == 'Arc') {
227    this.el = new Ui.El.Arc(this.options);
228    this.el.setAngle(this.options.size);
229  } else {
230    this.el = new Ui.El[this.options.type](this.options.pointerWidth,
231      this.options.pointerHeight, this.width / 2,
232      this.options.pointerHeight / 2 + this.options.offset);
233  }
234  this.el.addClassName('pointer');
235  this.appendTo(parentEl);
236
237};
238
239Ui.Arc = function(options) {
240  this.options = options || {};
241};
242
243Ui.Arc.prototype = Object.create(Ui.prototype);
244
245Ui.Arc.prototype.createElement = function(parentEl) {
246  this.el = new Ui.El.Arc(this.options);
247  this.appendTo(parentEl);
248};
249
250Ui.Arc.prototype.update = function(percent) {
251  this.el.setAngle(percent * this.options.anglerange);
252};
253
254Ui.Scale = function(options) {
255  this.options = this.merge({
256    steps: options.range / options.step,
257    radius: this.width / 2,
258    tickWidth: 1,
259    tickHeight: 3
260  }, options);
261  this.options.type = Ui.El[this.options.type || 'Rect'];
262};
263
264Ui.Scale.prototype = Object.create(Ui.prototype);
265
266Ui.Scale.prototype.createElement = function(parentEl) {
267  this.el = new Ui.El(this.width, this.height);
268  this.startAngle = this.options.angleoffset || 0;
269  this.options.radius || (this.options.radius = this.height / 2.5);
270  this.el.create("g");
271  this.el.addClassName('scale');
272  if (this.options.drawScale) {
273    if(!this.options.labels){
274      var step = this.options.anglerange / this.options.steps;
275      var end = this.options.steps + (this.options.anglerange == 360 ? 0 : 1);
276      this.ticks = [];
277      var Shape = this.options.type;
278      for (var i = 0; i < end; i++) {
279        var rect = new Shape(this.options.tickWidth, this.options.tickHeight, this.width / 2,
280          this.options.tickHeight / 2);
281        rect.rotate(this.startAngle + i * step, this.width / 2, this.height / 2);
282        this.el.append(rect);
283        this.ticks.push(rect);
284      }
285    }
286  }
287  this.appendTo(parentEl);
288  if (this.options.drawDial) {
289    this.dial();
290  }
291};
292
293Ui.Scale.prototype.dial = function() {
294  var step = this.options.anglerange / this.options.steps;
295  var min = this.options.min;
296  var dialStep = (this.options.max - min) / this.options.steps;
297  var end = this.options.steps + (this.options.anglerange == 360 ? 0 : 1);
298  this.dials = [];
299  if(!this.options.labels){
300    for (var i = 0; i < end; i++) {
301      var text = new Ui.El.Text(Math.abs(min + dialStep * i), this.width / 2 - 2.5,
302        this.height / 2 - this.options.radius, 5, 5);
303      this.el.append(text);
304      text.rotate(this.startAngle + i * step, this.width / 2, this.height / 2);
305      this.dials.push(text);
306    }
307  } else {
308    step = this.options.anglerange / (this.options.labels.length-1);
309    for(var i=0; i<this.options.labels.length; i++){
310      var label = this.options.labels[i];
311      var text = new Ui.El.Text(label, this.width / 2 - 2.5,
312        this.height / 2 - this.options.radius, 5, 5);
313      this.el.append(text);
314      text.rotate(this.startAngle + i * step, this.width / 2, this.height / 2);
315      text.attr('text-anchor', 'middle');
316      this.dials.push(text);
317    }
318
319  }
320};
321
322Ui.Scale.prototype.update = function(percent) {
323  if (this.ticks) {
324    if (this.activeStep) {
325      this.activeStep.attr('class', '');
326    }
327    this.activeStep = this.ticks[Math.round(this.options.steps * percent)];
328    this.activeStep.attr('class', 'active');
329  }
330  if (this.dials) {
331    if (this.activeDial) {
332      this.activeDial.attr('class', '');
333    }
334    this.activeDial = this.dials[Math.round(this.options.steps * percent)];
335    if (this.activeDial) {
336      this.activeDial.attr('class', 'active');
337    }
338  }
339};
340
341Ui.Text = function() {};
342
343Ui.Text.prototype = Object.create(Ui.prototype);
344
345Ui.Text.prototype.createElement = function(parentEl) {
346  this.parentEl = parentEl
347  this.el = new Ui.El.Text('', 0, this.height);
348  this.appendTo(parentEl);
349  this.el.center(parentEl);
350};
351
352Ui.Text.prototype.update = function(percent, value) {
353  this.el.node.textContent = value;
354  this.el.center(this.parentEl);
355};
356
357Ui.El = function() {};
358
359Ui.El.prototype = {
360  svgNS: "http://www.w3.org/2000/svg",
361
362  init: function(width, height, x, y) {
363    this.width = width;
364    this.height = height;
365    this.x = x || 0;
366    this.y = y || 0;
367    this.left = this.x - width / 2;
368    this.right = this.x + width / 2;
369    this.top = this.y - height / 2;
370    this.bottom = this.y + height / 2;
371  },
372  create: function(type, attributes) {
373    this.node = document.createElementNS(this.svgNS, type);
374    for (var key  in attributes) {
375      this.attr(key, attributes[key]);
376    }
377  },
378
379  rotate: function(angle, x, y) {
380    this.attr("transform", "rotate(" + angle + " " + (x || this.x) + " " + (y || this.y ) + ")");
381  },
382
383  attr: function(attributeName, value) {
384    if (value == null) return this.node.getAttribute(attributeName) || '';
385    this.node.setAttribute(attributeName, value);
386  },
387
388  append: function(el) {
389    this.node.appendChild(el.node);
390  },
391
392  addClassName: function(className) {
393    this.attr('class', this.attr('class') + ' ' + className);
394  }
395};
396
397Ui.El.Triangle = function() {
398  this.init.apply(this, arguments);
399  this.create("polygon", {
400    'points': this.left + ',' + this.bottom + ' ' + this.x + ',' + this.top + ' ' + this.right + ',' + this.bottom
401  });
402};
403
404Ui.El.Triangle.prototype = Object.create(Ui.El.prototype);
405
406Ui.El.Rect = function() {
407  this.init.apply(this, arguments);
408  this.create("rect", {
409    x: this.x - this.width / 2,
410    y: this.y,
411    width: this.width,
412    height: this.height
413  });
414};
415
416Ui.El.Rect.prototype = Object.create(Ui.El.prototype);
417
418Ui.El.Circle = function(radius, x, y) {
419  if (arguments.length == 4) {
420    x = arguments[2];
421    y = arguments[3];
422  }
423  this.init(radius * 2, radius * 2, x, y);
424  this.create("circle", {
425    cx: this.x,
426    cy: this.y,
427    r: radius
428  });
429};
430
431Ui.El.Circle.prototype = Object.create(Ui.El.prototype);
432
433Ui.El.Text = function(text, x, y, width, height) {
434  this.create('text', {
435    x: x,
436    y: y,
437    width: width,
438    height: height
439  });
440  this.node.textContent = text;
441};
442
443Ui.El.Text.prototype = Object.create(Ui.El.prototype);
444
445Ui.El.Text.prototype.center = function(element) {
446  var width = element.getAttribute('width');
447  var height = element.getAttribute('height');
448  this.attr('x', width / 2 - this.node.getBBox().width / 2);
449  this.attr('y', height / 2 + this.node.getBBox().height / 4);
450};
451
452Ui.El.Arc = function(options) {
453  this.options = options;
454  //when there are lables, do not shift the arc other wise it will be 180 degree off
455  //compared to the labels
456  this.options.angleoffset = (options.angleoffset || 0) - (this.options.labels?0:90);
457
458  this.create('path');
459};
460
461Ui.El.Arc.prototype = Object.create(Ui.El.prototype);
462
463Ui.El.Arc.prototype.setAngle = function(angle) {
464  this.attr('d', this.getCoords(angle));
465};
466
467
468Ui.El.Arc.prototype.getCoords = function(angle) {
469  var startAngle = this.options.angleoffset;
470  var outerRadius = this.options.outerRadius || this.options.width / 2;
471  var innerRadius = this.options.innerRadius || this.options.width / 2 - this.options.arcWidth;
472  var startAngleDegree = Math.PI * startAngle / 180;
473  var endAngleDegree = Math.PI * (startAngle + angle) / 180;
474  var center = this.options.width / 2;
475
476  var p1 = pointOnCircle(outerRadius, endAngleDegree);
477  var p2 = pointOnCircle(outerRadius, startAngleDegree);
478  var p3 = pointOnCircle(innerRadius, startAngleDegree);
479  var p4 = pointOnCircle(innerRadius, endAngleDegree);
480
481  var path = 'M' + p1.x + ',' + p1.y;
482  var largeArcFlag = ( angle < 180 ? 0 : 1);
483  path += ' A' + outerRadius + ',' + outerRadius + ' 0 ' + largeArcFlag + ' 0 ' + p2.x + ',' + p2.y;
484  path += 'L' + p3.x + ',' + p3.y;
485  path += ' A' + innerRadius + ',' + innerRadius + ' 0 ' + largeArcFlag + ' 1 ' + p4.x + ',' + p4.y;
486  path += 'L' + p1.x + ',' + p1.y;
487  return  path;
488
489  function pointOnCircle(radius, angle) {
490    return {
491      x: center + radius * Math.cos(angle),
492      y: center + radius * Math.sin(angle)
493    };
494  }
495};
496
497(function($) {
498  Ui.P1 = function() {
499
500  };
501  
502  Ui.P1.prototype = Object.create(Ui.prototype);
503  
504  Ui.P1.prototype.createElement = function() {
505    "use strict";
506    Ui.prototype.createElement.apply(this, arguments);
507    this.addComponent(new Ui.Pointer({
508      type: 'Rect',
509      pointerWidth: 5,
510      pointerHeight: this.width / 4,
511      offset: this.width / 2 - this.width / 3.3 - this.width / 10
512    }));
513  
514    this.addComponent(new Ui.Scale(this.merge(this.options, {
515      drawScale: false,
516      drawDial: true,
517      radius: this.width/2.6})));
518  
519    var circle = new Ui.El.Circle(this.width / 3.3, this.width / 2, this.height / 2);
520    this.el.node.appendChild(circle.node);
521    this.el.node.setAttribute("class", "p1");
522  };
523
524  var tvControl = new Knob(document.getElementsByClassName('preset1')[0], new Ui.P1());
525  $('text').attr('class', '');
526  $('text').first().attr('class','active');
527  $('rect').attr('transform', "rotate(270, 72.5, 72.5)");
528
529  document.getElementsByClassName('preset1')[0].addEventListener('change', function(el) {
530    var knobNumber = this.value
531    var targetVideo = "#slick-slide-control0"+knobNumber;
532    $(targetVideo).trigger('click');
533  });
534
535  $('.scale text').on('click', function(){
536    var knobNumber = parseInt($(this).text()) - 1;
537    var targetVideo = "#slick-slide-control0"+knobNumber;
538
539
540    $('text').attr('class', '');
541    $(this).attr('class', 'active');
542
543    $('rect').attr('transform', $(this).attr('transform'))
544    $(targetVideo).trigger('click');        
545  });
546
547})(jQuery); // end of jQuery name space

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.