diff --git a/JukeBox/settings.py b/JukeBox/settings.py index d316a0e..1b9919d 100644 --- a/JukeBox/settings.py +++ b/JukeBox/settings.py @@ -73,7 +73,7 @@ ) -SITE_ID = 1 +SITE_ID = 2 MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', diff --git a/manager/admin.py b/manager/admin.py index 3f18eb2..4b37be1 100644 --- a/manager/admin.py +++ b/manager/admin.py @@ -1,9 +1,10 @@ from django.contrib import admin -from manager.models import Playlist, Track, Artist, PlaylistEntry +from manager.models import Playlist, Track, Artist, PlaylistEntry, PlaylistSession admin.site.register(Playlist) admin.site.register(Track) admin.site.register(Artist) admin.site.register(PlaylistEntry) +admin.site.register(PlaylistSession) # Register your models here. diff --git a/manager/models.py b/manager/models.py index 4c5d612..e432b9a 100644 --- a/manager/models.py +++ b/manager/models.py @@ -1,18 +1,22 @@ from django.db import models -import pprint -import sys -import os -import subprocess +import unicodedata import requests import json -def import_playlists(userid = 674215921): - user_playlists=json.loads(requests.get("https://api.deezer.com/user/" + str(userid) + "/playlists").text)['data'] +# from fields import JSONField +from json_field import JSONField +import json + + +def import_playlists(userid=674215921): + user_playlists = json.loads(requests.get( + "https://api.deezer.com/user/" + str(userid) + "/playlists").text)['data'] for playlist in user_playlists: - json_result=requests.get("https://api.deezer.com/playlist/" + str(playlist['id'])) - playlist_tracks=json.loads(json_result.text)['tracks']['data'] - if not Playlist.objects.filter(DeezerId= int(playlist['id'])).exists(): + json_result = requests.get( + "https://api.deezer.com/playlist/" + str(playlist['id'])) + playlist_tracks = json.loads(json_result.text)['tracks']['data'] + if not Playlist.objects.filter(DeezerId=int(playlist['id'])).exists(): pl = Playlist() pl.title = playlist['title'] pl.DeezerId = playlist['id'] @@ -23,7 +27,7 @@ def import_playlists(userid = 674215921): pl.save() for track in playlist_tracks: - if not Artist.objects.filter(DeezerId= int(track['artist']['id'])).exists(): + if not Artist.objects.filter(DeezerId=int(track['artist']['id'])).exists(): art = Artist() art.name = track['artist']['name'] art.DeezerId = track['artist']['id'] @@ -31,17 +35,19 @@ def import_playlists(userid = 674215921): # art.picture = track['artist']['picture'] art.save() - if not Track.objects.filter(DeezerId= int(track['id'])).exists(): + if not Track.objects.filter(DeezerId=int(track['id'])).exists(): tr = Track() tr.title = track['title'] tr.DeezerId = track['id'] tr.link = track['link'] tr.duration = track['duration'] - tr.ArtistId = Artist.objects.filter(DeezerId=int(track['artist']['id'])).first() + tr.ArtistId = Artist.objects.filter( + DeezerId=int(track['artist']['id'])).first() tr.save() tr_id = Track.objects.filter(DeezerId=int(track['id'])).first() - pl_id = Playlist.objects.filter(DeezerId=int(playlist['id'])).first() + pl_id = Playlist.objects.filter( + DeezerId=int(playlist['id'])).first() if not PlaylistEntry.objects.filter(TrackId=tr_id, PlaylistId=pl_id).exists(): pl_ent = PlaylistEntry() @@ -51,6 +57,8 @@ def import_playlists(userid = 674215921): pl_ent.save() # Create your models here. + + class Playlist(models.Model): title = models.CharField(max_length=100) DeezerId = models.IntegerField(unique=True) @@ -73,7 +81,7 @@ def to_dict(self): "link": self.link, "picture": self.picture, "duration": self.duration, - "Tracks": [ a.TrackId.to_dict() for a in self.playlistentry_set.all() ] + # "Tracks": [a.TrackId.to_dict() for a in self.playlistentry_set.all()] } return dico @@ -93,7 +101,8 @@ class Artist(models.Model): def to_dict(self): dico = { - "name": self.name, + "name": remove_accents(self.name[:16]), + # "name": self.name, "DeezerId": self.DeezerId, "link": self.link, "picture": self.picture, @@ -103,6 +112,7 @@ def to_dict(self): def __str__(self): # __unicode__ on Python 2 return self.name + class Track(models.Model): title = models.CharField(max_length=100) DeezerId = models.IntegerField(unique=True) @@ -112,13 +122,15 @@ class Track(models.Model): def to_dict(self): dico = { - "title": self.title, + "title": remove_accents(self.title[:25]), + # "title": self.title, "DeezerId": self.DeezerId, "link": self.link, "duration": self.duration, "minutes": self.getMinutes(), "msec": self.getmSec(), "Artist": None, + "vote": 0 } art = Artist.objects.get(id=self.ArtistId.id) @@ -144,6 +156,25 @@ class PlaylistEntry(models.Model): TrackId = models.ForeignKey(Track) def __str__(self): # __unicode__ on Python 2 - string = self.PlaylistId.title + ' - ' + str(elf.TrackId.title) + string = self.PlaylistId.title + ' - ' + str(self.TrackId.title) return string + def to_dict(self): + dico = {} + return dico + +class PlaylistSession(models.Model): + Session = JSONField(blank=True, null=True) + # Session = JSONField(blank=True, null=True) + + def __str__(self): # __unicode__ on Python 2 + # string = self.PlaylistId.title + ' - ' + str(elf.TrackId.title) + return str(self.id) + + +def remove_accents(input_str): + nkfd_form = unicodedata.normalize('NFKD', input_str) + only_ascii = nkfd_form.encode('ASCII', 'ignore') + return only_ascii + + diff --git a/manager/templates/manager/nodejs_manager.html b/manager/templates/manager/nodejs_manager.html index 538509c..8fba33c 100644 --- a/manager/templates/manager/nodejs_manager.html +++ b/manager/templates/manager/nodejs_manager.html @@ -17,7 +17,7 @@ }); function playOn(){ - socket.emit('playlistOn', "{{ playlist.to_json }}".replace(/"/g,"\"") ); + socket.emit('playlistOn', "{{ context }}".replace(/"/g,"\"") ); } function playOff(){ socket.emit('playlistOff', "Aucune playlist en ligne" ); diff --git a/manager/templates/manager/track_list.html b/manager/templates/manager/track_list.html index c0670e7..b56cd41 100644 --- a/manager/templates/manager/track_list.html +++ b/manager/templates/manager/track_list.html @@ -1,6 +1,6 @@ (L'id de la playlist est : {{ playlist.DeezerId }}) - ({{ playlist.getMinutes }}) + ({{ playlist.duration }})
Liste des morceaux : @@ -15,11 +15,11 @@ - {% for tr in track_list %} + {% for tr in tracks %} - {{tr.TrackId.title}} - {{tr.TrackId.ArtistId.name}} - {{tr.TrackId.getMinutes}} + {{tr.title}} + {{tr.Artist.name}} + {{tr.duration}} {% endfor %} diff --git a/manager/urls.py b/manager/urls.py index 58f46e6..c3ef215 100644 --- a/manager/urls.py +++ b/manager/urls.py @@ -7,4 +7,8 @@ url(r'^selection/', views.select, name='select'), url(r'^update/', views.update, name='update'), url(r'^playing/', views.playing, name='play'), + url(r'^createSession/', views.createSession, name='newSession'), + url(r'^getSession/', views.getSession, name='getSession'), + url(r'^next/', views.nextTrack, name='next'), + url(r'^vote/', views.newVote, name='vote'), ) \ No newline at end of file diff --git a/manager/views.py b/manager/views.py index a36a01d..ec420c8 100644 --- a/manager/views.py +++ b/manager/views.py @@ -1,28 +1,177 @@ from django.shortcuts import get_object_or_404, render from django.http import HttpResponse -from manager.models import Playlist, PlaylistEntry, import_playlists -# Create your views here. -#def index(request): -# return HttpResponse("Hello, world. You're at the manager page.") +from models import Playlist, Track, PlaylistEntry, import_playlists, PlaylistSession + +import json + +from random import randrange def index(request): - playlists = Playlist.objects.all() - return render(request, 'manager/index.html', {'playlists' : playlists}) + playlists = Playlist.objects.all() + return render(request, 'manager/index.html', {'playlists': playlists}) + def update(request): - import_playlists() - playlists = Playlist.objects.all() - return render(request, 'manager/index.html', {'playlists' : playlists}) + import_playlists() + playlists = Playlist.objects.all() + return render(request, 'manager/index.html', {'playlists': playlists}) + def select(request): - playlists = Playlist.objects.all() - return render(request, 'manager/index.html', {'playlists' : playlists}) + playlists = Playlist.objects.all() + return render(request, 'manager/index.html', {'playlists': playlists}) + + +def createSession(request): + ''' + Create a new playlist session (json format) from + a playlist id in a post request and + save it in th db + ''' + + data = {"playlist": None, + "current_track": None, + "tracks": None, + "played": None, + } + + if 'choice' in request.POST: + playlist_id = request.POST['choice'] + playlist = get_object_or_404(Playlist, DeezerId=int(playlist_id)) + + dplaylist = playlist.to_dict() + + track_list = PlaylistEntry.objects.all().filter(PlaylistId=playlist.id) + ldtracks = [] + + for entry in track_list: + ldtracks.append(entry.TrackId.to_dict()) + # print entry.TrackId.to_dict() + + # print ldtracks + current_track = track_list[0].TrackId.to_dict() + dcurrent_track = current_track + + # print current_track + + data = {"playlist": dplaylist, + "current_track": dcurrent_track, + "tracks": ldtracks} + + jspData = json.dumps(data, sort_keys=True, indent=4) + new_session = PlaylistSession() + new_session.Session = jspData + new_session.save() + + if 'callback' in request.GET: + jspData = request.GET['callback'] + '(' + jsData + ');' + + return HttpResponse(jspData, content_type='application/json') + + +def getSession(request): + if 'session_id' in request.POST: + sess = get_object_or_404( + PlaylistSession, id=request.POST['session_id']) + + elif 'session_id' in request.GET: + sess = get_object_or_404(PlaylistSession, id=request.GET['session_id']) + + else: + sess = PlaylistSession.objects.all()[0] + + jspData = json.dumps(sess.Session, sort_keys=True, indent=4) + + print jspData + + return HttpResponse(jspData, content_type='application/json') + + +def nextTrack(request): + if 'session_id' in request.POST: + sess = get_object_or_404( + PlaylistSession, id=request.POST['session_id']) + + elif 'session_id' in request.GET: + sess = get_object_or_404(PlaylistSession, id=request.GET['session_id']) + + else: + sess = PlaylistSession.objects.all()[0] + + # >>> sorted(student_objects, key=lambda student: student.age) # sort by age + # [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] + track_list = sess.Session["tracks"] + toReset = sess.Session['current_track']['DeezerId'] + + for i in range(len(sess.Session["tracks"])): + if str(toReset) == str(sess.Session["tracks"][i]["DeezerId"]): + sess.Session["tracks"][i]["vote"] = 0 + # sess.save() + + maxVote = 0 + # nextTrack = sess.Session["current_track"]["DeezerId"] + # nextTrack = track_list[0]["DeezerId"] + nextTrack = track_list[randrange(len(track_list))]["DeezerId"] + + for track in track_list: + if int(track['vote']) > maxVote: + maxVote = int(track['vote']) + nextTrack = track["DeezerId"] + print nextTrack + + current_track = get_object_or_404(Track, DeezerId=nextTrack) + dcurrent_track = current_track.to_dict() + + sess.Session["current_track"] = dcurrent_track + + sess.save() + + jspData = json.dumps(sess.Session, sort_keys=True, indent=4) + + return HttpResponse(jspData, content_type='application/json') + + +def newVote(request): + if 'session_id' in request.POST: + sess = get_object_or_404( + PlaylistSession, id=request.POST['session_id']) + + elif 'session_id' in request.GET: + sess = get_object_or_404(PlaylistSession, id=request.GET['session_id']) + + else: + sess = PlaylistSession.objects.all()[0] + + if 'vote_id'in request.GET: + sess = PlaylistSession.objects.all()[0] + print "vote_id " + request.GET['vote_id'] + print "tracks : ", sess.Session["tracks"][0]["DeezerId"] + for i in range(len(sess.Session["tracks"])): + print "tracks : ", sess.Session["tracks"][i]["DeezerId"] + if request.GET['vote_id'] == str(sess.Session["tracks"][i]["DeezerId"]): + print "nbre de vote :" # , sess.Session.tracks[i].vote + sess.Session["tracks"][i]["vote"] += 1 + print sess.Session["tracks"][i]["vote"] + sess.save() + + return HttpResponse(sess, content_type='application/json') + def playing(request): - playlist = get_object_or_404(Playlist, DeezerId=int(request.POST['choice'])) - track_list = PlaylistEntry.objects.all().filter(PlaylistId=playlist.id) - player_type = 'playlist' - context = {'playlist' : playlist, 'track_list' : track_list, 'type' : player_type } - return render(request, 'manager/playing.html', context) \ No newline at end of file + createSession(request) + sess = PlaylistSession.objects.all()[0] + # playlist = sess.Session["playlist"] + # track_list = PlaylistEntry.objects.all().filter(PlaylistId=playlist.id) + # player_type = 'playlist' + # context = {'playlist': playlist, + # 'track_list': track_list, 'type': player_type} + + context = sess.Session + # context = json.load(sess.Session) + + print context + # for tr in context['tracks']: + # print tr + return render(request, 'manager/playing.html', context) diff --git a/nodejs/server.js b/nodejs/server.js index cb81ac0..df5fb1c 100644 --- a/nodejs/server.js +++ b/nodejs/server.js @@ -12,33 +12,37 @@ var io = require('socket.io').listen(httpServer); var playlist = "Aucune playlist n'a été mise en ligne"; var playlistOnline = false; var votes; -var current_trackId; +var current_track; var limit; +var request = require("request") +var url = "http://0.0.0.0:8000/manager/getSession/" +var session = "plop"; +var cnt = 0; var nsp_manager = io.of('/manager'); nsp_manager.on('connection', function(socket){ console.log('Manager connected'); socket.emit('connected', 'Hi Manager!'); socket.on('playlistOn', function (message) { + + // getJSON(url, function (body) { + // console.log('we have the body!', body); + // console.log(session, cnt); // Print the json response + // session = body; + // cnt = cnt + 1; + // console.log(session, cnt); // Print the json response + // }); + console.log(session, cnt); // Print the json response limit = 5; - //if (JSON.parse(message).Tracks.length > limit){ - // playlist = limitedPlaylist(message, limit); - //} else { - playlist = message ; - //} + console.log('Manager says : ' + session.playlist.title); playlistOnline = true; - console.log('Manager says : ' + JSON.parse(playlist).title); - nsp_player.emit('playlistOn', playlist); - nsp_voting.emit('playlistOn', playlist); - current_trackId = JSON.parse(playlist).Tracks[0].DeezerId; - nsp_player.emit('current_track', current_trackId); - votes = []; - for(var index in JSON.parse(playlist).Tracks){ - console.log(index+": "+ JSON.parse(playlist).Tracks[index].title); - votes.push(0); + nsp_player.emit('playlistOn', session); + nsp_voting.emit('playlistOn', session); + current_track = session.current_track; + nsp_player.emit('current_track', session); + for(var index in session.tracks){ + console.log(index+": "+ session.tracks[index].title); } - nsp_player.emit('votes', votes); - setTimeout(reset, JSON.parse(playlist).Tracks[0].msec); }); @@ -52,6 +56,17 @@ nsp_manager.on('connection', function(socket){ }); +function getJSON(url, callback) { + request({ + url: url, + json: true + }, function (error, response, body) { + if (!error && response.statusCode === 200) { + callback(body); + } + }); +} + function limitedPlaylist(playlist, limit){ var newPlaylist = playlist; var newPlaylistJSon = JSON.parse(newPlaylist); @@ -72,8 +87,8 @@ function reset(){ var maxIndex = votes.indexOf(Math.max.apply(Math, votes)); console.log(maxIndex + " : " + JSON.parse(playlist).Tracks[maxIndex].title + " - msec : " + JSON.parse(playlist).Tracks[maxIndex].msec); - current_trackId = JSON.parse(playlist).Tracks[maxIndex].DeezerId; - nsp_player.emit('current_track', current_trackId); + current_track = JSON.parse(playlist).Tracks[maxIndex]; + nsp_player.emit('current_track', current_track); setTimeout(reset, JSON.parse(playlist).Tracks[maxIndex].msec); } } @@ -83,9 +98,7 @@ nsp_player.on('connection', function(socket){ console.log('Player connected'); socket.emit('connected', 'Hi Player!'); if(playlistOnline){ - socket.emit('playlistOn', playlist); - socket.emit('votes', votes); - socket.emit('current_track', current_trackId); + socket.emit('playlistOn', session); } else{socket.emit('playlistOff', playlist);} @@ -95,13 +108,18 @@ var nsp_voting = io.of('/voting'); nsp_voting.on('connection', function(socket){ console.log('Voting connected'); socket.emit('connected', 'Hi Voting!'); - if(playlistOnline){socket.emit('playlistOn', playlist);} + if(playlistOnline){socket.emit('playlistOn', session);} else{socket.emit('playlistOff', playlist);} socket.on('vote', function (message) { console.log('Voting says : ' + message); - votes[message]++; - nsp_player.emit('votes', votes); + for (var i = session.tracks.length - 1; i >= 0; i--) { + if (session.tracks[i].DeezerId == message) { + session.tracks[i].vote++; + }; + }; + nsp_player.emit('votes', session, message); + }); }); @@ -113,3 +131,20 @@ io.sockets.on('connection', function (socket) { }); }); + +var request = require("request") + +var url = "http://0.0.0.0:8000/manager/getSession/" + +request({ + url: url, + json: true +}, function (error, response, body) { + + if (!error && response.statusCode === 200) { + console.log(body) // Print the json response + console.log('Manager says : ' + body.playlist.title) + session = body + } +}) + diff --git a/player/static/player/css/style.css b/player/static/player/css/style.css new file mode 100644 index 0000000..454011b --- /dev/null +++ b/player/static/player/css/style.css @@ -0,0 +1,205 @@ +@font-face{ + font-family: 'AtlanticCruisedemo'; + src: local('AtlanticCruiseDemo'), + url('../fonts/AmericanCaptain.ttf') format('truetype'); + font-weight: 300; + font-style: normal; +} + + + +body{ +/* font-family: 'AtlanticCruisedemo';*/ +/* font-size:180%;*/ +/* color: #292622;*/ +/* background-position: top center, bottom center;*/ + background-image: url("../img/background.jpg"); + /*background-position: center center;*/ + background-size: 100% ; + background-repeat: no-repeat; + background-color: #020606 ; + } + +#player{ + /*background-image: url("../img/board.png");*/ + background-size: 100% ; + background-repeat: no-repeat; + height: 90vh; + width: 40vw; + margin-left: 5%; + /*margin-right: 50%;*/ + float: left; +} + +#scroll{ + height: 6vh; + padding-top:37vh; + padding-left:15vw; + /*padding-right:2vw;*/ +} + +#album{ + padding-left:16.7vw; + /*padding-top:37vh;*/ + height: 12vh; + width: 12vh; +} + +#timer{ + padding-left:19vw; +} + +#album img +{ +max-width:100%; +max-height:100%; +margin:auto; +display:block; +} + +#blackboard{ + background-image: url("../img/board.png"); + background-size: 100% ; + background-repeat: no-repeat; + height: 90vh; + width: 40%; + /*margin-top:2%;*/ + /*margin-left: 55%;*/ + margin-right: 8%; + /*padding-top:50%;*/ + float: right; +} + +#playlist{ + /*font: 400 100px/1.3 'Oleo Script', Helvetica, sans-serif;*/ + font: 400 100px/1.2 'Merienda One', Helvetica, sans-serif; + color: #F2F5A9; + font-size:1.5vw; + /*font-size:40%;*/ + /*size: 40%; */ + width: 72%; + height: 80vh; + position: center; + /*margin-top:5%;*/ + margin-left: 14%; + padding-top:15%; +} + +#label{ + background-image: url("../img/label.png"); + background-size: 100% ; + background-repeat: no-repeat; + height: 10vh; + width: 50vh; +} + +#title{ + text-align: center; + margin-right: 15%; + padding-top: 2%; +} + +#rank{ + text-align: center; + /*margin-left: 10%;*/ + margin-right: 5%; + /*margin-bottom: 10%;*/ + float: right; + padding-top: 5%; + /*width: 26%;*/ +} + +#artist{ + text-align: center; + padding-bottom: 2%; + width: 80%; + padding-top: 2%; + + +} + +.light { + width: 5px; + height: 5px; + margin: 1px 1px; + text-align: center; + font-size: 15px; + float: left; + border-radius: 50%; +} + +.off { background-color: #121212; } + +.on { background-color: green; } + + +#min{ + padding-top:8px; +} + +#header { + color: #292622; + background-image: url("../images/jukeboxlogo-1.gif"), url("../images/banner.png"); + /*background-image: url() , url("../images/banner.png");*/ + background-position: center 70%, top center; + background-repeat: no-repeat, no-repeat ; + background-size: 30%, 85% ; + background-color: #020606 ; + padding: 28%; +} +#headsec { + color: #292622; + background-image: url("../images/head_section.png"); + background-position: top center; + background-repeat: repeat-y; + background-size: 85% ; + background-color: #020606 ; +} +#section { + color: #292622; + background-image: url("../images/section.png"); + background-position: top center; + background-repeat: repeat-y; + background-size: 85% ; + background-color: #020606 ; +} + +#ticket{ + /*display:inline-block;*/ + background-repeat: no-repeat; + background-size: 30%, 50%; + background-color: #004C4C ; + width:100%; + height: 150px ; + margin-bottom:15px; + margin-left:auto; + margin-right:auto; +/* margin-top:15px; +*/ +} + +/* */ + +#bsection { + color: #292622; + background-image: url("../images/big_section.png"); + background-position: top center; + background-repeat: repeat-y; + background-size: 85% ; + background-color: #020606 ; +} +#footer { + color: #292622; + background-image: url("../images/footer.png"); + /*background-image: url("../images/disc.gif ");*/ + background-position: bottom center; + background-repeat: no-repeat; + background-size: 85% ; + background-color: #020606 ; + padding:20%; + +} + +#Container .mix{ + /*display: none;*/ +} diff --git a/player/static/player/img/background.jpg b/player/static/player/img/background.jpg new file mode 100644 index 0000000..c73fa08 Binary files /dev/null and b/player/static/player/img/background.jpg differ diff --git a/player/static/player/img/board.png b/player/static/player/img/board.png new file mode 100644 index 0000000..e1fd283 Binary files /dev/null and b/player/static/player/img/board.png differ diff --git a/player/static/player/img/label.png b/player/static/player/img/label.png new file mode 100644 index 0000000..9ab1f18 Binary files /dev/null and b/player/static/player/img/label.png differ diff --git a/player/static/player/js/design.js b/player/static/player/js/design.js new file mode 100644 index 0000000..42b5e09 --- /dev/null +++ b/player/static/player/js/design.js @@ -0,0 +1,21 @@ + + +$(function(){ + var options = { + pixelSize: 10, + stepDelay: 40, + horizontalPixelsCount:5, + verticalPixelsCount:5, + pixelRatio: 0.8, + runImmidiatly: false + }; + $('.crl').leddisplay(options); + + $('.crl').find('div').click(function(){ + if ($(this).css('background-color') == 'rgb(255, 0, 0)') + $(this).css('background-color', "#404040") + else + $(this).css('background-color', 'red') + + }); +}) \ No newline at end of file diff --git a/player/static/player/js/excanvas.js b/player/static/player/js/excanvas.js new file mode 100755 index 0000000..367764b --- /dev/null +++ b/player/static/player/js/excanvas.js @@ -0,0 +1,924 @@ +// Copyright 2006 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// Known Issues: +// +// * Patterns are not implemented. +// * Radial gradient are not implemented. The VML version of these look very +// different from the canvas one. +// * Clipping paths are not implemented. +// * Coordsize. The width and height attribute have higher priority than the +// width and height style values which isn't correct. +// * Painting mode isn't implemented. +// * Canvas width/height should is using content-box by default. IE in +// Quirks mode will draw the canvas using border-box. Either change your +// doctype to HTML5 +// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype) +// or use Box Sizing Behavior from WebFX +// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html) +// * Non uniform scaling does not correctly scale strokes. +// * Optimize. There is always room for speed improvements. + +// Only add this code if we do not already have a canvas implementation +if (!document.createElement('canvas').getContext) { + +(function() { + + // alias some functions to make (compiled) code shorter + var m = Math; + var mr = m.round; + var ms = m.sin; + var mc = m.cos; + var abs = m.abs; + var sqrt = m.sqrt; + + // this is used for sub pixel precision + var Z = 10; + var Z2 = Z / 2; + + /** + * This funtion is assigned to the elements as element.getContext(). + * @this {HTMLElement} + * @return {CanvasRenderingContext2D_} + */ + function getContext() { + return this.context_ || + (this.context_ = new CanvasRenderingContext2D_(this)); + } + + var slice = Array.prototype.slice; + + /** + * Binds a function to an object. The returned function will always use the + * passed in {@code obj} as {@code this}. + * + * Example: + * + * g = bind(f, obj, a, b) + * g(c, d) // will do f.call(obj, a, b, c, d) + * + * @param {Function} f The function to bind the object to + * @param {Object} obj The object that should act as this when the function + * is called + * @param {*} var_args Rest arguments that will be used as the initial + * arguments when the function is called + * @return {Function} A new function that has bound this + */ + function bind(f, obj, var_args) { + var a = slice.call(arguments, 2); + return function() { + return f.apply(obj, a.concat(slice.call(arguments))); + }; + } + + var G_vmlCanvasManager_ = { + init: function(opt_doc) { + if (/MSIE/.test(navigator.userAgent) && !window.opera) { + var doc = opt_doc || document; + // Create a dummy element so that IE will allow canvas elements to be + // recognized. + doc.createElement('canvas'); + doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); + } + }, + + init_: function(doc) { + // create xmlns + if (!doc.namespaces['g_vml_']) { + doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml', + '#default#VML'); + + } + if (!doc.namespaces['g_o_']) { + doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office', + '#default#VML'); + } + + // Setup default CSS. Only add one style sheet per document + if (!doc.styleSheets['ex_canvas_']) { + var ss = doc.createStyleSheet(); + ss.owningElement.id = 'ex_canvas_'; + ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + + // default size is 300x150 in Gecko and Opera + 'text-align:left;width:300px;height:150px}' + + 'g_vml_\\:*{behavior:url(#default#VML)}' + + 'g_o_\\:*{behavior:url(#default#VML)}'; + + } + + // find all canvas elements + var els = doc.getElementsByTagName('canvas'); + for (var i = 0; i < els.length; i++) { + this.initElement(els[i]); + } + }, + + /** + * Public initializes a canvas element so that it can be used as canvas + * element from now on. This is called automatically before the page is + * loaded but if you are creating elements using createElement you need to + * make sure this is called on the element. + * @param {HTMLElement} el The canvas element to initialize. + * @return {HTMLElement} the element that was created. + */ + initElement: function(el) { + if (!el.getContext) { + + el.getContext = getContext; + + // Remove fallback content. There is no way to hide text nodes so we + // just remove all childNodes. We could hide all elements and remove + // text nodes but who really cares about the fallback content. + el.innerHTML = ''; + + // do not use inline function because that will leak memory + el.attachEvent('onpropertychange', onPropertyChange); + el.attachEvent('onresize', onResize); + + var attrs = el.attributes; + if (attrs.width && attrs.width.specified) { + // TODO: use runtimeStyle and coordsize + // el.getContext().setWidth_(attrs.width.nodeValue); + el.style.width = attrs.width.nodeValue + 'px'; + } else { + el.width = el.clientWidth; + } + if (attrs.height && attrs.height.specified) { + // TODO: use runtimeStyle and coordsize + // el.getContext().setHeight_(attrs.height.nodeValue); + el.style.height = attrs.height.nodeValue + 'px'; + } else { + el.height = el.clientHeight; + } + //el.getContext().setCoordsize_() + } + return el; + } + }; + + function onPropertyChange(e) { + var el = e.srcElement; + + switch (e.propertyName) { + case 'width': + el.style.width = el.attributes.width.nodeValue + 'px'; + el.getContext().clearRect(); + break; + case 'height': + el.style.height = el.attributes.height.nodeValue + 'px'; + el.getContext().clearRect(); + break; + } + } + + function onResize(e) { + var el = e.srcElement; + if (el.firstChild) { + el.firstChild.style.width = el.clientWidth + 'px'; + el.firstChild.style.height = el.clientHeight + 'px'; + } + } + + G_vmlCanvasManager_.init(); + + // precompute "00" to "FF" + var dec2hex = []; + for (var i = 0; i < 16; i++) { + for (var j = 0; j < 16; j++) { + dec2hex[i * 16 + j] = i.toString(16) + j.toString(16); + } + } + + function createMatrixIdentity() { + return [ + [1, 0, 0], + [0, 1, 0], + [0, 0, 1] + ]; + } + + function matrixMultiply(m1, m2) { + var result = createMatrixIdentity(); + + for (var x = 0; x < 3; x++) { + for (var y = 0; y < 3; y++) { + var sum = 0; + + for (var z = 0; z < 3; z++) { + sum += m1[x][z] * m2[z][y]; + } + + result[x][y] = sum; + } + } + return result; + } + + function copyState(o1, o2) { + o2.fillStyle = o1.fillStyle; + o2.lineCap = o1.lineCap; + o2.lineJoin = o1.lineJoin; + o2.lineWidth = o1.lineWidth; + o2.miterLimit = o1.miterLimit; + o2.shadowBlur = o1.shadowBlur; + o2.shadowColor = o1.shadowColor; + o2.shadowOffsetX = o1.shadowOffsetX; + o2.shadowOffsetY = o1.shadowOffsetY; + o2.strokeStyle = o1.strokeStyle; + o2.globalAlpha = o1.globalAlpha; + o2.arcScaleX_ = o1.arcScaleX_; + o2.arcScaleY_ = o1.arcScaleY_; + o2.lineScale_ = o1.lineScale_; + } + + function processStyle(styleString) { + var str, alpha = 1; + + styleString = String(styleString); + if (styleString.substring(0, 3) == 'rgb') { + var start = styleString.indexOf('(', 3); + var end = styleString.indexOf(')', start + 1); + var guts = styleString.substring(start + 1, end).split(','); + + str = '#'; + for (var i = 0; i < 3; i++) { + str += dec2hex[Number(guts[i])]; + } + + if (guts.length == 4 && styleString.substr(3, 1) == 'a') { + alpha = guts[3]; + } + } else { + str = styleString; + } + + return {color: str, alpha: alpha}; + } + + function processLineCap(lineCap) { + switch (lineCap) { + case 'butt': + return 'flat'; + case 'round': + return 'round'; + case 'square': + default: + return 'square'; + } + } + + /** + * This class implements CanvasRenderingContext2D interface as described by + * the WHATWG. + * @param {HTMLElement} surfaceElement The element that the 2D context should + * be associated with + */ + function CanvasRenderingContext2D_(surfaceElement) { + this.m_ = createMatrixIdentity(); + + this.mStack_ = []; + this.aStack_ = []; + this.currentPath_ = []; + + // Canvas context properties + this.strokeStyle = '#000'; + this.fillStyle = '#000'; + + this.lineWidth = 1; + this.lineJoin = 'miter'; + this.lineCap = 'butt'; + this.miterLimit = Z * 1; + this.globalAlpha = 1; + this.canvas = surfaceElement; + + var el = surfaceElement.ownerDocument.createElement('div'); + el.style.width = surfaceElement.clientWidth + 'px'; + el.style.height = surfaceElement.clientHeight + 'px'; + el.style.overflow = 'hidden'; + el.style.position = 'absolute'; + surfaceElement.appendChild(el); + + this.element_ = el; + this.arcScaleX_ = 1; + this.arcScaleY_ = 1; + this.lineScale_ = 1; + } + + var contextPrototype = CanvasRenderingContext2D_.prototype; + contextPrototype.clearRect = function() { + this.element_.innerHTML = ''; + }; + + contextPrototype.beginPath = function() { + // TODO: Branch current matrix so that save/restore has no effect + // as per safari docs. + this.currentPath_ = []; + }; + + contextPrototype.moveTo = function(aX, aY) { + var p = this.getCoords_(aX, aY); + this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y}); + this.currentX_ = p.x; + this.currentY_ = p.y; + }; + + contextPrototype.lineTo = function(aX, aY) { + var p = this.getCoords_(aX, aY); + this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y}); + + this.currentX_ = p.x; + this.currentY_ = p.y; + }; + + contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, + aCP2x, aCP2y, + aX, aY) { + var p = this.getCoords_(aX, aY); + var cp1 = this.getCoords_(aCP1x, aCP1y); + var cp2 = this.getCoords_(aCP2x, aCP2y); + bezierCurveTo(this, cp1, cp2, p); + }; + + // Helper function that takes the already fixed cordinates. + function bezierCurveTo(self, cp1, cp2, p) { + self.currentPath_.push({ + type: 'bezierCurveTo', + cp1x: cp1.x, + cp1y: cp1.y, + cp2x: cp2.x, + cp2y: cp2.y, + x: p.x, + y: p.y + }); + self.currentX_ = p.x; + self.currentY_ = p.y; + } + + contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { + // the following is lifted almost directly from + // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes + + var cp = this.getCoords_(aCPx, aCPy); + var p = this.getCoords_(aX, aY); + + var cp1 = { + x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), + y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) + }; + var cp2 = { + x: cp1.x + (p.x - this.currentX_) / 3.0, + y: cp1.y + (p.y - this.currentY_) / 3.0 + }; + + bezierCurveTo(this, cp1, cp2, p); + }; + + contextPrototype.arc = function(aX, aY, aRadius, + aStartAngle, aEndAngle, aClockwise) { + aRadius *= Z; + var arcType = aClockwise ? 'at' : 'wa'; + + var xStart = aX + mc(aStartAngle) * aRadius - Z2; + var yStart = aY + ms(aStartAngle) * aRadius - Z2; + + var xEnd = aX + mc(aEndAngle) * aRadius - Z2; + var yEnd = aY + ms(aEndAngle) * aRadius - Z2; + + // IE won't render arches drawn counter clockwise if xStart == xEnd. + if (xStart == xEnd && !aClockwise) { + xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something + // that can be represented in binary + } + + var p = this.getCoords_(aX, aY); + var pStart = this.getCoords_(xStart, yStart); + var pEnd = this.getCoords_(xEnd, yEnd); + + this.currentPath_.push({type: arcType, + x: p.x, + y: p.y, + radius: aRadius, + xStart: pStart.x, + yStart: pStart.y, + xEnd: pEnd.x, + yEnd: pEnd.y}); + + }; + + contextPrototype.rect = function(aX, aY, aWidth, aHeight) { + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + }; + + contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { + var oldPath = this.currentPath_; + this.beginPath(); + + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + this.stroke(); + + this.currentPath_ = oldPath; + }; + + contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { + var oldPath = this.currentPath_; + this.beginPath(); + + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + this.fill(); + + this.currentPath_ = oldPath; + }; + + contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { + var gradient = new CanvasGradient_('gradient'); + gradient.x0_ = aX0; + gradient.y0_ = aY0; + gradient.x1_ = aX1; + gradient.y1_ = aY1; + return gradient; + }; + + contextPrototype.createRadialGradient = function(aX0, aY0, aR0, + aX1, aY1, aR1) { + var gradient = new CanvasGradient_('gradientradial'); + gradient.x0_ = aX0; + gradient.y0_ = aY0; + gradient.r0_ = aR0; + gradient.x1_ = aX1; + gradient.y1_ = aY1; + gradient.r1_ = aR1; + return gradient; + }; + + contextPrototype.drawImage = function(image, var_args) { + var dx, dy, dw, dh, sx, sy, sw, sh; + + // to find the original width we overide the width and height + var oldRuntimeWidth = image.runtimeStyle.width; + var oldRuntimeHeight = image.runtimeStyle.height; + image.runtimeStyle.width = 'auto'; + image.runtimeStyle.height = 'auto'; + + // get the original size + var w = image.width; + var h = image.height; + + // and remove overides + image.runtimeStyle.width = oldRuntimeWidth; + image.runtimeStyle.height = oldRuntimeHeight; + + if (arguments.length == 3) { + dx = arguments[1]; + dy = arguments[2]; + sx = sy = 0; + sw = dw = w; + sh = dh = h; + } else if (arguments.length == 5) { + dx = arguments[1]; + dy = arguments[2]; + dw = arguments[3]; + dh = arguments[4]; + sx = sy = 0; + sw = w; + sh = h; + } else if (arguments.length == 9) { + sx = arguments[1]; + sy = arguments[2]; + sw = arguments[3]; + sh = arguments[4]; + dx = arguments[5]; + dy = arguments[6]; + dw = arguments[7]; + dh = arguments[8]; + } else { + throw Error('Invalid number of arguments'); + } + + var d = this.getCoords_(dx, dy); + + var w2 = sw / 2; + var h2 = sh / 2; + + var vmlStr = []; + + var W = 10; + var H = 10; + + // For some reason that I've now forgotten, using divs didn't work + vmlStr.push(' ' , + '', + ''); + + this.element_.insertAdjacentHTML('BeforeEnd', + vmlStr.join('')); + }; + + contextPrototype.stroke = function(aFill) { + var lineStr = []; + var lineOpen = false; + var a = processStyle(aFill ? this.fillStyle : this.strokeStyle); + var color = a.color; + var opacity = a.alpha * this.globalAlpha; + + var W = 10; + var H = 10; + + lineStr.push(''); + + if (!aFill) { + var lineWidth = this.lineScale_ * this.lineWidth; + + // VML cannot correctly render a line if the width is less than 1px. + // In that case, we dilute the color to make the line look thinner. + if (lineWidth < 1) { + opacity *= lineWidth; + } + + lineStr.push( + '' + ); + } else if (typeof this.fillStyle == 'object') { + var fillStyle = this.fillStyle; + var angle = 0; + var focus = {x: 0, y: 0}; + + // additional offset + var shift = 0; + // scale factor for offset + var expansion = 1; + + if (fillStyle.type_ == 'gradient') { + var x0 = fillStyle.x0_ / this.arcScaleX_; + var y0 = fillStyle.y0_ / this.arcScaleY_; + var x1 = fillStyle.x1_ / this.arcScaleX_; + var y1 = fillStyle.y1_ / this.arcScaleY_; + var p0 = this.getCoords_(x0, y0); + var p1 = this.getCoords_(x1, y1); + var dx = p1.x - p0.x; + var dy = p1.y - p0.y; + angle = Math.atan2(dx, dy) * 180 / Math.PI; + + // The angle should be a non-negative number. + if (angle < 0) { + angle += 360; + } + + // Very small angles produce an unexpected result because they are + // converted to a scientific notation string. + if (angle < 1e-6) { + angle = 0; + } + } else { + var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_); + var width = max.x - min.x; + var height = max.y - min.y; + focus = { + x: (p0.x - min.x) / width, + y: (p0.y - min.y) / height + }; + + width /= this.arcScaleX_ * Z; + height /= this.arcScaleY_ * Z; + var dimension = m.max(width, height); + shift = 2 * fillStyle.r0_ / dimension; + expansion = 2 * fillStyle.r1_ / dimension - shift; + } + + // We need to sort the color stops in ascending order by offset, + // otherwise IE won't interpret it correctly. + var stops = fillStyle.colors_; + stops.sort(function(cs1, cs2) { + return cs1.offset - cs2.offset; + }); + + var length = stops.length; + var color1 = stops[0].color; + var color2 = stops[length - 1].color; + var opacity1 = stops[0].alpha * this.globalAlpha; + var opacity2 = stops[length - 1].alpha * this.globalAlpha; + + var colors = []; + for (var i = 0; i < length; i++) { + var stop = stops[i]; + colors.push(stop.offset * expansion + shift + ' ' + stop.color); + } + + // When colors attribute is used, the meanings of opacity and o:opacity2 + // are reversed. + lineStr.push(''); + } else { + lineStr.push(''); + } + + lineStr.push(''); + + this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); + }; + + contextPrototype.fill = function() { + this.stroke(true); + } + + contextPrototype.closePath = function() { + this.currentPath_.push({type: 'close'}); + }; + + /** + * @private + */ + contextPrototype.getCoords_ = function(aX, aY) { + var m = this.m_; + return { + x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2, + y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2 + } + }; + + contextPrototype.save = function() { + var o = {}; + copyState(this, o); + this.aStack_.push(o); + this.mStack_.push(this.m_); + this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); + }; + + contextPrototype.restore = function() { + copyState(this.aStack_.pop(), this); + this.m_ = this.mStack_.pop(); + }; + + function matrixIsFinite(m) { + for (var j = 0; j < 3; j++) { + for (var k = 0; k < 2; k++) { + if (!isFinite(m[j][k]) || isNaN(m[j][k])) { + return false; + } + } + } + return true; + } + + function setM(ctx, m, updateLineScale) { + if (!matrixIsFinite(m)) { + return; + } + ctx.m_ = m; + + if (updateLineScale) { + // Get the line scale. + // Determinant of this.m_ means how much the area is enlarged by the + // transformation. So its square root can be used as a scale factor + // for width. + var det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; + ctx.lineScale_ = sqrt(abs(det)); + } + } + + contextPrototype.translate = function(aX, aY) { + var m1 = [ + [1, 0, 0], + [0, 1, 0], + [aX, aY, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), false); + }; + + contextPrototype.rotate = function(aRot) { + var c = mc(aRot); + var s = ms(aRot); + + var m1 = [ + [c, s, 0], + [-s, c, 0], + [0, 0, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), false); + }; + + contextPrototype.scale = function(aX, aY) { + this.arcScaleX_ *= aX; + this.arcScaleY_ *= aY; + var m1 = [ + [aX, 0, 0], + [0, aY, 0], + [0, 0, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), true); + }; + + contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) { + var m1 = [ + [m11, m12, 0], + [m21, m22, 0], + [dx, dy, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), true); + }; + + contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) { + var m = [ + [m11, m12, 0], + [m21, m22, 0], + [dx, dy, 1] + ]; + + setM(this, m, true); + }; + + /******** STUBS ********/ + contextPrototype.clip = function() { + // TODO: Implement + }; + + contextPrototype.arcTo = function() { + // TODO: Implement + }; + + contextPrototype.createPattern = function() { + return new CanvasPattern_; + }; + + // Gradient / Pattern Stubs + function CanvasGradient_(aType) { + this.type_ = aType; + this.x0_ = 0; + this.y0_ = 0; + this.r0_ = 0; + this.x1_ = 0; + this.y1_ = 0; + this.r1_ = 0; + this.colors_ = []; + } + + CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { + aColor = processStyle(aColor); + this.colors_.push({offset: aOffset, + color: aColor.color, + alpha: aColor.alpha}); + }; + + function CanvasPattern_() {} + + // set up externs + G_vmlCanvasManager = G_vmlCanvasManager_; + CanvasRenderingContext2D = CanvasRenderingContext2D_; + CanvasGradient = CanvasGradient_; + CanvasPattern = CanvasPattern_; + +})(); + +} // if diff --git a/player/static/player/js/jquery.leddisplay.js b/player/static/player/js/jquery.leddisplay.js new file mode 100644 index 0000000..fc55136 --- /dev/null +++ b/player/static/player/js/jquery.leddisplay.js @@ -0,0 +1,526 @@ +(function( $ ) { + + var charactersMapData = { + // A + 97: [[0, 1, 1, 1, 1], [1, 0, 1, 0, 0], [1, 1, 1, 1, 1]], + 65: [[0, 1, 1, 1, 1], [1, 0, 1, 0, 0], [1, 1, 1, 1, 1]], + 1072: [[0, 1, 1, 1, 1], [1, 0, 1, 0, 0], [1, 1, 1, 1, 1]], + 1040: [[0, 1, 1, 1, 1], [1, 0, 1, 0, 0], [1, 1, 1, 1, 1]], + // Б + 1041: [[1, 1, 1, 1, 1], [1, 0, 1, 0, 1], [1, 0, 1, 1, 1]], + 1073: [[1, 1, 1, 1, 1], [1, 0, 1, 0, 1], [1, 0, 1, 1, 1]], + // B + 1042: [[1, 1, 1, 1, 1], [1, 0, 1, 0, 1], [0, 1, 0, 1, 0]], + 1074: [[1, 1, 1, 1, 1], [1, 0, 1, 0, 1], [0, 1, 0, 1, 0]], + 98: [[1, 1, 1, 1, 1], [1, 0, 1, 0, 1], [0, 1, 0, 1, 0]], + 66: [[1, 1, 1, 1, 1], [1, 0, 1, 0, 1], [0, 1, 0, 1, 0]], + // Г + 1043: [[1, 1, 1, 1, 1], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]], + 1075: [[1, 1, 1, 1, 1], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]], + // Д + 1076: [[0, 0, 0, 1, 1], [0, 1, 1, 1, 0], [1, 0, 0, 1, 0], [1, 1, 1, 1, 0], [0, 0, 0, 1, 1]], + 1044: [[0, 0, 0, 1, 1], [0, 1, 1, 1, 0], [1, 0, 0, 1, 0], [1, 1, 1, 1, 0], [0, 0, 0, 1, 1]], + // Е, Ё + 1045:[[1, 1, 1, 1, 1], [1, 0, 1, 0, 1], [1, 0, 0, 0, 1]], + 1077:[[1, 1, 1, 1, 1], [1, 0, 1, 0, 1], [1, 0, 0, 0, 1]], + 1025:[[1, 1, 1, 1, 1], [1, 0, 1, 0, 1], [1, 0, 0, 0, 1]], + 1105:[[1, 1, 1, 1, 1], [1, 0, 1, 0, 1], [1, 0, 0, 0, 1]], + 69:[[1, 1, 1, 1, 1], [1, 0, 1, 0, 1], [1, 0, 0, 0, 1]], + 101:[[1, 1, 1, 1, 1], [1, 0, 1, 0, 1], [1, 0, 0, 0, 1]], + // Ж + 1046: [[1, 1, 0, 1, 1], [0, 0, 1, 0, 0], [1, 1, 1, 1, 1], [0, 0, 1, 0, 0], [1, 1, 0, 1, 1]], + 1078: [[1, 1, 0, 1, 1], [0, 0, 1, 0, 0], [1, 1, 1, 1, 1], [0, 0, 1, 0, 0], [1, 1, 0, 1, 1]], + // З + 1047: [[1,0,0,0,1], [1,0,1,0,1], [0,1,0,1,0]], + 1079: [[1,0,0,0,1], [1,0,1,0,1], [0,1,0,1,0]], + // И, Й + 1048: [[1,1,1,1,1], [0,0,0,1,0], [0,0,1,0,0], [1,1,1,1,1]], + 1080: [[1,1,1,1,1], [0,0,0,1,0], [0,0,1,0,0], [1,1,1,1,1]], + 1049: [[1,1,1,1,1], [0,0,0,1,0], [0,0,1,0,0], [1,1,1,1,1]], + 1081: [[1,1,1,1,1], [0,0,0,1,0], [0,0,1,0,0], [1,1,1,1,1]], + // К + 1050: [[1,1,1,1,1], [0,0,1,0,0], [0,1,0,1,0], [1,0,0,0,1]], + 1082: [[1,1,1,1,1], [0,0,1,0,0], [0,1,0,1,0], [1,0,0,0,1]], + 75: [[1,1,1,1,1], [0,0,1,0,0], [0,1,0,1,0], [1,0,0,0,1]], + 107: [[1,1,1,1,1], [0,0,1,0,0], [0,1,0,1,0], [1,0,0,0,1]], + // Л + 1051: [[0,0,0,0,1], [0,1,1,1,1], [1,0,0,0,0], [1,1,1,1,1]], + 1083: [[0,0,0,0,1], [0,1,1,1,1], [1,0,0,0,0], [1,1,1,1,1]], + // М + 1052: [[1,1,1,1,1], [0,1,0,0,0], [0,0,1,0,0], [0,1,0,0,0], [1,1,1,1,1]], + 1084: [[1,1,1,1,1], [0,1,0,0,0], [0,0,1,0,0], [0,1,0,0,0], [1,1,1,1,1]], + 77: [[1,1,1,1,1], [0,1,0,0,0], [0,0,1,0,0], [0,1,0,0,0], [1,1,1,1,1]], + 109: [[1,1,1,1,1], [0,1,0,0,0], [0,0,1,0,0], [0,1,0,0,0], [1,1,1,1,1]], + // Н + 72: [[1, 1, 1, 1, 1], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [1, 1, 1, 1, 1]], + 104: [[1, 1, 1, 1, 1], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [1, 1, 1, 1, 1]], + 1053: [[1, 1, 1, 1, 1], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [1, 1, 1, 1, 1]], + 1085: [[1, 1, 1, 1, 1], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [1, 1, 1, 1, 1]], + // О + 79:[[0, 1, 1, 1, 0], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0]], + 111:[[0, 1, 1, 1, 0], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0]], + 1054:[[0, 1, 1, 1, 0], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0]], + 1086:[[0, 1, 1, 1, 0], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0]], + // П + 1055: [[1,1,1,1,1], [1,0,0,0,0], [1,0,0,0,0], [1,1,1,1,1]], + 1087: [[1,1,1,1,1], [1,0,0,0,0], [1,0,0,0,0], [1,1,1,1,1]], + // Р + 1056: [[1,1,1,1,1], [1,0,1,0,0], [1,1,1,0,0]], + 1088: [[1,1,1,1,1], [1,0,1,0,0], [1,1,1,0,0]], + 80: [[1,1,1,1,1], [1,0,1,0,0], [1,1,1,0,0]], + 112: [[1,1,1,1,1], [1,0,1,0,0], [1,1,1,0,0]], + // С [0,0,0,0,0] + 67: [[0,1,1,1,0], [1,0,0,0,1], [1,0,0,0,1]], + 99: [[0,1,1,1,0], [1,0,0,0,1], [1,0,0,0,1]], + 1057: [[0,1,1,1,0], [1,0,0,0,1], [1,0,0,0,1]], + 1089: [[0,1,1,1,0], [1,0,0,0,1], [1,0,0,0,1]], + // Т + 1058: [[1,0,0,0,0], [1,1,1,1,1], [1,0,0,0,0]], + 1090: [[1,0,0,0,0], [1,1,1,1,1], [1,0,0,0,0]], + 84: [[1,0,0,0,0], [1,1,1,1,1], [1,0,0,0,0]], + 116: [[1,0,0,0,0], [1,1,1,1,1], [1,0,0,0,0]], + // У + 1059: [[1,1,1,0,1], [0,0,1,0,1], [1,1,1,1,0]], + 1091: [[1,1,1,0,1], [0,0,1,0,1], [1,1,1,1,0]], + // Ф + 1092: [[0,1,1,0,0], [1,0,0,1,0], [1,1,1,1,1], [1,0,0,1,0], [0,1,1,0,0]], + 1060: [[0,1,1,0,0], [1,0,0,1,0], [1,1,1,1,1], [1,0,0,1,0], [0,1,1,0,0]], + // Х + 1061: [[1,1,0,1,1], [0,0,1,0,0], [1,1,0,1,1]], + 1093: [[1,1,0,1,1], [0,0,1,0,0], [1,1,0,1,1]], + 88: [[1,1,0,1,1], [0,0,1,0,0], [1,1,0,1,1]], + 120: [[1,1,0,1,1], [0,0,1,0,0], [1,1,0,1,1]], + // Ц + 1062: [[1,1,1,1,1], [0,0,0,0,1], [1,1,1,1,1], [0,0,0,0,1]], + 1094: [[1,1,1,1,1], [0,0,0,0,1], [1,1,1,1,1], [0,0,0,0,1]], + // Ч + 1063: [[1,1,1,0,0], [0,0,1,0,0], [1,1,1,1,1]], + 1095: [[1,1,1,0,0], [0,0,1,0,0], [1,1,1,1,1]], + // Ш + 1064: [[1,1,1,1,1], [0,0,0,0,1], [0,0,1,1,1],[0,0,0,0,1], [1,1,1,1,1]], + 1096: [[1,1,1,1,1], [0,0,0,0,1], [0,0,1,1,1],[0,0,0,0,1], [1,1,1,1,1]], + // Щ + 1065: [[1,1,1,1,1], [0,0,0,0,1], [0,0,1,1,1],[0,0,0,0,1], [1,1,1,1,1],[0,0,0,0,1]], + 1097: [[1,1,1,1,1], [0,0,0,0,1], [0,0,1,1,1],[0,0,0,0,1], [1,1,1,1,1],[0,0,0,0,1]], + // Ъ + 1066: [[1,0,0,0,0], [1,1,1,1,1], [0,0,1,0,1], [0,0,1,1,1]], + 1098: [[1,0,0,0,0], [1,1,1,1,1], [0,0,1,0,1], [0,0,1,1,1]], + // Ы + 1067: [[1,1,1,1,1], [0,0,1,0,1], [0,0,1,1,1], [0,0,0,0,0], [1,1,1,1,1]], + 1099: [[1,1,1,1,1], [0,0,1,0,1], [0,0,1,1,1], [0,0,0,0,0], [1,1,1,1,1]], + // Ь + 1068: [[1,1,1,1,1], [0,0,1,0,1], [0,0,1,1,1]], + 1100: [[1,1,1,1,1], [0,0,1,0,1], [0,0,1,1,1]], + // Э + 1069: [[0,1,0,1,0],[1,0,0,0,1], [1,0,1,0,1], [0,1,1,1,0]], + 1101: [[0,1,0,1,0],[1,0,0,0,1], [1,0,1,0,1], [0,1,1,1,0]], + // Ю + 1070: [[1,1,1,1,1], [0,0,1,0,0], [0,1,1,1,0], [1,0,0,0,1], [0,1,1,1,0]], + 1102: [[1,1,1,1,1], [0,0,1,0,0], [0,1,1,1,0], [1,0,0,0,1], [0,1,1,1,0]], + // Я + 1071: [[1,1,1,0,1],[1,0,1,1,0],[1,1,1,1,1]], + 1103: [[1,1,1,0,1],[1,0,1,1,0],[1,1,1,1,1]], + + // D + 68:[[1, 1, 1, 1, 1], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0]], + 100:[[1, 1, 1, 1, 1], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0]], + // F + 70: [[1, 1, 1, 1, 1], [1,0,1,0,0], [1,0,0,0,0]], + 102: [[1, 1, 1, 1, 1], [1,0,1,0,0], [1,0,0,0,0]], + // G + 71: [[0,1,1,1,0], [1,0,0,0,1], [1,0,1,0,1], [1,0,1,1,1]], + 103: [[0,1,1,1,0], [1,0,0,0,1], [1,0,1,0,1], [1,0,1,1,1]], + // I + 73: [[1,0,0,0,1], [1,1,1,1,1], [1,0,0,0,1]], + 105: [[1,0,0,0,1], [1,1,1,1,1], [1,0,0,0,1]], + // J + 74: [[0,0,0,1,0],[0,0,0,0,1],[1,0,0,0,1],[1,1,1,1,0]], + 106: [[0,0,0,1,0],[0,0,0,0,1],[1,0,0,0,1],[1,1,1,1,0]], + // L + 76:[[1, 1, 1, 1, 1], [0, 0, 0, 0, 1], [0, 0, 0, 0, 1]], + 108:[[1, 1, 1, 1, 1], [0, 0, 0, 0, 1], [0, 0, 0, 0, 1]], + // N + 78: [[1,1,1,1,1], [0,0,1,0,0], [0,0,0,1,0], [1,1,1,1,1]], + 110: [[1,1,1,1,1], [0,0,1,0,0], [0,0,0,1,0], [1,1,1,1,1]], + // Q + 81: [[0,1,1,1,0],[1,0,0,0,1],[1,0,0,0,1],[0,1,1,1,0],[0,0,0,0,1]], + 113: [[0,1,1,1,0],[1,0,0,0,1],[1,0,0,0,1],[0,1,1,1,0],[0,0,0,0,1]], + // R + 82:[[1, 1, 1, 1, 1], [1, 0, 1, 1, 0], [1, 1, 1, 0, 1]], + 114:[[1, 1, 1, 1, 1], [1, 0, 1, 1, 0], [1, 1, 1, 0, 1]], + // S + 83: [[0,1,1,0,1],[1,0,1,0,1],[1,0,1,1,0]], + 115: [[0,1,1,0,1],[1,0,1,0,1],[1,0,1,1,0]], + // U + 85: [[1,1,1,1,0],[0,0,0,0,1],[0,0,0,0,1],[1,1,1,1,0]], + 117: [[1,1,1,1,0],[0,0,0,0,1],[0,0,0,0,1],[1,1,1,1,0]], + // V + 86: [[1,1,1,0,0],[0,0,0,1,0],[0,0,0,0,1],[0,0,0,1,0],[1,1,1,0,0]], + 118: [[1,1,1,0,0],[0,0,0,1,0],[0,0,0,0,1],[0,0,0,1,0],[1,1,1,0,0]], + // W + 87:[[1, 1, 1, 1, 0], [0, 0, 0, 0, 1], [0, 0, 1, 1, 0], [0, 0, 0, 0, 1], [1, 1, 1, 1, 0]], + 119:[[1, 1, 1, 1, 0], [0, 0, 0, 0, 1], [0, 0, 1, 1, 0], [0, 0, 0, 0, 1], [1, 1, 1, 1, 0]], + // Y + 89: [[1,1,0,0,0],[0,0,1,0,0],[0,0,0,1,1],[0,0,1,0,0],[1,1,0,0,0]], + 121: [[1,1,0,0,0],[0,0,1,0,0],[0,0,0,1,1],[0,0,1,0,0],[1,1,0,0,0]], + // Z + 90: [[1,0,0,1,1],[1,0,1,0,1],[1,1,0,0,1]], + 122: [[1,0,0,1,1],[1,0,1,0,1],[1,1,0,0,1]], + + // 1 + 49: [[0,1,0,0,1],[1,1,1,1,1],[0,0,0,0,1]], + // 2 + 50: [[1,0,1,1,1],[1,0,1,0,1],[1,1,1,0,1]], + // 3 + 51: [[1,0,1,0,1],[1,0,1,0,1],[1,1,1,1,1]], + // 4 + 52: [[1,1,1,0,0],[0,0,1,0,0],[1,1,1,1,1]], + // 5 + 53: [[1,1,1,0,1],[1,0,1,0,1],[1,0,1,1,1]], + // 6 + 54: [[0,1,1,1,1], [1,0,1,0,1], [0,0,1,1,1]], + // 7 + 55: [[1,0,0,0,0], [1,0,0,0,0], [1,1,1,1,1]], + // 8 + 56: [[1,1,1,1,1],[1,0,1,0,1],[1,1,1,1,1]], + // 9 + 57: [[1,1,1,0,1],[1,0,1,0,1],[1,1,1,1,1]], + // 0 + 48: [[1,1,1,1,1],[1,0,0,0,1],[1,1,1,1,1]], + + // + + 43: [[0,0,1,0,0],[0,1,1,1,0],[0,0,1,0,0]], + // - + 45: [[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0]], + // . + 46: [[0,0,0,0,1]], + // , + 44: [[0,0,0,0,1],[0,0,0,1,0]], + // ! + 33: [[1,1,1,0,1]], + // ( + 40: [[0,1,1,1,0], [1,0,0,0,1]], + // ) + 41: [[1,0,0,0,1], [0,1,1,1,0]], + 32: [[0,0,0,0,0], [0,0,0,0,0]], + } + + var _betweenChar = [0,0,0,0,0]; + + var defaults = { + horizontalPixelsCount: 90, + verticalPixelsCount: 5, + pixelSize: 5, + disabledPixelColor: '#404040', + enabledPixelColor: 'red', + pathToPixelImage: 'pixel.png', + stepDelay: 40, + // only for canvas + backgroundColor: '#202020', + // only for canvas + pixelRatio: 0.7, + runImmidiatly: true + }; + + var resolveMethods = function(element){ + var methods = null; + if (element.tagName == 'DIV') + return divMethods; + if (element.tagName == 'CANVAS') + return canvasMethods; + + $.error( 'Element "' + element.tagName + '" dont supported in jQuery.leddisplay plugin' ); + } + + var privateMethods = { + getPixelByOptions: function(options){ + var pixel = $('
'); + pixel.css('width', options.pixelSize + 'px'); + pixel.css('height', options.pixelSize + 'px'); + pixel.css('background', 'url("' + options.pathToPixelImage + '")'); + pixel.css('float', 'left'); + pixel.css('background-size', 'cover'); + pixel.css('background-color', options.disabledPixelColor); + return pixel; + }, + showTextDiv: function(containerElement, textData, startPosition){ + var options = containerElement.data('options'); + var textDataToDrawStartPosition = 0; + if (startPosition < 0) + textDataToDrawStartPosition = startPosition * -1; + + var textDataToDrawEndPosition = textData.length; + if (startPosition >= 0) + { + textDataToDrawEndPosition = textDataToDrawStartPosition + (options.horizontalPixelsCount - startPosition) + } + else + { + textDataToDrawEndPosition = textDataToDrawStartPosition + options.horizontalPixelsCount; + } + + if (textDataToDrawEndPosition > textData.length) + textDataToDrawEndPosition = textData.length; + + var allPixels = containerElement.data('allPixels'); + + for(var i = textDataToDrawStartPosition; i < textDataToDrawEndPosition; i++){ + var oneLine = textData[i]; + var position = startPosition + i; + for(var j = 0; j < oneLine.length; j++){ + if (position > options.horizontalPixelsCount) position -= options.horizontalPixelsCount; + var pixel = allPixels[j * options.horizontalPixelsCount + position]; + if (oneLine[j] == 0) + $(pixel).css('background-color', options.disabledPixelColor); + else + $(pixel).css('background-color', options.enabledPixelColor); + } + } + }, + showTextCanvas: function(containerElement, textData, startPosition){ + var options = containerElement.data('options'); + var context = containerElement.data('2dContext'); + var textDataToDrawStartPosition = 0; + if (startPosition < 0) + textDataToDrawStartPosition = startPosition * -1; + + var textDataToDrawEndPosition = textData.length; + if (startPosition >= 0) + { + textDataToDrawEndPosition = textDataToDrawStartPosition + (options.horizontalPixelsCount - startPosition) + } + else + { + textDataToDrawEndPosition = textDataToDrawStartPosition + options.horizontalPixelsCount; + } + + if (textDataToDrawEndPosition > textData.length) + textDataToDrawEndPosition = textData.length; + + var allPixels = containerElement.data('allPixels'); + + for(var i = textDataToDrawStartPosition; i < textDataToDrawEndPosition; i++){ + var oneLine = textData[i]; + var position = startPosition + i; + for(var j = 0; j < oneLine.length; j++){ + if (oneLine[j] == 0) continue; + + if (position > options.horizontalPixelsCount) position -= options.horizontalPixelsCount; + var pixel = allPixels[j * options.horizontalPixelsCount + position]; + + context.beginPath(); + context.arc(pixel.centerX, pixel.centerY, pixel.radius, 0, 2 * Math.PI, false); + + pixel.enabled = true; + context.fillStyle = options.enabledPixelColor; + context.fill(); + } + } + }, + getDataFromString: function(str){ + var resultData = []; + for (var i = 0; i < str.length; i++){ + var character = str[i]; + var characterData = this.getDataForCharacter(character); + for (var d = 0; d < characterData.length; d++) + { + resultData.push(characterData[d]); + } + if (character.charCodeAt() != 32) + resultData.push(_betweenChar); + } + + return resultData; + }, + getDataForCharacter: function(character){ + var charCode = character.charCodeAt(); + + // trim enter, tabulation, etc. + if (charCode < 32) + return []; + + if (charactersMapData[charCode]) + return charactersMapData[charCode]; + + return [[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]; + }, + clearDiv: function($this){ + var options = $this.data('options'); + var allPixels = $this.data('allPixels'); + allPixels.css('background-color', options.disabledPixelColor); + }, + clearCanvas: function($this){ + var options = $this.data('options'); + var allPixels = $this.data('allPixels'); + var context = $this.data('2dContext'); + //privateMethods.canvas_fillBackground(context, options); + privateMethods.canvas_drawDisabledPixels(context, allPixels, options); + }, + canvas_fillBackground: function(context, options){ + context.beginPath(); + var width = options.horizontalPixelsCount * options.pixelSize; + var height = options.verticalPixelsCount * options.pixelSize; + context.rect(0, 0, width, height); + context.fillStyle = options.backgroundColor; + context.fill(); + }, + canvas_drawDisabledPixels: function(context, allPixels, options){ + $(allPixels).each(function(){ + if (this.enabled){ + var x = this.centerX - options.pixelSize/2; + var y = this.centerY - options.pixelSize/2; + context.beginPath(); + context.rect(x, y, options.pixelSize, options.pixelSize); + context.fillStyle = options.backgroundColor; + context.fill(); + context.beginPath(); + context.arc(this.centerX, this.centerY, this.radius, 0, 2 * Math.PI, false); + context.fillStyle = options.disabledPixelColor; + context.fill(); + this.enabled = false; + } + }); + } + } + + var canvasMethods = { + init: function(params, text){ + var options = $.extend(defaults, params); + var context = this[0].getContext('2d'); + this.data('2dContext', context); + this.data('options', options); + var textToDisplay = text ? text : this.text(); + this.data('initialText', textToDisplay); + this.data('textData', privateMethods.getDataFromString(textToDisplay)); + this.text(''); + this.data('currentPosition', options.horizontalPixelsCount); + this.attr('width', (options.horizontalPixelsCount * options.pixelSize) + 'px'); + this.attr('height', (options.verticalPixelsCount * options.pixelSize) + 'px'); + + privateMethods.canvas_fillBackground(context, options); + + var allPixels = []; + for (var h = 0; h < options.verticalPixelsCount; h++) + for (var w = 0; w < options.horizontalPixelsCount; w++) + { + var centerX = w * options.pixelSize + (options.pixelSize/2); + var centerY = h * options.pixelSize + (options.pixelSize/2); + var radius = options.pixelSize * (options.pixelRatio / 2); + allPixels.push({centerX: centerX, centerY: centerY, radius: radius, enabled: true}); + } + + privateMethods.canvas_drawDisabledPixels(context, allPixels, options); + + this.data('allPixels', allPixels); + var _this = this; + + if (!options.runImmidiatly) + return; + + var intervalId = setInterval(function() { + privateMethods.clearCanvas(_this); + var currentPosition = _this.data('currentPosition'); + var currentData = _this.data('textData'); + privateMethods.showTextCanvas(_this, currentData, --currentPosition) + + if (currentPosition <= 0 && currentData.length < currentPosition * -1) + currentPosition = options.horizontalPixelsCount; + + _this.data('currentPosition', currentPosition); + }, options.stepDelay); + + this.data('intervalId', intervalId); + }, + destroy: function(){ + clearInterval(this.data('intervalId')); + this.removeData(); + this.removeAttr('width'); + this.removeAttr('height'); + } + } + + var divMethods = { + init: function(params, text){ + var options = $.extend(defaults, params); + + this.data('options', options); + var textToDisplay = text ? text : this.text(); + this.data('initialText', textToDisplay); + this.data('textData', privateMethods.getDataFromString(textToDisplay)); + this.text(''); + this.data('currentPosition', options.horizontalPixelsCount); + this.css('width', (options.horizontalPixelsCount * options.pixelSize) + 'px'); + this.css('height', (options.verticalPixelsCount * options.pixelSize) + 'px'); + for (var h = 1; h <= options.verticalPixelsCount; h++) + for (var w = 1; w <= options.horizontalPixelsCount; w++) + this.append(privateMethods.getPixelByOptions(options)); + + this.data('allPixels', this.find('div')); + var _this = this; + if (!options.runImmidiatly) + return; + var intervalId = setInterval(function() { + privateMethods.clearDiv(_this); + var currentPosition = _this.data('currentPosition'); + var currentData = _this.data('textData'); + privateMethods.showTextDiv(_this, currentData, --currentPosition) + + if (currentPosition <= 0 && currentData.length < currentPosition * -1) + currentPosition = options.horizontalPixelsCount; + + _this.data('currentPosition', currentPosition); + }, options.stepDelay); + this.data('intervalId', intervalId); + }, + destroy: function(){ + clearInterval(this.data('intervalId')); + this.children().remove(); + this.removeData(); + this.css('width', ''); + this.css('height', ''); + } + } + + var customMethods = { + init: function(){ + var _arg = arguments; + return this.each(function() { + var $this = $(this); + if ($this.data('leddisplay')) + return; + + $this.data('leddisplay', true); + var methods = resolveMethods(this); + methods.init.apply($this, _arg); + }); + }, + destroy: function(){ + var _arg = arguments; + return this.each(function() { + var $this = $(this); + if (!$this.data('leddisplay')) + return; + + $this.data('leddisplay', null); + var methods = resolveMethods(this); + methods.destroy.apply($this, _arg); + }); + }, + start: function(){ + + }, + stop: function(){ + + } + } + + $.fn.leddisplay = function(method) { + if ( customMethods[method] ) { + return customMethods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); + } else if ( typeof method === 'object' || ! method ) { + return customMethods.init.apply( this, arguments ); + } else { + $.error( 'Method "' + method + '" dont find in jQuery.leddisplay plugin' ); + } + }; +})(jQuery); \ No newline at end of file diff --git a/player/static/player/js/main.js b/player/static/player/js/main.js new file mode 100644 index 0000000..d8bb372 --- /dev/null +++ b/player/static/player/js/main.js @@ -0,0 +1,9 @@ + // On document ready: + +$(function(){ + + // Instantiate MixItUp: + $('#playlist').mixItUp(); + // $('#Container').mixItUp(); + +}); diff --git a/player/static/player/js/pixel.png b/player/static/player/js/pixel.png new file mode 100644 index 0000000..048302b Binary files /dev/null and b/player/static/player/js/pixel.png differ diff --git a/player/static/player/js/plexiglas.png b/player/static/player/js/plexiglas.png new file mode 100644 index 0000000..c471860 Binary files /dev/null and b/player/static/player/js/plexiglas.png differ diff --git a/player/static/player/js/scroll.js b/player/static/player/js/scroll.js new file mode 100644 index 0000000..8e2e3dd --- /dev/null +++ b/player/static/player/js/scroll.js @@ -0,0 +1,270 @@ +var SCROLLER_LENGTH = 18; +var HEIGHT = 7; + +function clearLights(){ + var lightsOn = $('.on'); + lightsOn.addClass('off'); + lightsOn.removeClass('on'); +} + +function setLight(row, col, state){ + var theLight = $('.'+row+'_'+col); + + if(theLight.hasClass('on') && !state){ + theLight.removeClass('on'); + theLight.addClass('off'); + }else if(theLight.hasClass('off') && state){ + theLight.removeClass('off'); + theLight.addClass('on'); + } +} + +function drawMessage(messageArray, leftPointer){ + var messageLength = messageArray.length; + var totalScrollLength = SCROLLER_LENGTH + messageLength; + + if(messageLength>0){ + + for(var col=0;col= 0){ + setLight(row,offsetCol,messageArray[col][row]); + } + + } + } + + } +} + +function textToLED(theWord){ + var theMessage = []; + theWord = theWord.toUpperCase(); + for(var i=0;iAnimationFrame(draw); + clearLights(); + + if(leftPointer==furthestLeftPoint){ + leftPointer = SCROLLER_LENGTH + 1; + } + + drawMessage(myMessage, leftPointer); + leftPointer--; + + }, 1000 / fps); +} + +draw(); \ No newline at end of file diff --git a/player/static/player/js/segment-display.js b/player/static/player/js/segment-display.js new file mode 100644 index 0000000..6fe6712 --- /dev/null +++ b/player/static/player/js/segment-display.js @@ -0,0 +1,558 @@ +/*! + * segment-display.js + * + * Copyright 2012, Rüdiger Appel + * http://www.3quarks.com + * Published under Creative Commons 3.0 License. + * + * Date: 2012-02-14 + * Version: 1.0.0 + * + * Dokumentation: http://www.3quarks.com/de/Segmentanzeige + * Documentation: http://www.3quarks.com/en/SegmentDisplay + */ + +// Segment display types +SegmentDisplay.SevenSegment = 7; +SegmentDisplay.FourteenSegment = 14; +SegmentDisplay.SixteenSegment = 16; + +// Segment corner types +SegmentDisplay.SymmetricCorner = 0; +SegmentDisplay.SquaredCorner = 1; +SegmentDisplay.RoundedCorner = 2; + + +function SegmentDisplay(displayId) { + this.displayId = displayId; + this.pattern = '##:##:##'; + this.value = '12:34:56'; + this.digitHeight = 20; + this.digitWidth = 10; + this.digitDistance = 2.5; + this.displayAngle = 12; + this.segmentWidth = 2.5; + this.segmentDistance = 0.2; + this.segmentCount = SegmentDisplay.SevenSegment; + this.cornerType = SegmentDisplay.RoundedCorner; + this.colorOn = 'rgb(233, 93, 15)'; + this.colorOff = 'rgb(75, 30, 5)'; +}; + +SegmentDisplay.prototype.setValue = function(value) { + this.value = value; + this.draw(); +}; + +SegmentDisplay.prototype.draw = function() { + var display = document.getElementById(this.displayId); + if (display) { + var context = display.getContext('2d'); + if (context) { + // clear canvas + context.clearRect(0, 0, display.width, display.height); + + // compute and check display width + var width = 0; + var first = true; + if (this.pattern) { + for (var i = 0; i < this.pattern.length; i++) { + var c = this.pattern.charAt(i).toLowerCase(); + if (c == '#') { + width += this.digitWidth; + } else if (c == '.' || c == ':') { + width += this.segmentWidth; + } else if (c != ' ') { + return; + } + width += first ? 0 : this.digitDistance; + first = false; + } + } + if (width <= 0) { + return; + } + + // compute skew factor + var angle = -1.0 * Math.max(-45.0, Math.min(45.0, this.displayAngle)); + var skew = Math.tan((angle * Math.PI) / 180.0); + + // compute scale factor + var scale = Math.min(display.width / (width + Math.abs(skew * this.digitHeight)), display.height / this.digitHeight); + + // compute display offset + var offsetX = (display.width - (width + skew * this.digitHeight) * scale) / 2.0; + var offsetY = (display.height - this.digitHeight * scale) / 2.0; + + // context transformation + context.save(); + context.translate(offsetX, offsetY); + context.scale(scale, scale); + context.transform(1, 0, skew, 1, 0, 0); + + // draw segments + var xPos = 0; + var size = (this.value) ? this.value.length : 0; + for (var i = 0; i < this.pattern.length; i++) { + var mask = this.pattern.charAt(i); + var value = (i < size) ? this.value.charAt(i).toLowerCase() : ' '; + xPos += this.drawDigit(context, xPos, mask, value); + } + + // finish drawing + context.restore(); + } + } +}; + +SegmentDisplay.prototype.drawDigit = function(context, xPos, mask, c) { + switch (mask) { + case '#': + var r = Math.sqrt(this.segmentWidth * this.segmentWidth / 2.0); + var d = Math.sqrt(this.segmentDistance * this.segmentDistance / 2.0); + var e = d / 2.0; + var f = (this.segmentWidth - d) * Math.sin((45.0 * Math.PI) / 180.0); + var g = f / 2.0; + var h = (this.digitHeight - 3.0 * this.segmentWidth) / 2.0; + var w = (this.digitWidth - 3.0 * this.segmentWidth) / 2.0; + var s = this.segmentWidth / 2.0; + var t = this.digitWidth / 2.0; + + // draw segment a (a1 and a2 for 16 segments) + if (this.segmentCount == 16) { + var x = xPos; + var y = 0; + context.fillStyle = this.getSegmentColor(c, null, '02356789abcdefgiopqrstz@%'); + context.beginPath(); + switch (this.cornerType) { + case SegmentDisplay.SymmetricCorner: + context.moveTo(x + s + d, y + s); + context.lineTo(x + this.segmentWidth + d, y); + break; + case SegmentDisplay.SquaredCorner: + context.moveTo(x + s + e, y + s - e); + context.lineTo(x + this.segmentWidth, y); + break; + default: + context.moveTo(x + this.segmentWidth - f, y + this.segmentWidth - f - d); + context.quadraticCurveTo(x + this.segmentWidth - g, y, x + this.segmentWidth, y); + } + context.lineTo(x + t - d - s, y); + context.lineTo(x + t - d, y + s); + context.lineTo(x + t - d - s, y + this.segmentWidth); + context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth); + context.fill(); + + var x = xPos; + var y = 0; + context.fillStyle = this.getSegmentColor(c, null, '02356789abcdefgiopqrstz@'); + context.beginPath(); + context.moveTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth); + context.lineTo(x + t + d + s, y + this.segmentWidth); + context.lineTo(x + t + d, y + s); + context.lineTo(x + t + d + s, y); + switch (this.cornerType) { + case SegmentDisplay.SymmetricCorner: + context.lineTo(x + this.digitWidth - this.segmentWidth - d, y); + context.lineTo(x + this.digitWidth - s - d, y + s); + break; + case SegmentDisplay.SquaredCorner: + context.lineTo(x + this.digitWidth - this.segmentWidth, y); + context.lineTo(x + this.digitWidth - s - e, y + s - e); + break; + default: + context.lineTo(x + this.digitWidth - this.segmentWidth, y); + context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y, x + this.digitWidth - this.segmentWidth + f, y + this.segmentWidth - f - d); + } + context.fill(); + + } else { + var x = xPos; + var y = 0; + context.fillStyle = this.getSegmentColor(c, '02356789acefp', '02356789abcdefgiopqrstz@'); + context.beginPath(); + switch (this.cornerType) { + case SegmentDisplay.SymmetricCorner: + context.moveTo(x + s + d, y + s); + context.lineTo(x + this.segmentWidth + d, y); + context.lineTo(x + this.digitWidth - this.segmentWidth - d, y); + context.lineTo(x + this.digitWidth - s - d, y + s); + break; + case SegmentDisplay.SquaredCorner: + context.moveTo(x + s + e, y + s - e); + context.lineTo(x + this.segmentWidth, y); + context.lineTo(x + this.digitWidth - this.segmentWidth, y); + context.lineTo(x + this.digitWidth - s - e, y + s - e); + break; + default: + context.moveTo(x + this.segmentWidth - f, y + this.segmentWidth - f - d); + context.quadraticCurveTo(x + this.segmentWidth - g, y, x + this.segmentWidth, y); + context.lineTo(x + this.digitWidth - this.segmentWidth, y); + context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y, x + this.digitWidth - this.segmentWidth + f, y + this.segmentWidth - f - d); + } + context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth); + context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth); + context.fill(); + } + + // draw segment b + x = xPos + this.digitWidth - this.segmentWidth; + y = 0; + context.fillStyle = this.getSegmentColor(c, '01234789adhpy', '01234789abdhjmnopqruwy'); + context.beginPath(); + switch (this.cornerType) { + case SegmentDisplay.SymmetricCorner: + context.moveTo(x + s, y + s + d); + context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d); + break; + case SegmentDisplay.SquaredCorner: + context.moveTo(x + s + e, y + s + e); + context.lineTo(x + this.segmentWidth, y + this.segmentWidth); + break; + default: + context.moveTo(x + f + d, y + this.segmentWidth - f); + context.quadraticCurveTo(x + this.segmentWidth, y + this.segmentWidth - g, x + this.segmentWidth, y + this.segmentWidth); + } + context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d); + context.lineTo(x + s, y + h + this.segmentWidth + s - d); + context.lineTo(x, y + h + this.segmentWidth - d); + context.lineTo(x, y + this.segmentWidth + d); + context.fill(); + + // draw segment c + x = xPos + this.digitWidth - this.segmentWidth; + y = h + this.segmentWidth; + context.fillStyle = this.getSegmentColor(c, '013456789abdhnouy', '01346789abdghjmnoqsuw@', '%'); + context.beginPath(); + context.moveTo(x, y + this.segmentWidth + d); + context.lineTo(x + s, y + s + d); + context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d); + context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d); + switch (this.cornerType) { + case SegmentDisplay.SymmetricCorner: + context.lineTo(x + s, y + h + this.segmentWidth + s - d); + context.lineTo(x, y + h + this.segmentWidth - d); + break; + case SegmentDisplay.SquaredCorner: + context.lineTo(x + s + e, y + h + this.segmentWidth + s - e); + context.lineTo(x, y + h + this.segmentWidth - d); + break; + default: + context.quadraticCurveTo(x + this.segmentWidth, y + h + this.segmentWidth + g, x + f + d, y + h + this.segmentWidth + f); // + context.lineTo(x, y + h + this.segmentWidth - d); + } + context.fill(); + + // draw segment d (d1 and d2 for 16 segments) + if (this.segmentCount == 16) { + x = xPos; + y = this.digitHeight - this.segmentWidth; + context.fillStyle = this.getSegmentColor(c, null, '0235689bcdegijloqsuz_=@'); + context.beginPath(); + context.moveTo(x + this.segmentWidth + d, y); + context.lineTo(x + t - d - s, y); + context.lineTo(x + t - d, y + s); + context.lineTo(x + t - d - s, y + this.segmentWidth); + switch (this.cornerType) { + case SegmentDisplay.SymmetricCorner: + context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth); + context.lineTo(x + s + d, y + s); + break; + case SegmentDisplay.SquaredCorner: + context.lineTo(x + this.segmentWidth, y + this.segmentWidth); + context.lineTo(x + s + e, y + s + e); + break; + default: + context.lineTo(x + this.segmentWidth, y + this.segmentWidth); + context.quadraticCurveTo(x + this.segmentWidth - g, y + this.segmentWidth, x + this.segmentWidth - f, y + f + d); + context.lineTo(x + this.segmentWidth - f, y + f + d); + } + context.fill(); + + x = xPos; + y = this.digitHeight - this.segmentWidth; + context.fillStyle = this.getSegmentColor(c, null, '0235689bcdegijloqsuz_=@', '%'); + context.beginPath(); + context.moveTo(x + t + d + s, y + this.segmentWidth); + context.lineTo(x + t + d, y + s); + context.lineTo(x + t + d + s, y); + context.lineTo(x + this.digitWidth - this.segmentWidth - d, y); + switch (this.cornerType) { + case SegmentDisplay.SymmetricCorner: + context.lineTo(x + this.digitWidth - s - d, y + s); + context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth); + break; + case SegmentDisplay.SquaredCorner: + context.lineTo(x + this.digitWidth - s - e, y + s + e); + context.lineTo(x + this.digitWidth - this.segmentWidth, y + this.segmentWidth); + break; + default: + context.lineTo(x + this.digitWidth - this.segmentWidth + f, y + f + d); + context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y + this.segmentWidth, x + this.digitWidth - this.segmentWidth, y + this.segmentWidth); + } + context.fill(); + } + else { + x = xPos; + y = this.digitHeight - this.segmentWidth; + context.fillStyle = this.getSegmentColor(c, '0235689bcdelotuy_', '0235689bcdegijloqsuz_=@'); + context.beginPath(); + context.moveTo(x + this.segmentWidth + d, y); + context.lineTo(x + this.digitWidth - this.segmentWidth - d, y); + switch (this.cornerType) { + case SegmentDisplay.SymmetricCorner: + context.lineTo(x + this.digitWidth - s - d, y + s); + context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth); + context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth); + context.lineTo(x + s + d, y + s); + break; + case SegmentDisplay.SquaredCorner: + context.lineTo(x + this.digitWidth - s - e, y + s + e); + context.lineTo(x + this.digitWidth - this.segmentWidth, y + this.segmentWidth); + context.lineTo(x + this.segmentWidth, y + this.segmentWidth); + context.lineTo(x + s + e, y + s + e); + break; + default: + context.lineTo(x + this.digitWidth - this.segmentWidth + f, y + f + d); + context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y + this.segmentWidth, x + this.digitWidth - this.segmentWidth, y + this.segmentWidth); + context.lineTo(x + this.segmentWidth, y + this.segmentWidth); + context.quadraticCurveTo(x + this.segmentWidth - g, y + this.segmentWidth, x + this.segmentWidth - f, y + f + d); + context.lineTo(x + this.segmentWidth - f, y + f + d); + } + context.fill(); + } + + // draw segment e + x = xPos; + y = h + this.segmentWidth; + context.fillStyle = this.getSegmentColor(c, '0268abcdefhlnoprtu', '0268acefghjklmnopqruvw@'); + context.beginPath(); + context.moveTo(x, y + this.segmentWidth + d); + context.lineTo(x + s, y + s + d); + context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d); + context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d); + switch (this.cornerType) { + case SegmentDisplay.SymmetricCorner: + context.lineTo(x + s, y + h + this.segmentWidth + s - d); + context.lineTo(x, y + h + this.segmentWidth - d); + break; + case SegmentDisplay.SquaredCorner: + context.lineTo(x + s - e, y + h + this.segmentWidth + s - d + e); + context.lineTo(x, y + h + this.segmentWidth); + break; + default: + context.lineTo(x + this.segmentWidth - f - d, y + h + this.segmentWidth + f); + context.quadraticCurveTo(x, y + h + this.segmentWidth + g, x, y + h + this.segmentWidth); + } + context.fill(); + + // draw segment f + x = xPos; + y = 0; + context.fillStyle = this.getSegmentColor(c, '045689abcefhlpty', '045689acefghklmnopqrsuvwy@', '%'); + context.beginPath(); + context.moveTo(x + this.segmentWidth, y + this.segmentWidth + d); + context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d); + context.lineTo(x + s, y + h + this.segmentWidth + s - d); + context.lineTo(x, y + h + this.segmentWidth - d); + switch (this.cornerType) { + case SegmentDisplay.SymmetricCorner: + context.lineTo(x, y + this.segmentWidth + d); + context.lineTo(x + s, y + s + d); + break; + case SegmentDisplay.SquaredCorner: + context.lineTo(x, y + this.segmentWidth); + context.lineTo(x + s - e, y + s + e); + break; + default: + context.lineTo(x, y + this.segmentWidth); + context.quadraticCurveTo(x, y + this.segmentWidth - g, x + this.segmentWidth - f - d, y + this.segmentWidth - f); + context.lineTo(x + this.segmentWidth - f - d, y + this.segmentWidth - f); + } + context.fill(); + + // draw segment g for 7 segments + if (this.segmentCount == 7) { + x = xPos; + y = (this.digitHeight - this.segmentWidth) / 2.0; + context.fillStyle = this.getSegmentColor(c, '2345689abdefhnoprty-='); + context.beginPath(); + context.moveTo(x + s + d, y + s); + context.lineTo(x + this.segmentWidth + d, y); + context.lineTo(x + this.digitWidth - this.segmentWidth - d, y); + context.lineTo(x + this.digitWidth - s - d, y + s); + context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth); + context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth); + context.fill(); + } + + // draw inner segments for the fourteen- and sixteen-segment-display + if (this.segmentCount != 7) { + // draw segment g1 + x = xPos; + y = (this.digitHeight - this.segmentWidth) / 2.0; + context.fillStyle = this.getSegmentColor(c, null, '2345689aefhkprsy-+*=', '%'); + context.beginPath(); + context.moveTo(x + s + d, y + s); + context.lineTo(x + this.segmentWidth + d, y); + context.lineTo(x + t - d - s, y); + context.lineTo(x + t - d, y + s); + context.lineTo(x + t - d - s, y + this.segmentWidth); + context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth); + context.fill(); + + // draw segment g2 + x = xPos; + y = (this.digitHeight - this.segmentWidth) / 2.0; + context.fillStyle = this.getSegmentColor(c, null, '234689abefghprsy-+*=@', '%'); + context.beginPath(); + context.moveTo(x + t + d, y + s); + context.lineTo(x + t + d + s, y); + context.lineTo(x + this.digitWidth - this.segmentWidth - d, y); + context.lineTo(x + this.digitWidth - s - d, y + s); + context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth); + context.lineTo(x + t + d + s, y + this.segmentWidth); + context.fill(); + + // draw segment j + x = xPos + t - s; + y = 0; + context.fillStyle = this.getSegmentColor(c, null, 'bdit+*', '%'); + context.beginPath(); + if (this.segmentCount == 14) { + context.moveTo(x, y + this.segmentWidth + this.segmentDistance); + context.lineTo(x + this.segmentWidth, y + this.segmentWidth + this.segmentDistance); + } else { + context.moveTo(x, y + this.segmentWidth + d); + context.lineTo(x + s, y + s + d); + context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d); + } + context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d); + context.lineTo(x + s, y + h + this.segmentWidth + s - d); + context.lineTo(x, y + h + this.segmentWidth - d); + context.fill(); + + // draw segment m + x = xPos + t - s; + y = this.digitHeight; + context.fillStyle = this.getSegmentColor(c, null, 'bdity+*@', '%'); + context.beginPath(); + if (this.segmentCount == 14) { + context.moveTo(x, y - this.segmentWidth - this.segmentDistance); + context.lineTo(x + this.segmentWidth, y - this.segmentWidth - this.segmentDistance); + } else { + context.moveTo(x, y - this.segmentWidth - d); + context.lineTo(x + s, y - s - d); + context.lineTo(x + this.segmentWidth, y - this.segmentWidth - d); + } + context.lineTo(x + this.segmentWidth, y - h - this.segmentWidth + d); + context.lineTo(x + s, y - h - this.segmentWidth - s + d); + context.lineTo(x, y - h - this.segmentWidth + d); + context.fill(); + + // draw segment h + x = xPos + this.segmentWidth; + y = this.segmentWidth; + context.fillStyle = this.getSegmentColor(c, null, 'mnx\\*'); + context.beginPath(); + context.moveTo(x + this.segmentDistance, y + this.segmentDistance); + context.lineTo(x + this.segmentDistance + r, y + this.segmentDistance); + context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance - r); + context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance); + context.lineTo(x + w - this.segmentDistance - r , y + h - this.segmentDistance); + context.lineTo(x + this.segmentDistance, y + this.segmentDistance + r); + context.fill(); + + // draw segment k + x = xPos + w + 2.0 * this.segmentWidth; + y = this.segmentWidth; + context.fillStyle = this.getSegmentColor(c, null, '0kmvxz/*', '%'); + context.beginPath(); + context.moveTo(x + w - this.segmentDistance, y + this.segmentDistance); + context.lineTo(x + w - this.segmentDistance, y + this.segmentDistance + r); + context.lineTo(x + this.segmentDistance + r, y + h - this.segmentDistance); + context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance); + context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance - r); + context.lineTo(x + w - this.segmentDistance - r, y + this.segmentDistance); + context.fill(); + + // draw segment l + x = xPos + w + 2.0 * this.segmentWidth; + y = h + 2.0 * this.segmentWidth; + context.fillStyle = this.getSegmentColor(c, null, '5knqrwx\\*'); + context.beginPath(); + context.moveTo(x + this.segmentDistance, y + this.segmentDistance); + context.lineTo(x + this.segmentDistance + r, y + this.segmentDistance); + context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance - r); + context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance); + context.lineTo(x + w - this.segmentDistance - r , y + h - this.segmentDistance); + context.lineTo(x + this.segmentDistance, y + this.segmentDistance + r); + context.fill(); + + // draw segment n + x = xPos + this.segmentWidth; + y = h + 2.0 * this.segmentWidth; + context.fillStyle = this.getSegmentColor(c, null, '0vwxz/*', '%'); + context.beginPath(); + context.moveTo(x + w - this.segmentDistance, y + this.segmentDistance); + context.lineTo(x + w - this.segmentDistance, y + this.segmentDistance + r); + context.lineTo(x + this.segmentDistance + r, y + h - this.segmentDistance); + context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance); + context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance - r); + context.lineTo(x + w - this.segmentDistance - r, y + this.segmentDistance); + context.fill(); + } + + return this.digitDistance + this.digitWidth; + + case '.': + context.fillStyle = (c == '#') || (c == '.') ? this.colorOn : this.colorOff; + this.drawPoint(context, xPos, this.digitHeight - this.segmentWidth, this.segmentWidth); + return this.digitDistance + this.segmentWidth; + + case ':': + context.fillStyle = (c == '#') || (c == ':') ? this.colorOn : this.colorOff; + var y = (this.digitHeight - this.segmentWidth) / 2.0 - this.segmentWidth; + this.drawPoint(context, xPos, y, this.segmentWidth); + this.drawPoint(context, xPos, y + 2.0 * this.segmentWidth, this.segmentWidth); + return this.digitDistance + this.segmentWidth; + + default: + return this.digitDistance; + } +}; + +SegmentDisplay.prototype.drawPoint = function(context, x1, y1, size) { + var x2 = x1 + size; + var y2 = y1 + size; + var d = size / 4.0; + + context.beginPath(); + context.moveTo(x2 - d, y1); + context.quadraticCurveTo(x2, y1, x2, y1 + d); + context.lineTo(x2, y2 - d); + context.quadraticCurveTo(x2, y2, x2 - d, y2); + context.lineTo(x1 + d, y2); + context.quadraticCurveTo(x1, y2, x1, y2 - d); + context.lineTo(x1, y1 + d); + context.quadraticCurveTo(x1, y1, x1 + d, y1); + context.fill(); +}; + +SegmentDisplay.prototype.getSegmentColor = function(c, charSet7, charSet14, charSet16) { + if (c == '#') { + return this.colorOn; + } else { + switch (this.segmentCount) { + case 7: return (charSet7.indexOf(c) == -1) ? this.colorOff : this.colorOn; + case 14: return (charSet14.indexOf(c) == -1) ? this.colorOff : this.colorOn; + case 16: var pattern = charSet14 + (charSet16 === undefined ? '' : charSet16); + return (pattern.indexOf(c) == -1) ? this.colorOff : this.colorOn; + default: return this.colorOff; + } + } +}; + + + + diff --git a/player/templates/player/index.html b/player/templates/player/index.html index d161b18..0d937e1 100644 --- a/player/templates/player/index.html +++ b/player/templates/player/index.html @@ -1,34 +1,317 @@ -{% extends 'base.html' %} -{% block menu%} - {% include "player/menu.html" %} -{% endblock %} -{% block content%} -
- {% if not request.user.is_staff %} - - {% endif %} -
-
-
-
- -
- -
-

