Difference between revisions of "MediaWiki:Common.js"

From Conceptual Reconstructionism Project
Line 2: Line 2:




function TimeSegment(track, segmentStart, segmentEnd, htmlElement) {
function TimeSegment(track, startTime, endTime, element) {
        this.track = track;
this.track = track;
        this.segmentStart = segmentStart;
this.startTime = startTime;
        this.segmentEnd = segmentEnd;
this.endTime = endTime;
        this.htmlElement = htmlElement;
this.element = element;
}
}
TimeSegment.prototype.isDisabled = function() {
return this.element.hasClass('active');
};
TimeSegment.prototype.disable = function() {
this.element.removeClass('active');
};
TimeSegment.prototype.update = function(track, currentTime) {
var percent = Math.max(currentTime - this.startTime, 0) / (this.endTime - this.startTime)
if (track === this.track && percent < 100.0) {
this.element.get(0).style.setProperty('--gauge-fill',  percent);
this.element.addClass('active');
} else {
this.disable();
}
};


function PlaybackData() {
function PlaybackData() {
        this.autostopTime = null;
this.autostopTime = null;
        this.timeSegments = [];
this.segments = [];
        this.tracks = [];
this.tracks = [];
        this.closestPlayableSegment = 0;
this.closestPlayableSegment = 0;
        this.playingTrack = null;
this.playingTrack = null;
    };
};
 


var playbackData = new PlaybackData();
var playbackData = new PlaybackData();
Line 26: Line 49:


     $('*[data-track]').each(function(trackNumber) {
     $('*[data-track]').each(function(trackNumber) {
         var audio = $('<audio></audio>').prop('controls', true).attr('preload', 'auto').attr('src', $(this).attr('data-track'));
         var audio = $('<audio></audio>')
.prop('controls', true)
.attr('preload', 'auto')
.attr('src', $(this).attr('data-track'));
          
          
$('<figure></figure>').append($('<figcaption></figcaption>').text($(this).attr('data-track-title'))).appendTo($(this)).append(audio);
$('<figure></figure>')
.append($('<figcaption></figcaption>')
.attr('data-track-title')
.text($(this)))
.appendTo($(this))
.append(audio);


        audio.on('play', function(event) {
function onPlay(event) {
if (playbackData.playingTrack !== null && playbackData.playingTrack !== trackNumber) {
if (playbackData.playingAudio !== null
playbackData.tracks[playbackData.playingTrack].stop();
&& playbackData.playingAudio !== trackNumber) {
playbackData.htmlAudios[playbackData.playingAudio].pause();
}
}
playbackData.playingTrack = trackNumber;
playbackData.playingAudio = trackNumber;
console.log('Play was called on track ' + trackNumber);
}
});
function onPause(event) {
playbackData.autostopTime = null;
playbackData.playingAudio = null;
playbackData.closestPlayableSegment = 0;
}
         playbackData.tracks.push(audio);
function onSeeked(event) {
playbackData.closestPlayableSegment = 0;
playbackData.segments.forEach(s => s.disable());
}
function onEnded(event) {
var nextPlayingTrack = playbackData.playingAudio + 1;
var hasAutoStop = playbackData.autostopTime !== null;
onPause(event);
onSeeked(event);
if (nextPlayingTrack < playbackData.htmlAudios.length && !hasAutoStop) {
playbackData.htmlAudios[nextPlayingTrack].play();
}
}
        audio.on('play', onPlay);
        audio.on('pause', onPause);
audio.on('ended', onEnded);
audio.on('seeked', onSeeked);
         playbackData.htmlAudios.push(audio.get(0));
     });
     });


Line 58: Line 115:


if (m) {
if (m) {
playbackData.timeSegments.push(new TimeSegment(
playbackData.segments.push(new TimeSegment(
parseInt(m.groups.track),
parseInt(m.groups.track),
parseInt(m.groups.minuteStart) * 60 + parseFloat(m.groups.secondStart),
parseInt(m.groups.minuteStart) * 60 + parseFloat(m.groups.secondStart),
parseInt(m.groups.minuteEnd) * 60 + parseFloat(m.groups.secondEnd),
parseInt(m.groups.minuteEnd) * 60 + parseFloat(m.groups.secondEnd),
$(this)));
$(this)));
} else {
}
else {
$(this).append('Wrong time segment');
$(this).append('Wrong time segment');
}
}
});
});


playbackData.timeSegments.sort(function(a, b) { return a.segmentStart - b.segmentStart; });
playbackData.segments.sort(function(a, b) { return a.startTime - b.startTime; });


Line 74: Line 132:
window.setInterval(function() {
window.setInterval(function() {
if (playbackData.playingAudio === null) {
return;
}
var playingTrack = playbackData.htmlAudios[playbackData.playingAudio];
var currentTime = playingTrack? playingTrack.currentTime;
if (currentTime >= playbackData.autostopTime) {
playingTrack.pause();
return;
}
var segIndex = playbackData.closestPlayableSegment || 0;
var previouSegmentActive = false;
while (segIndex < playbackData.segments.length) {
var segment = playbackData.segments[segIndex++];
segment.update(playingTrack, currentTime);
if (segment.isDisabled()) {
if (segment.startTime > currentTime) {
break;
}
continue;
}
else {
if (!previouSegmentActive) {
playbackData.closestPlayableSegment = segIndex;
}
previouSegmentActive = true;
}
}


}, 50);
}, 50);


});
});

