TestCard/script.js
2025-12-05 23:35:13 +08:00

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);
});
}