Sélection d'une playlist

-
+{% load staticfiles %} + -
+ + + + + + + + + + + +
+ + + +
+ +
+ +
+ +
+ +
-
+
- {% include "player/select.html" %} +
- +
+
1
+
Titre de la chanson
+
Artist
+ +
+

+

+ +
-
-
- -{% endblock %} + + +
+ + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/player/views.py b/player/views.py index 7e02d15..4dc251d 100644 --- a/player/views.py +++ b/player/views.py @@ -6,26 +6,31 @@ from manager.models import Playlist, PlaylistEntry, import_playlists - def index(request): - playlists = Playlist.objects.all() - return render(request, 'player/index.html', {'playlists' : playlists}) + playlists = Playlist.objects.all() + return render(request, 'player/index.html', {'playlists': playlists}) + def update(request): - import_playlists() - playlists = Playlist.objects.all() - return render(request, 'player/index.html', {'playlists' : playlists}) + import_playlists() + playlists = Playlist.objects.all() + return render(request, 'player/index.html', {'playlists': playlists}) + def select(request): - playlists = Playlist.objects.all() - return render(request, 'player/index.html', {'playlists' : playlists}) + playlists = Playlist.objects.all() + return render(request, 'player/index.html', {'playlists': playlists}) + def playing(request): - playlist = get_object_or_404(Playlist, DeezerId=int(request.POST['choice'])) - track_list = PlaylistEntry.objects.all().filter(PlaylistId=playlist.id) - player_type = 'playlist' - context = {'playlist' : playlist, 'track_list' : track_list, 'type' : player_type } - return render(request, 'player/playing.html', context) + playlist = get_object_or_404( + Playlist, DeezerId=int(request.POST['choice'])) + track_list = PlaylistEntry.objects.all().filter(PlaylistId=playlist.id) + player_type = 'playlist' + context = {'playlist': playlist, + 'track_list': track_list, 'type': player_type} + return render(request, 'player/playing.html', context) + def nodejs_player(request): - return render(request, 'player/nodejs_player.html') + return render(request, 'player/nodejs_player.html') diff --git a/voting/templates/voting/nodejs_voting.html b/voting/templates/voting/nodejs_voting.html index 440477c..6d30767 100644 --- a/voting/templates/voting/nodejs_voting.html +++ b/voting/templates/voting/nodejs_voting.html @@ -17,9 +17,9 @@ socket.on('playlistOn', function (data) { $( "#inner" ).empty(); $( "#DataTable" ).empty(); - $( "#inner" ).prepend($.parseJSON(data).title ); - for(var i = 0, l = $.parseJSON(data).Tracks.length; i < l; i++) { - $( "#DataTable" ).append( '' + $.parseJSON(data).Tracks[i].title + + $( "#inner" ).prepend(data.playlist.title ); + for(var i = 0, l = data.tracks.length; i < l; i++) { + $( "#DataTable" ).append( '' + data.tracks[i].title + '' ); } }); diff --git a/voting/views.py b/voting/views.py index 23718b8..b3b76e4 100644 --- a/voting/views.py +++ b/voting/views.py @@ -1,15 +1,41 @@ from django.shortcuts import render from django.http import HttpResponse +from manager.models import Playlist, PlaylistEntry, import_playlists, PlaylistSession + # Create your views here. def index(request): - # playlists = Playlist.objects.all() - return render(request, 'voting/index.html') + # playlists = Playlist.objects.all() + return render(request, 'voting/index.html') def nodejs_voting(request): - return render(request, 'voting/nodejs_voting.html') + return render(request, 'voting/nodejs_voting.html') + def register(request): - return HttpResponse("Vous allez vous logger") + return HttpResponse("Vous allez vous logger") + + +# def newVote(request): +# if 'session_id' in request.POST: +# sess = get_object_or_404( +# PlaylistSession, id=request.POST['session_id']) + +# elif 'session_id' in request.GET: +# sess = get_object_or_404(PlaylistSession, id=request.GET['session_id']) + +# else: +# sess = PlaylistSession.objects.all()[0] + + +# id_voted = ' ' +# if 'vote' in request.POST: +# id_voted = request.POST['vote']) +# track_list = sess.Session.tracks +# for tr in track_list: +# if tr["DeezerId"] = id_voted: +# tr["vote"] += 1 +# print "new vote done !" +# return render(request, 'voting/nodejs_voting.html')