Merge pull request 'feat: 扩大体量和显影参数范围' (#4) from feat/wide-volume-range into main

This commit was merged in pull request #4.
This commit is contained in:
2026-07-25 09:04:25 +00:00
3 changed files with 41 additions and 10 deletions
+10 -3
View File
@@ -74,10 +74,10 @@ app.innerHTML = `
<label class="control" for="retention-control"> <label class="control" for="retention-control">
<span class="control__heading"> <span class="control__heading">
<span>显影</span> <span>显影</span>
<output id="retention-value">14%</output> <output id="retention-value">15%</output>
</span> </span>
<span class="control__hint">留下多少原文词语</span> <span class="control__hint">留下多少原文词语</span>
<input id="retention-control" type="range" min="5" max="40" value="14" /> <input id="retention-control" type="range" min="0" max="100" value="15" />
</label> </label>
<label class="control" for="volume-control"> <label class="control" for="volume-control">
@@ -86,7 +86,14 @@ app.innerHTML = `
<output id="volume-value">100%</output> <output id="volume-value">100%</output>
</span> </span>
<span class="control__hint">结果相对原文的总长度</span> <span class="control__hint">结果相对原文的总长度</span>
<input id="volume-control" type="range" min="85" max="115" value="100" /> <input
id="volume-control"
type="range"
min="10"
max="1000"
step="10"
value="100"
/>
</label> </label>
<label class="control" for="disorder-control"> <label class="control" for="disorder-control">
+24
View File
@@ -36,6 +36,14 @@ describe('selectKeywords', () => {
expect(candidates.some((candidate) => candidate.selected)).toBe(true) expect(candidates.some((candidate) => candidate.selected)).toBe(true)
}) })
it('显影 0% 不保留词语,100% 保留全部候选词', () => {
const hidden = selectKeywords(SOURCE, 0, 1)
const revealed = selectKeywords(SOURCE, 100, 1)
expect(hidden.some((candidate) => candidate.selected)).toBe(false)
expect(revealed.every((candidate) => candidate.selected)).toBe(true)
})
}) })
describe('generateMosaic', () => { describe('generateMosaic', () => {
@@ -74,6 +82,22 @@ describe('generateMosaic', () => {
expect(ratio).toBeLessThanOrEqual(1.03) expect(ratio).toBeLessThanOrEqual(1.03)
}) })
it('支持将体量压缩到 10% 或膨胀到 1000%', () => {
const compressed = generateMosaic(SOURCE, [], {
volume: 10,
disorder: 0,
seed: 42,
})
const expanded = generateMosaic(SOURCE, [], {
volume: 1000,
disorder: 0,
seed: 42,
})
expect(compressed.outputLength).toBe(Math.round(compressed.inputLength * 0.1))
expect(expanded.outputLength).toBe(expanded.inputLength * 10)
})
it('相同种子可复现,不同种子会重新侵蚀', () => { it('相同种子可复现,不同种子会重新侵蚀', () => {
const candidates = selectKeywords(SOURCE, 14, 1) const candidates = selectKeywords(SOURCE, 14, 1)
const first = generateMosaic(SOURCE, candidates, { const first = generateMosaic(SOURCE, candidates, {
+7 -7
View File
@@ -345,13 +345,13 @@ export function selectKeywords(
return candidates return candidates
} }
const desiredCount = Math.min( const desiredCount =
candidates.length, retention <= 0
Math.max( ? 0
candidates.length >= 4 ? 2 : 1, : Math.min(
Math.round(candidates.length * (retention / 100)), candidates.length,
), Math.max(1, Math.ceil(candidates.length * (retention / 100))),
) )
const ranked = [...candidates].sort( const ranked = [...candidates].sort(
(left, right) => right.score - left.score || left.start - right.start, (left, right) => right.score - left.score || left.start - right.start,
) )