216 lines
No EOL
6 KiB
JavaScript
216 lines
No EOL
6 KiB
JavaScript
// Load configuration
|
|
var config = getConfigFromURL();
|
|
|
|
// 如果配置要求全屏,自动进入全屏
|
|
if (config.fullscreen) {
|
|
// 高亮全屏按钮并弹窗提示
|
|
window.addEventListener('DOMContentLoaded', function() {
|
|
var btn = document.getElementById('fullscreen-btn');
|
|
if (btn) {
|
|
btn.classList.add('selected');
|
|
btn.focus();
|
|
}
|
|
setTimeout(function() {
|
|
alert('请点击“全屏显示”按钮或画面以进入全屏(浏览器安全限制,需用户操作)');
|
|
}, 350);
|
|
});
|
|
}
|
|
|
|
// Load font
|
|
var vcr_font = new FontFace('VCR', 'url(vcr.ttf)');
|
|
document.fonts.add(vcr_font);
|
|
let canvas = document.querySelector('#testcard');
|
|
let ctx = canvas.getContext('2d');
|
|
ctx.font = "100px VCR";
|
|
|
|
// Load images
|
|
var images_names = ['bars75', 'bars100', 'black', 'checkerboard', 'circle', 'darkblue', 'gray50',
|
|
'lines', 'linesw', 'mauve', 'overscan', 'smpte', 'circlew','PM5544'];
|
|
var canvas_images = new Map();
|
|
for(let i=0 ; i < images_names.length ; i++) {
|
|
let image_object = new Image();
|
|
image_object.src = './imgs/' + images_names[i] + '.svg'; // 路径加./更稳妥
|
|
canvas_images.set(images_names[i], image_object);
|
|
}
|
|
|
|
// Update test card
|
|
setInterval(function() {
|
|
updateCanvasFromConfig();
|
|
}, 100);
|
|
|
|
function getConfigFromURL() {
|
|
let config = { // Default config
|
|
'pattern': 'bars75',
|
|
'circle': false,
|
|
'circlew': false,
|
|
'overscan': false,
|
|
'text': false,
|
|
'time': false,
|
|
'inverted': false,
|
|
'boxed': true,
|
|
'blink': false,
|
|
'label': 'NO SIGNAL',
|
|
'fullscreen': false
|
|
};
|
|
|
|
let url_config_str = document.location.hash.substring(1);
|
|
if(url_config_str) {
|
|
let url_config_list = url_config_str.split(';');
|
|
url_config_list.forEach(function(value, i, array) {
|
|
let key_for_index = Object.keys(config)[i];
|
|
value = decodeURIComponent(value);
|
|
if(value == '1') { value = true; }
|
|
if(value == '0') { value = false; }
|
|
config[key_for_index] = value;
|
|
});
|
|
}
|
|
|
|
document.querySelector("#label-widget").innerHTML = config['label'];
|
|
|
|
return config;
|
|
}
|
|
|
|
function setConfigToURL() {
|
|
let config_array = Object.values(config);
|
|
config_array.forEach(function(value, i) {
|
|
if(value == true) { config_array[i] = '1'; }
|
|
if(value == false) { config_array[i] = '0'; }
|
|
});
|
|
let config_str = config_array.join(';');
|
|
document.location.hash = config_str;
|
|
}
|
|
|
|
function updateCanvasFromConfig() {
|
|
drawImage(config['pattern']);
|
|
if(config['circle']) {
|
|
drawImage('circle');
|
|
}
|
|
if(config['circlew']) {
|
|
drawImage('circlew');
|
|
}
|
|
if(config['overscan']) {
|
|
drawImage('overscan');
|
|
}
|
|
if(config['text']) {
|
|
drawTextbox(
|
|
config['label'],
|
|
config['boxed'],
|
|
config['inverted'],
|
|
config['blink']
|
|
);
|
|
}
|
|
if(config['time']) {
|
|
let d = new Date();
|
|
drawTextbox(
|
|
padt(d.getHours()) + ':' + padt(d.getMinutes()) + ':' + padt(d.getSeconds()),
|
|
config['boxed'],
|
|
config['inverted'],
|
|
config['blink'],
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
function drawImage(filename) {
|
|
let canvas = document.querySelector('#testcard');
|
|
let ctx = canvas.getContext('2d');
|
|
ctx.drawImage(canvas_images.get(filename), 0, 0, canvas.width, canvas.height);
|
|
}
|
|
|
|
function drawTextbox(text, boxed, inverted, blink, bottom) {
|
|
let d = new Date();
|
|
if(blink && d.getSeconds() % 2) {
|
|
return false;
|
|
}
|
|
|
|
if(boxed) {
|
|
ctx.fillStyle = inverted ? "white" : "black";
|
|
let boxWidth = ctx.measureText(text).width + 60;
|
|
let boxHeight = 110;
|
|
let boxX = (canvas.width/2) - (boxWidth/2);
|
|
let boxY = (canvas.height/2) - (boxHeight/2);
|
|
if(bottom) {
|
|
boxY += 300;
|
|
}
|
|
ctx.fillRect(boxX, boxY, boxWidth, boxHeight);
|
|
}
|
|
|
|
ctx.textAlign = "center";
|
|
ctx.textBaseline = "middle";
|
|
ctx.fillStyle = inverted ? "black" : "white";
|
|
let textHeight = canvas.height/2-12;
|
|
if(bottom) {
|
|
textHeight += 300;
|
|
}
|
|
ctx.fillText(text, canvas.width/2, textHeight);
|
|
}
|
|
|
|
function padt(hour_or_minute) {
|
|
if(hour_or_minute < 10) {
|
|
return '0' + hour_or_minute;
|
|
}
|
|
else {
|
|
return hour_or_minute;
|
|
}
|
|
}
|
|
|
|
// Buttons
|
|
|
|
function setPattern(filename) {
|
|
config['pattern'] = filename;
|
|
updateCanvasFromConfig();
|
|
setConfigToURL();
|
|
}
|
|
|
|
function toggleOption(option) {
|
|
config[option] = !config[option];
|
|
updateCanvasFromConfig();
|
|
setConfigToURL();
|
|
}
|
|
|
|
function setLabel(text) {
|
|
config['label'] = text;
|
|
updateCanvasFromConfig();
|
|
setConfigToURL();
|
|
}
|
|
|
|
function setPreviewWide(yes) {
|
|
if(yes) {
|
|
document.querySelector("#testcard").classList.add('wide');
|
|
}
|
|
else {
|
|
document.querySelector("#testcard").classList.remove('wide');
|
|
}
|
|
}
|
|
|
|
function toggleFullscreen() {
|
|
let canvas = document.querySelector("#testcard");
|
|
let btn = document.getElementById('fullscreen-btn');
|
|
if (!document.fullscreenElement) {
|
|
if (canvas.requestFullscreen) {
|
|
canvas.requestFullscreen();
|
|
} else if (canvas.webkitRequestFullscreen) {
|
|
canvas.webkitRequestFullscreen();
|
|
} else if (canvas.msRequestFullscreen) {
|
|
canvas.msRequestFullscreen();
|
|
}
|
|
if (btn) btn.classList.remove('selected');
|
|
} else {
|
|
if (document.exitFullscreen) {
|
|
document.exitFullscreen();
|
|
} else if (document.webkitExitFullscreen) {
|
|
document.webkitExitFullscreen();
|
|
} else if (document.msExitFullscreen) {
|
|
document.msExitFullscreen();
|
|
}
|
|
}
|
|
}
|
|
|
|
function copyFullscreenLink() {
|
|
let fullscreenURL = window.location.href.split('#')[0] + '#1;0;0;0;1;0;0;1;0;NO SIGNAL;0';
|
|
navigator.clipboard.writeText(fullscreenURL).then(function() {
|
|
alert('全屏链接已复制到剪贴板!');
|
|
}).catch(function(err) {
|
|
console.error('无法复制链接: ', err);
|
|
});
|
|
} |