Revision as of 18:45, 19 December 2021

/* Any JavaScript here will be loaded for all users on every page load. */


function TimeSegment(track, startTime, endTime, element) {
	this.track = track;
	this.startTime = startTime;
	this.endTime = endTime;
	this.element = element;
}


TimeSegment.prototype.isDisabled = function() {
	return this.element.hasClass('active');
};


TimeSegment.prototype.disable = function() {
	this.element.removeClass('active');
};


TimeSegment.prototype.update = function(track, currentTime) {
	var percent = Math.max(currentTime - this.startTime, 0) / (this.endTime - this.startTime)
	if (track === this.track && percent < 100.0) {
		this.element.get(0).style.setProperty('--gauge-fill',  percent);
		this.element.addClass('active');
	} else {
		this.disable();
	}
};


function PlaybackData() {
	this.autostopTime = null;
	this.segments = [];
	this.tracks = [];
	this.closestPlayableSegment = 0;
	this.playingTrack = null;
};


var playbackData = new PlaybackData();


$(document).ready(function() {


    // Create one audio player per declared track

    $('*[data-track]').each(function(trackNumber) {
        var audio = $('<audio></audio>')
			.prop('controls', true)
			.attr('preload', 'auto')
			.attr('src', $(this).attr('data-track'));
        
		$('<figure></figure>')
			.append($('<figcaption></figcaption>')
				.attr('data-track-title')
				.text($(this)))
			.appendTo($(this))
			.append(audio);

		function onPlay(event) {
			if (playbackData.playingAudio !== null
				&& playbackData.playingAudio !== trackNumber) {
				playbackData.htmlAudios[playbackData.playingAudio].pause();
			}
			playbackData.playingAudio = trackNumber;
		}
		
		function onPause(event) {
			playbackData.autostopTime = null;
			playbackData.playingAudio = null;
			playbackData.closestPlayableSegment = 0;
		}
		
		function onSeeked(event) {
			playbackData.closestPlayableSegment = 0;
			playbackData.segments.forEach(s => s.disable());
		}
		
		function onEnded(event) {
			var nextPlayingTrack = playbackData.playingAudio + 1;
			var hasAutoStop = playbackData.autostopTime !== null;
			onPause(event);
			onSeeked(event);
			if (nextPlayingTrack < playbackData.htmlAudios.length && !hasAutoStop) {
				playbackData.htmlAudios[nextPlayingTrack].play();
			}
		}
		
        audio.on('play', onPlay);
        audio.on('pause', onPause);
		audio.on('ended', onEnded);
		audio.on('seeked', onSeeked);
		
        playbackData.htmlAudios.push(audio.get(0));
    });


    // Create hyperlinks out of reconstruction markup

    $('*[data-def]').click(function() {
        var url = location.href;
        location.href = "#" + $(this).attr('data-def');
        history.replaceState(null, null, url);
    });


    // Update timing data

    $('*[data-segment]').each(function() {

        var m = /(?<track>\d+\/)?((?<minuteStart>\d+):)?(?<secondStart>\d+(.\d*)?)-((?<minuteEnd>\d+):)?(?<secondEnd>\d+(.\d*)?)/.exec($(this).attr('data-segment'));

		if (m) {
			playbackData.segments.push(new TimeSegment(
				parseInt(m.groups.track),
				parseInt(m.groups.minuteStart) * 60 + parseFloat(m.groups.secondStart),
				parseInt(m.groups.minuteEnd) * 60 + parseFloat(m.groups.secondEnd),
				$(this)));
		}
		else {
			$(this).append('Wrong time segment');
		}
	});

	playbackData.segments.sort(function(a, b) { return a.startTime - b.startTime; });

	
	// Playing tick
	
	window.setInterval(function() {
		if (playbackData.playingAudio === null) {
			return;
		}
		var playingTrack = playbackData.htmlAudios[playbackData.playingAudio];
		var currentTime = playingTrack? playingTrack.currentTime;
		
		if (currentTime >= playbackData.autostopTime) {
			playingTrack.pause();
			return;
		}
		
		var segIndex = playbackData.closestPlayableSegment || 0;
		var previouSegmentActive = false;
		
		while (segIndex < playbackData.segments.length) {
			var segment = playbackData.segments[segIndex++];
			segment.update(playingTrack, currentTime);
			
			if (segment.isDisabled()) {
				if (segment.startTime > currentTime) {
					break;
				}
				continue;
			}
			else {
				if (!previouSegmentActive) {
					playbackData.closestPlayableSegment = segIndex;
				}
				previouSegmentActive = true;
			}
		}

	}, 50);

});