PageSourceSearch

https://groundupmusic.net/lib/nano-player.js

js groundupmusic.net collected 2026-10-02 12:10:03 UTC 5,301 bytes, 146 lines download raw bytes

1angular.module('NanoPlayer', [])
2  .service('NanoPlayerService', function () {
3    var service = {};
4
5    service.playerCss = `
6      .nano-player panel {
7        display: block;
8        margin: 0px auto;
9        padding: 5px;
10        font-size: 30px;
11      }
12      .nano-player button {
13        display: inline-block;
14        background: none;
15        border: none;
16        padding: 3px 0px;
17        cursor: pointer;
18        font-size: 30px;
19        margin: 0;
20        margin-right: -2px;
21        transition: all 0.2s;
22      }
23      .nano-player button:hover {
24        color: #a0b0ff;
25        opacity: 0.5;
26      }
27    `;
28
29    service.panel = `
30    <panel>
31      <button act="play" class="fa fa-play-circle"></button>
32      <button act="pause" class="fa fa-pause-circle"></button>
33      <button act="reset" class="fa fa-backward" style="font-size: 24px; position: relative; top: -2px;"></button>
34    </panel>
35    `;
36
37    service.forward = `<button act="forward" class="fa fa-forward ml10"></button>`;
38    service.rewind = `<button act="back" class="fa fa-backward mr10"></button>`;
39
40    service.players = {};
41
42    service.onPlayerPlay = function (playerId) {
43      Object.keys(service.players).forEach(pid => {
44        if (pid === playerId) {
45          $('[player-id=' + pid + ']').find('[act="play"]').css({ color: '#ebb710' })
46          $('[player-id=' + pid + ']').find('[act="pause"]').css({ color: 'white' })
47          service.players[pid].play();
48        } else {
49          $('[player-id=' + pid + ']').find('[act="play"]').css({ color: 'white' })
50          $('[player-id=' + pid + ']').find('[act="pause"]').css({ color: 'white' })
51          service.players[pid].pause();
52        }
53      })
54    };
55    service.onPlayerPause = function (playerId) {
56      Object.keys(service.players).forEach(pid => {
57        if (pid === playerId) {
58          $('[player-id=' + pid + ']').find('[act="play"]').css({ color: 'white' })
59          $('[player-id=' + pid + ']').find('[act="pause"]').css({ color: '#ebb710' })
60          service.players[pid].pause();
61        } else {
62          $('[player-id=' + pid + ']').find('[act="play"]').css({ color: 'white' })
63          $('[player-id=' + pid + ']').find('[act="pause"]').css({ color: 'white' })
64          service.players[pid].pause();
65        }
66      })
67    };
68
69
70    service.registerPlayer = function (playerId, player) {
71      service.players[playerId] = player;
72    };
73
74    service.installStyle = function () {
75      if (!$('#nano-player-css').length) {
76        $('<style></style>')
77          .attr('id', 'nano-player-css')
78          .attr('type', 'text/css')
79          .append(service.playerCss)
80          .appendTo('head');
81      }
82    }
83    return service;
84  })
85  .directive('nanoTrigger', ['NanoPlayerService', function (NanoPlayerService) {
86    return {
87      restrict: 'A',
88      link: (scope, el, attrs) => {
89        el.on('click', function () {
90          if (attrs.nanoTrigger) {
91            NanoPlayerService.onPlayerPlay(attrs.nanoTrigger);
92          }
93        })
94      }
95    }
96  }])
97  .directive('mp3Player', ['NanoPlayerService', function (NanoPlayerService) {
98    return {
99      restrict: 'E',
100      template: (c, attr) => `<audio ng-src="${attr.src}" type="audio/mp3" preload="auto"></audio>`,
101      link: (scope, element, attributes) => {
102        NanoPlayerService.installStyle();
103        $(element).addClass('nano-player').append(NanoPlayerService.panel);
104
105        let playerId = attributes.playerId || (Math.random()).toString().split('.').join('');
106        $(element).attr('player-id', playerId);
107        let player = $(element).find('audio').get(0);
108        let buttons = $(element).find('button');
109
110        buttons.filter('[act="play"]').click((e) => {
111          e.stopPropagation();
112          NanoPlayerService.onPlayerPlay(playerId);
113        });
114        buttons.filter('[act="pause"]').click((e) => {
115          e.stopPropagation();
116          NanoPlayerService.onPlayerPause(playerId);
117        });
118        buttons.filter('[act="reset"]').click((e) => player.currentTime = 0);
119
120        NanoPlayerService.registerPlayer(playerId, player)
121      }
122    }
123  }])
124  .directive('mp4Player', ['NanoPlayerService', function (NanoPlayerService) {
125    return {
126      restrict: 'E',
127      template: (c, attr) => `<video ng-src="${attr.src}" type="video/mpeg"></video>`,
128      link: (scope, element, attributes) => {
129        NanoPlayerService.installStyle();
130        $(element).addClass('nano-player').append(NanoPlayerService.panel);
131        if (attributes.extended) $(element).find('panel').prepend(NanoPlayerService.rewind).append(NanoPlayerService.forward);
132        if (attributes.poster) $(element).find('video').attr('poster', attributes.poster);
133
134        let player = $(element).find('video').get(0);
135        let buttons = $(element).find('button');
136
137        $(player).click(function () { player.play(); })
138
139        buttons.filter('[act="play"]').click((e) => player.play());
140        buttons.filter('[act="pause"]').click((e) => player.pause());
141        buttons.filter('[act="reset"]').click((e) => player.currentTime = 0);
142        buttons.filter('[act="forward"]').click((e) => player.currentTime = player.currentTime + 5);
143        buttons.filter('[act="back"]').click((e) => player.currentTime = player.currentTime - 5);
144      }
145    }
146  }]);

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.