Difference between revisions of "MediaWiki:Common.js"
From Conceptual Reconstructionism Project
Thaumasnot (talk | contribs) |
Thaumasnot (talk | contribs) |
||
Line 155: | Line 155: | ||
$(this).append($('<div class="sound-meta-menu meta-menu">') | $(this).append($('<div class="sound-meta-menu meta-menu">') | ||
.append($('<div>\u25B6 [- | .append($('<div>\u25B6 [-0s +0s]</div>').click(function () { playSample($(this), 0, 0); })) | ||
.append($('<div>\u25B6 [- | .append($('<div>\u25B6 [-2s +2s]</div>').click(function () { playSample($(this), -2, 2); })) | ||
.append($('<div>\u25B6 [- | .append($('<div>\u25B6 [-5s +5s]</div>').click(function () { playSample($(this), -5, 5); })) | ||
.append($('<div>\u25B6 [- | .append($('<div>\u25B6 [-10s +10s]</div>').click(function () { playSample($(this), -10, 10); })) | ||
); | ); | ||
}); | }); | ||
Line 174: | Line 174: | ||
var previouSegmentActive = false; | var previouSegmentActive = false; | ||
var lastActiveSegment = null; | |||
for(var segIndex = playbackData.closestPlayableSegIndex; | for(var segIndex = playbackData.closestPlayableSegIndex; | ||
segIndex < playbackData.segments.length; | segIndex < playbackData.segments.length; | ||
segIndex++) { | segIndex++) { | ||
var segment = playbackData.segments[segIndex]; | var segment = playbackData.segments[segIndex]; | ||
segment.update(playbackData.playingAudioIndex, currentTime); | segment.update(playbackData.playingAudioIndex, currentTime); | ||
Line 191: | Line 193: | ||
playbackData.closestPlayableSegIndex = segIndex; | playbackData.closestPlayableSegIndex = segIndex; | ||
} | } | ||
previouSegmentActive = true; | previouSegmentActive = true; | ||
lastActiveSegment = segment; | |||
} | } | ||
function checkIfInView(element) { | |||
var offset = element.offset().top - $(window).scrollTop(); | |||
if (offset > window.innerHeight) { | |||
$('html,body').animate({ | |||
scrollTop: offset | |||
}, 1000); | |||
return false; | |||
} | |||
return true; | |||
} | |||
checkIfInView(segment.element) | |||
if (playbackData.autostopTime != null && currentTime >= playbackData.autostopTime) { | if (playbackData.autostopTime != null && currentTime >= playbackData.autostopTime) { |
Revision as of 18:20, 20 December 2021
/* Any JavaScript here will be loaded for all users on every page load. */ function TimeSegment(trackIndex, startTime, endTime, element) { this.trackIndex = trackIndex; 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(trackIndex, currentTime) { var percent = 100.0 * Math.max(currentTime - this.startTime, 0) / (this.endTime - this.startTime) if (trackIndex === this.trackIndex && percent > 0.0 && 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.htmlAudios = []; this.closestPlayableSegIndex = 0; this.playingAudioIndex = null; }; var playbackData = new PlaybackData(); $(document).ready(function() { // Create one audio player per declared track $('*[data-track]').each(function(trackNumber) { $(this).addClass('audio-player'); 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); function onPlay(event) { if (playbackData.playingAudioIndex != null && playbackData.playingAudioIndex !== trackNumber) { playbackData.htmlAudios[playbackData.playingAudioIndex].pause(); } playbackData.playingAudioIndex = trackNumber; } function onPause(event) { playbackData.autostopTime = null; playbackData.playingAudioIndex = null; playbackData.closestPlayableSegIndex = 0; } function onSeeked(event) { playbackData.closestPlayableSegIndex = 0; playbackData.segments.forEach(function(s) { s.disable(); }); } function onEnded(event) { var nextPlayingAudioIndex = playbackData.playingAudioIndex + 1; onPause(event); onSeeked(event); if (nextPlayingAudioIndex < playbackData.htmlAudios.length) { playbackData.htmlAudios[nextPlayingAudioIndex].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) { if (m.groups.track != null && playbackData.htmlAudios.length <= parseInt(m.groups.track)) { $(this).append('Track number does not refer to existing track (note that the index starts with 0)'); } else { $(this).prop('data-segment-id', playbackData.segments.length) playbackData.segments.push(new TimeSegment( m.groups.track? parseInt(m.groups.track) : 0, (m.groups.minuteStart? parseInt(m.groups.minuteStart) : 0) * 60 + parseFloat(m.groups.secondStart), (m.groups.minuteEnd? parseInt(m.groups.minuteEnd) : 0) * 60 + parseFloat(m.groups.secondEnd), $(this).find('.meta-progress') )); } } else { $(this).append('Invalid syntax for segment time'); } }); playbackData.segments.sort(function(a, b) { return a.startTime - b.startTime; }); // Attach context menu to music references $('*[data-segment]').each(function() { function playSample(menuItem, lowerBound, upperBound) { var segmentId = parseInt(menuItem.closest('.meta').prop('data-segment-id')); var segment = playbackData.segments[segmentId]; var trackIndex = segment.trackIndex; playbackData.autostopTime = segment.endTime + upperBound; playbackData.htmlAudios[trackIndex].currentTime = Math.max(0, segment.startTime + lowerBound); playbackData.htmlAudios[trackIndex].play(); } $(this).append($('<div class="sound-meta-menu meta-menu">') .append($('<div>\u25B6 [-0s +0s]</div>').click(function () { playSample($(this), 0, 0); })) .append($('<div>\u25B6 [-2s +2s]</div>').click(function () { playSample($(this), -2, 2); })) .append($('<div>\u25B6 [-5s +5s]</div>').click(function () { playSample($(this), -5, 5); })) .append($('<div>\u25B6 [-10s +10s]</div>').click(function () { playSample($(this), -10, 10); })) ); }); // Playing tick window.setInterval(function() { if (playbackData.playingAudioIndex === null) { return; } var playingAudio = playbackData.htmlAudios[playbackData.playingAudioIndex]; var currentTime = playingAudio.currentTime; var previouSegmentActive = false; var lastActiveSegment = null; for(var segIndex = playbackData.closestPlayableSegIndex; segIndex < playbackData.segments.length; segIndex++) { var segment = playbackData.segments[segIndex]; segment.update(playbackData.playingAudioIndex, currentTime); if (segment.isDisabled()) { if (segment.startTime > currentTime) { break; } continue; } if (!previouSegmentActive) { playbackData.closestPlayableSegIndex = segIndex; } previouSegmentActive = true; lastActiveSegment = segment; } function checkIfInView(element) { var offset = element.offset().top - $(window).scrollTop(); if (offset > window.innerHeight) { $('html,body').animate({ scrollTop: offset }, 1000); return false; } return true; } checkIfInView(segment.element) if (playbackData.autostopTime != null && currentTime >= playbackData.autostopTime) { playingAudio.pause(); return; } }, 50); });