(Install package: clbiwiki-mainpage-category-project-pillar-shifted-insets-20260716 / js/CategoryPillar.js) |
(Install package: clbiwiki-frame-geometry-normalized-20260717 / js/CategoryPillar.js) |
||
| 3번째 줄: | 3번째 줄: | ||
대문 상단 카테고리의 중앙 「프로젝트」 기둥 | 대문 상단 카테고리의 중앙 「프로젝트」 기둥 | ||
========================================= */ | ========================================= */ | ||
(function (window, document, mw) { | (function (window, document, mw) { | ||
'use strict'; | 'use strict'; | ||
var VERSION = '20260717-shared-frame-geometry-001'; | |||
var VERSION = ' | |||
var renderTimer = 0; | var renderTimer = 0; | ||
function | function api() { | ||
return | return window.CLBI && window.CLBI.frame; | ||
} | } | ||
function | function renderSvg(svg, seams) { | ||
var frame = api(); | |||
var source; | |||
var previous; | |||
var points; | |||
var | |||
var | |||
var previous | |||
var | |||
var group; | var group; | ||
var label; | var label; | ||
var centerY; | |||
var leftCenter; | |||
var rightCenter; | |||
if (! | if (!frame || !svg || !seams || Number(svg.getAttribute('data-frame-width')) !== seams.width) return false; | ||
source = svg.querySelector('.portal-cat-anchor[data-category-key="project"]'); | |||
if (!source) return false; | |||
previous = svg.querySelector('.portal-category-pillar'); | |||
if (previous) previous.remove(); | |||
points = frame.segmentAt( | |||
seams.projectLeftTopX, | |||
seams.projectRightTopX, | |||
0, | |||
seams.rowHeight, | |||
seams.projectLeftDir, | |||
seams.projectRightDir, | |||
0, | |||
0, | |||
0 | |||
); | |||
group = frame.create('g', 'portal-category-pillar'); | |||
) | |||
group = | |||
group.setAttribute('data-category-key', 'project'); | group.setAttribute('data-category-key', 'project'); | ||
group.setAttribute('aria-label', | group.setAttribute('aria-label', '프로젝트'); | ||
group.setAttribute('pointer-events', 'none'); | group.setAttribute('pointer-events', 'none'); | ||
group.appendChild(frame.polygon('portal-category-pillar-surface', points)); | |||
group.appendChild(frame.line('portal-category-pillar-line portal-category-pillar-shadow', points[3], points[0])); | |||
group.appendChild(frame.line('portal-category-pillar-line portal-category-pillar-highlight', points[1], points[2])); | |||
centerY = Math.round((seams.buttonTop + seams.buttonBottom) / 2); | |||
leftCenter = frame.slantX(seams.projectLeftTopX, centerY, seams.projectLeftDir, 0); | |||
rightCenter = frame.slantX(seams.projectRightTopX, centerY, seams.projectRightDir, 0); | |||
label = frame.create('text', 'portal-cat-label portal-category-pillar-label'); | |||
label.setAttribute('x', Math.round((leftCenter + rightCenter) / 2)); | |||
label.setAttribute('y', centerY + 1); | |||
label.setAttribute('font-size', '12'); | |||
label.setAttribute('font-weight', '700'); | |||
label.setAttribute('text-anchor', 'middle'); | |||
label.setAttribute('dominant-baseline', 'middle'); | |||
label.textContent = '프로젝트'; | |||
label.setAttribute(' | |||
label.setAttribute(' | |||
label.textContent = | |||
group.appendChild(label); | group.appendChild(label); | ||
| 223번째 줄: | 72번째 줄: | ||
} | } | ||
function | function renderAll(root, seams) { | ||
var scope = root && root.querySelectorAll ? root : document; | var scope = root && root.querySelectorAll ? root : document; | ||
var | var current = seams || (api() && api().seams); | ||
var rendered = 0; | |||
if ( | if (!current || !current.width) return 0; | ||
Array.prototype.forEach.call( | Array.prototype.forEach.call( | ||
scope.querySelectorAll('.main-portal [data-component="category-nav"] .portal-category-svg'), | scope.querySelectorAll('.main-portal [data-component="category-nav"] .portal-category-svg'), | ||
function (svg) { | function (svg) { | ||
if (renderSvg(svg, current)) rendered += 1; | |||
} | |||
); | ); | ||
return rendered; | return rendered; | ||
} | } | ||
function | function schedule(root, seams) { | ||
window.clearTimeout(renderTimer); | window.clearTimeout(renderTimer); | ||
renderTimer = window.setTimeout(function () { | renderTimer = window.setTimeout(function () { | ||
renderTimer = 0; | renderTimer = 0; | ||
renderAll(root || document); | renderAll(root || document, seams); | ||
}, 0); | }, 0); | ||
} | } | ||
if (api()) api().onSeams(function (seams) { schedule(document, seams); }); | |||
if (mw && mw.hook) { | if (mw && mw.hook) { | ||
mw.hook('wikipage.content').add(function (content) { | mw.hook('wikipage.content').add(function (content) { | ||
schedule(content && content[0] ? content[0] : document); | |||
}); | }); | ||
} | } | ||
window.CategoryPillar = { | window.CategoryPillar = { | ||
version:VERSION, | version:VERSION, | ||
init: | init:renderAll, | ||
render:renderSvg, | render:renderSvg, | ||
renderAll:renderAll | renderAll:renderAll | ||
}; | }; | ||
}(window, document, window.mw)); | }(window, document, window.mw)); | ||
2026년 7월 17일 (금) 10:15 판
/* =========================================
CategoryPillar
대문 상단 카테고리의 중앙 「프로젝트」 기둥
========================================= */
(function (window, document, mw) {
'use strict';
var VERSION = '20260717-shared-frame-geometry-001';
var renderTimer = 0;
function api() {
return window.CLBI && window.CLBI.frame;
}
function renderSvg(svg, seams) {
var frame = api();
var source;
var previous;
var points;
var group;
var label;
var centerY;
var leftCenter;
var rightCenter;
if (!frame || !svg || !seams || Number(svg.getAttribute('data-frame-width')) !== seams.width) return false;
source = svg.querySelector('.portal-cat-anchor[data-category-key="project"]');
if (!source) return false;
previous = svg.querySelector('.portal-category-pillar');
if (previous) previous.remove();
points = frame.segmentAt(
seams.projectLeftTopX,
seams.projectRightTopX,
0,
seams.rowHeight,
seams.projectLeftDir,
seams.projectRightDir,
0,
0,
0
);
group = frame.create('g', 'portal-category-pillar');
group.setAttribute('data-category-key', 'project');
group.setAttribute('aria-label', '프로젝트');
group.setAttribute('pointer-events', 'none');
group.appendChild(frame.polygon('portal-category-pillar-surface', points));
group.appendChild(frame.line('portal-category-pillar-line portal-category-pillar-shadow', points[3], points[0]));
group.appendChild(frame.line('portal-category-pillar-line portal-category-pillar-highlight', points[1], points[2]));
centerY = Math.round((seams.buttonTop + seams.buttonBottom) / 2);
leftCenter = frame.slantX(seams.projectLeftTopX, centerY, seams.projectLeftDir, 0);
rightCenter = frame.slantX(seams.projectRightTopX, centerY, seams.projectRightDir, 0);
label = frame.create('text', 'portal-cat-label portal-category-pillar-label');
label.setAttribute('x', Math.round((leftCenter + rightCenter) / 2));
label.setAttribute('y', centerY + 1);
label.setAttribute('font-size', '12');
label.setAttribute('font-weight', '700');
label.setAttribute('text-anchor', 'middle');
label.setAttribute('dominant-baseline', 'middle');
label.textContent = '프로젝트';
group.appendChild(label);
source.setAttribute('aria-hidden', 'true');
source.setAttribute('tabindex', '-1');
source.classList.add('portal-category-pillar-source');
svg.appendChild(group);
svg.classList.add('has-category-pillar');
return true;
}
function renderAll(root, seams) {
var scope = root && root.querySelectorAll ? root : document;
var current = seams || (api() && api().seams);
var rendered = 0;
if (!current || !current.width) return 0;
Array.prototype.forEach.call(
scope.querySelectorAll('.main-portal [data-component="category-nav"] .portal-category-svg'),
function (svg) {
if (renderSvg(svg, current)) rendered += 1;
}
);
return rendered;
}
function schedule(root, seams) {
window.clearTimeout(renderTimer);
renderTimer = window.setTimeout(function () {
renderTimer = 0;
renderAll(root || document, seams);
}, 0);
}
if (api()) api().onSeams(function (seams) { schedule(document, seams); });
if (mw && mw.hook) {
mw.hook('wikipage.content').add(function (content) {
schedule(content && content[0] ? content[0] : document);
});
}
window.CategoryPillar = {
version:VERSION,
init:renderAll,
render:renderSvg,
renderAll:renderAll
};
}(window, document, window.mw));