概述
希望创建一个具有随机(且不连续重复)背景颜色且标题也是随机的页面。
问题
该代码有两个问题。首先,根据当前页面的背景颜色生成互补的随机颜色是无效的。其次,为章节标题中的每个单词分配唯一的互补颜色的代码也是无效的。
代码
一个相对较短的例子:
\ctxlua{math.randomseed( 101 )}
\setupcolors[state=start]
\definecolor[ThemeColourGreen][h=8DC366]
\definecolor[ThemeColourBlue][h=79C9EF]
\definecolor[ThemeColourYellow][h=FFD631]
\startMPinclusions
color colours[];
colours[0] := \MPcolor{ThemeColourGreen};
colours[1] := \MPcolor{ThemeColourBlue};
colours[2] := \MPcolor{ThemeColourYellow};
max_colours := 3;
color base_colour;
color old_base_colour;
vardef ThemeBase( expr colour ) =
fill Page withcolor transparent(1, .85, colour );
enddef;
vardef RandomColour =
colours[ round( uniformdeviate( max_colours - 1 ) ) ]
enddef;
vardef GenerateRandomColour( expr colour ) =
color random_colour;
forever:
random_colour := RandomColour;
exitunless random_colour = colour;
endfor;
random_colour
enddef;
base_colour := RandomColour;
old_base_colour := base_colour;
\stopMPinclusions
\startuseMPgraphic{page:ThemeBackground}
base_colour := GenerateRandomColour( old_base_colour );
ThemeBase( base_colour );
old_base_colour := base_colour;
\stopuseMPgraphic
\startuseMPgraphic{heading:ThemeTitleStyle}
color complementary_colour;
complementary_colour := GenerateRandomColour( base_colour );
draw textext( \MPstring{heading:title} ) rotated 30
withcolor complementary_colour;
\stopuseMPgraphic
\defineoverlay[page:ThemeBackground][\uniqueMPgraphic{page:ThemeBackground}]
\defineoverlay[page:ThemeStyle][\uniqueMPgraphic{page:ThemeStyle}]
\defineframed[ThemeTitleStyle][
background=\useMPgraphic{ThemeTitleStyle},
]
% Called by processwords
\def\processword#1{%
\setMPtext{heading:title}{#1}%
\useMPgraphic{heading:ThemeTitleStyle}
}
\define[1]\ThemeChapterTitle{\processwords{#1}}
\setuphead[chapter][deeptextcommand={\ThemeChapterTitle}]
\starttext
\setupbackgrounds[page][background={page:ThemeBackground}]
\startchapter[title=One is 1st] \input knuth \stopchapter
\startchapter[title=Two is 2nd] \input zapf \stopchapter
\startchapter[title=Three is 3rd] \input knuth \stopchapter
\startchapter[title=Four is 4th] \input zapf \stopchapter
\startchapter[title=Five is 5th] \input knuth \stopchapter
\startchapter[title=Six is 6th] \input zapf \stopchapter
\stoptext
算法
我认为该算法是:
- 开始 MetaPost 包含。
- 定义一个全局的“颜色”数组来存储可用的颜色。
- 生成一个随机的初始颜色,并初始化“先前”的颜色。
- 创建新页面。
- 为页面背景生成新的随机颜色。
- 如果新的随机颜色与之前的相同,则重复上一步。
- 创建页面的标题。
- 对于标题中的每个单词,生成一种与页面背景不冲突的互补颜色。
然而,测试时发现:
- 章节标题绘制在页面背景之前;
- 该
\processwords
命令并未调用\processword
标题中的每个单词。
有关的
这与以下问题相关:
不同之处在于我需要生成一种随机颜色,以使其不与给定的颜色冲突。
问题
如何为章节标题中的每个单词选择随机颜色,以使所选颜色不与页面背景颜色冲突?
注意:我使用 MetaPost(而不是仅仅 ConTeXt),因为我想 (1) 跟踪页面颜色;(2) 使用命令生成轮廓字体graphictext
。
答案1
感谢 Marco 的评论,并意识到标题是在页面背景之前写的:
\ctxlua{math.randomseed( os.time() )}
%\ctxlua{math.randomseed( 105 )}
\setupcolors[state=start]
\definecolor[ThemeColourGreen][h=8DC366]
\definecolor[ThemeColourBlue][h=79C9EF]
\definecolor[ThemeColourYellow][h=FFD631]
\startMPinclusions
color colours[];
colours[0] := \MPcolor{ThemeColourGreen};
colours[1] := \MPcolor{ThemeColourBlue};
colours[2] := \MPcolor{ThemeColourYellow};
% Determine the maximum colour index.
max_colours := 0;
forever:
exitunless known(colours[max_colours+1]);
max_colours := max_colours + 1;
endfor;
numeric base_index;
boolean new_page;
base_index := 0;
new_page := true;
vardef ThemeBase( expr colour ) =
fill Page withcolor transparent(1, .85, colour );
enddef;
% Return a random number up to max_colours - 1.
vardef RandomColourIndex =
(round( uniformdeviate( max_colours - 1 ) ))
enddef;
% Return a random number that is not equal to the given number,
% using modulus math and the maximum number of available colours.
vardef DiscontinuousRandomIndex( expr index ) =
((index + 1 + RandomColourIndex) mod (max_colours + 1))
enddef;
\stopMPinclusions
\startuseMPgraphic{page:ThemeBackground}
ThemeBase( colours[ base_index ] );
% Force the ThemeTitleStyle to pick a new background colour. This is
% required because ThemeTitleStyle is executed before ThemeBackround.
new_page := true;
\stopuseMPgraphic
\startuseMPgraphic{heading:ThemeTitleStyle}
% On each new page, pick a unique base colour for the background.
if new_page:
new_page := false;
base_index := DiscontinuousRandomIndex( base_index );
fi
% Pick a colour that differs from the page background.
complementary_index := DiscontinuousRandomIndex( base_index );
% Draw each word in the title using one of the complementary colours.
draw textext( \MPstring{heading:title} ) rotated 30
withcolor colours[ complementary_index ];
\stopuseMPgraphic
\defineoverlay[page:ThemeBackground][\uniqueMPgraphic{page:ThemeBackground}]
\defineoverlay[page:ThemeStyle][\uniqueMPgraphic{page:ThemeStyle}]
\defineframed[ThemeTitleStyle][
background=\useMPgraphic{ThemeTitleStyle},
]
% Called by applytosplitstringword for each word in the title.
\def\processword#1{%
\setMPtext{heading:title}{#1}%
\useMPgraphic{heading:ThemeTitleStyle}
}
\define[1]\ThemeChapterTitle{\applytosplitstringword\processword{#1}}
\setuphead[chapter][deeptextcommand={\ThemeChapterTitle}]
\starttext
\setupbackgrounds[page][background={page:ThemeBackground}]
\startchapter[title={One is 1st}] \input knuth \stopchapter
\startchapter[title={Two is 2nd}] \input zapf \stopchapter
\startchapter[title={Three is 3rd}] \input knuth \stopchapter
\startchapter[title={Four is 4th}] \input zapf \stopchapter
\startchapter[title={Five is 5th}] \input knuth \stopchapter
\startchapter[title={Six is 6th}] \input zapf \stopchapter
\stoptext
然后,将随机颜色应用于标题中的每个单词,以使颜色永远不会与页面背景颜色冲突。