mirror of
https://github.com/typst/typst
synced 2025-05-17 02:25:27 +08:00
Improve color and gradient docs
This commit is contained in:
parent
a7fbe5151e
commit
38f59c2a27
@ -356,7 +356,7 @@ fn code_block(resolver: &dyn Resolver, lang: &str, text: &str) -> Html {
|
||||
md::escape::escape_html(&mut buf, &display).unwrap();
|
||||
buf.push_str("</pre>");
|
||||
return Html::new(buf);
|
||||
} else if !matches!(lang, "example" | "typ") {
|
||||
} else if !matches!(lang, "example" | "typ" | "preview") {
|
||||
let set = &*typst_library::text::SYNTAXES;
|
||||
let buf = syntect::html::highlighted_html_for_string(
|
||||
&display,
|
||||
@ -369,10 +369,14 @@ fn code_block(resolver: &dyn Resolver, lang: &str, text: &str) -> Html {
|
||||
return Html::new(buf);
|
||||
}
|
||||
|
||||
let root = typst::syntax::parse(&display);
|
||||
let highlighted = Html::new(typst::syntax::highlight_html(&root));
|
||||
if lang == "typ" {
|
||||
return Html::new(format!("<pre>{}</pre>", highlighted.as_str()));
|
||||
let mut highlighted = None;
|
||||
if matches!(lang, "example" | "typ") {
|
||||
let root = typst::syntax::parse(&display);
|
||||
let html = Html::new(typst::syntax::highlight_html(&root));
|
||||
if lang == "typ" {
|
||||
return Html::new(format!("<pre>{}</pre>", html.as_str()));
|
||||
}
|
||||
highlighted = Some(html);
|
||||
}
|
||||
|
||||
let id = FileId::new(None, VirtualPath::new("main.typ"));
|
||||
|
@ -77,7 +77,7 @@ pub trait Resolver {
|
||||
fn image(&self, filename: &str, data: &[u8]) -> String;
|
||||
|
||||
/// Produce HTML for an example.
|
||||
fn example(&self, hash: u128, source: Html, frames: &[Frame]) -> Html;
|
||||
fn example(&self, hash: u128, source: Option<Html>, frames: &[Frame]) -> Html;
|
||||
|
||||
/// Determine the commits between two tags.
|
||||
fn commits(&self, from: &str, to: &str) -> Vec<Commit>;
|
||||
@ -780,7 +780,7 @@ mod tests {
|
||||
None
|
||||
}
|
||||
|
||||
fn example(&self, _: u128, _: Html, _: &[Frame]) -> Html {
|
||||
fn example(&self, _: u128, _: Option<Html>, _: &[Frame]) -> Html {
|
||||
Html::new(String::new())
|
||||
}
|
||||
|
||||
|
@ -32,158 +32,122 @@ const ANGLE_EPSILON: f32 = 1e-5;
|
||||
/// - HSL through the [`color.hsl` function]($color.hsl)
|
||||
/// - HSV through the [`color.hsv` function]($color.hsv)
|
||||
///
|
||||
/// Typst provides the following built-in colors:
|
||||
///
|
||||
/// `black`, `gray`, `silver`, `white`, `navy`, `blue`, `aqua`, `teal`,
|
||||
/// `eastern`, `purple`, `fuchsia`, `maroon`, `red`, `orange`, `yellow`,
|
||||
/// `olive`, `green`, and `lime`.
|
||||
///
|
||||
/// # Example
|
||||
/// The predefined colors and the color constructors are available globally and
|
||||
/// also in the color type's scope, so you can write either of the following
|
||||
/// two:
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(fill: aqua)
|
||||
/// #rect(fill: color.aqua)
|
||||
/// ```
|
||||
///
|
||||
/// ## Color maps
|
||||
/// Typst also includes a number of preset color maps. In the following section,
|
||||
/// the list of available color maps is given, along with a sample of each gradient
|
||||
/// and relevant comments. Most of these color maps are chosen to be color blind
|
||||
/// friendly.
|
||||
/// # Predefined colors
|
||||
/// Typst defines the following built-in colors:
|
||||
///
|
||||
/// ### Turbo
|
||||
/// The [`turbo`]($color.map.turbo) gradient is a rainbow-like gradient that is
|
||||
/// perceptually uniform. You can learn more about the turbo color map on
|
||||
/// Google's [blog post](https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html).
|
||||
/// | Color | Definition |
|
||||
/// |-----------|:-------------------|
|
||||
/// | `black` | `{luma(0)}` |
|
||||
/// | `gray` | `{luma(170)}` |
|
||||
/// | `silver` | `{luma(221)}` |
|
||||
/// | `white` | `{luma(255)}` |
|
||||
/// | `navy` | `{rgb("#001f3f")}` |
|
||||
/// | `blue` | `{rgb("#0074d9")}` |
|
||||
/// | `aqua` | `{rgb("#7fdbff")}` |
|
||||
/// | `teal` | `{rgb("#39cccc")}` |
|
||||
/// | `eastern` | `{rgb("#239dad")}` |
|
||||
/// | `purple` | `{rgb("#b10dc9")}` |
|
||||
/// | `fuchsia` | `{rgb("#f012be")}` |
|
||||
/// | `maroon` | `{rgb("#85144b")}` |
|
||||
/// | `red` | `{rgb("#ff4136")}` |
|
||||
/// | `orange` | `{rgb("#ff851b")}` |
|
||||
/// | `yellow` | `{rgb("#ffdc00")}` |
|
||||
/// | `olive` | `{rgb("#3d9970")}` |
|
||||
/// | `green` | `{rgb("#2ecc40")}` |
|
||||
/// | `lime` | `{rgb("#01ff70")}` |
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(width: 100%, height: 20pt, fill: gradient.linear(..color.map.turbo))
|
||||
/// ```
|
||||
/// The predefined colors and the most important color constructors are
|
||||
/// available globally and also in the color type's scope, so you can write
|
||||
/// either `color.red` or just `red`.
|
||||
///
|
||||
/// ### Cividis
|
||||
/// The [`cividis`]($color.map.cividis) gradient is a blue to gray to yellow
|
||||
/// gradient. You can learn more about the Cividis color map on the
|
||||
/// Berkley Institute for Data Science's [blog post](https://bids.github.io/colormap/).
|
||||
/// ```preview
|
||||
/// #let colors = (
|
||||
/// "black", "gray", "silver", "white",
|
||||
/// "navy", "blue", "aqua", "teal",
|
||||
/// "eastern", "purple", "fuchsia",
|
||||
/// "maroon", "red", "orange", "yellow",
|
||||
/// "olive", "green", "lime",
|
||||
/// )
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(width: 100%, height: 20pt, fill: gradient.linear(..color.map.cividis))
|
||||
/// ```
|
||||
///
|
||||
/// ### Rainbow
|
||||
/// The [`rainbow`]($color.map.rainbow) gradient cycles through the full color
|
||||
/// spectrum. This color map is best used by setting the interpolation color
|
||||
/// space to [HSL]($color.hsl).
|
||||
///
|
||||
/// **Attention:** The rainbow gradient is _not suitable_ for data visualization
|
||||
/// because it is not perceptually uniform, so the differences between values
|
||||
/// become unclear to your readers. It should only be used for decorative
|
||||
/// purposes.
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(
|
||||
/// width: 100%,
|
||||
/// height: 20pt,
|
||||
/// fill: gradient.linear(..color.map.rainbow, space: color.hsl)
|
||||
/// #set text(font: "PT Sans")
|
||||
/// #set page(width: auto)
|
||||
/// #grid(
|
||||
/// columns: 9,
|
||||
/// gutter: 10pt,
|
||||
/// ..colors.map(name => {
|
||||
/// let c = eval(name)
|
||||
/// let cp = c.components()
|
||||
/// let x = cp.sum() / cp.len()
|
||||
/// set text(fill: white) if x < 50%
|
||||
/// set square(stroke: black) if c == white
|
||||
/// set align(center + horizon)
|
||||
/// square(size: 50pt, fill: c, name)
|
||||
/// })
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// ### Spectral
|
||||
/// The [`spectral`]($color.map.spectral) gradient is a red to yellow to blue
|
||||
/// gradient. Spectral does not take any parameters.
|
||||
/// # Predefined color maps
|
||||
/// Typst also includes a number of preset color maps that can be used for
|
||||
/// gradients. Most of these color maps are chosen to be color blind friendly.
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(width: 100%, height: 20pt, fill: gradient.linear(..color.map.spectral))
|
||||
/// | Map | Details |
|
||||
/// |------------|:------------------------------------------------------------|
|
||||
/// | `turbo` | A perceptually uniform rainbow-like color map. Read [this blog post](https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html) for more details. |
|
||||
/// | `cividis` | A blue to gray to yellow color map. See [this blog post](https://bids.github.io/colormap/) for more details. |
|
||||
/// | `rainbow` | Cycles through the full color spectrum. This color map is best used by setting the interpolation color space to [HSL]($color.hsl). The rainbow gradient is **not suitable** for data visualization because it is not perceptually uniform, so the differences between values become unclear to your readers. It should only be used for decorative purposes. |
|
||||
/// | `spectral` | Red to yellow to blue color map. |
|
||||
/// | `viridis` | A purple to teal to yellow color map. |
|
||||
/// | `inferno` | A black to red to yellow color map. |
|
||||
/// | `magma` | A black to purple to yellow color map. |
|
||||
/// | `plasma` | A purple to pink to yellow color map. |
|
||||
/// | `rocket` | A black to red to white color map. |
|
||||
/// | `mako` | A black to teal to yellow color map. |
|
||||
/// | `vlag` | A light blue to white to red color map. |
|
||||
/// | `icefire` | A light teal to black to yellow color map. |
|
||||
/// | `flare` | A orange to purple color map that is perceptually uniform. |
|
||||
/// | `crest` | A blue to white to red color map. |
|
||||
///
|
||||
/// Some popular presets are not included because they are not available under a
|
||||
/// free licence. Others, like
|
||||
/// [Jet](https://jakevdp.github.io/blog/2014/10/16/how-bad-is-your-colormap/),
|
||||
/// are not included because they are not not color blind friendly. Feel free to
|
||||
/// use or create a package with other presets that are useful to you!
|
||||
///
|
||||
/// ```preview
|
||||
/// #set page(width: auto, height: auto)
|
||||
/// #set text(font: "PT Sans", size: 8pt)
|
||||
///
|
||||
/// #let maps = (
|
||||
/// "turbo", "cividis", "rainbow", "spectral",
|
||||
/// "viridis", "inferno", "magma", "plasma",
|
||||
/// "rocket", "mako", "vlag", "icefire",
|
||||
/// "flare", "crest",
|
||||
/// )
|
||||
///
|
||||
/// #stack(dir: ltr, spacing: 3pt, ..maps.map((name) => {
|
||||
/// let map = eval("color.map." + name)
|
||||
/// stack(
|
||||
/// dir: ttb,
|
||||
/// block(
|
||||
/// width: 15pt,
|
||||
/// height: 100pt,
|
||||
/// fill: gradient.linear(..map, angle: 90deg),
|
||||
/// ),
|
||||
/// block(
|
||||
/// width: 15pt,
|
||||
/// height: 32pt,
|
||||
/// move(dy: 8pt, rotate(90deg, name)),
|
||||
/// ),
|
||||
/// )
|
||||
/// }))
|
||||
/// ```
|
||||
///
|
||||
/// ### Viridis
|
||||
/// The [`viridis`]($color.map.viridis) gradient is a purple to teal to yellow
|
||||
/// gradient. Viridis does not take any parameters.
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(width: 100%, height: 20pt, fill: gradient.linear(..color.map.viridis))
|
||||
/// ```
|
||||
///
|
||||
/// ### Inferno
|
||||
/// The [`inferno`]($color.map.inferno) gradient is a black to red to yellow
|
||||
/// gradient. Inferno does not take any parameters.
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(width: 100%, height: 20pt, fill: gradient.linear(..color.map.inferno))
|
||||
/// ```
|
||||
///
|
||||
/// ### Magma
|
||||
/// The [`magma`]($color.map.magma) gradient is a black to purple to yellow
|
||||
/// gradient. Magma does not take any parameters.
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(width: 100%, height: 20pt, fill: gradient.linear(..color.map.magma))
|
||||
/// ```
|
||||
///
|
||||
/// ### Plasma
|
||||
/// The [`plasma`]($color.map.plasma) gradient is a purple to pink to yellow
|
||||
/// gradient. Plasma does not take any parameters.
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(width: 100%, height: 20pt, fill: gradient.linear(..color.map.plasma))
|
||||
/// ```
|
||||
///
|
||||
/// ### Rocket
|
||||
/// The [`rocket`]($color.map.rocket) gradient is a black to red to white
|
||||
/// gradient. Rocket does not take any parameters.
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(width: 100%, height: 20pt, fill: gradient.linear(..color.map.rocket))
|
||||
/// ```
|
||||
///
|
||||
/// ### Mako
|
||||
/// The [`mako`]($color.map.mako) gradient is a black to teal to yellow gradient
|
||||
///. Mako does not take any parameters.
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(width: 100%, height: 20pt, fill: gradient.linear(..color.map.mako))
|
||||
/// ```
|
||||
///
|
||||
/// ### Vlag
|
||||
/// The [`vlag`]($color.map.vlag) gradient is a light blue to white to red
|
||||
/// gradient. Vlag does not take any parameters.
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(width: 100%, height: 20pt, fill: gradient.linear(..color.map.vlag))
|
||||
/// ```
|
||||
///
|
||||
/// ### Icefire
|
||||
/// The [`icefire`]($color.map.icefire) gradient is a light teal to black to
|
||||
/// yellow gradient. Icefire does not take any parameters.
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(width: 100%, height: 20pt, fill: gradient.linear(..color.map.icefire))
|
||||
/// ```
|
||||
///
|
||||
/// ### Flare
|
||||
/// The [`flare`]($color.map.flare) gradient is an orange to purple gradient that
|
||||
/// is perceptually uniform. Flare does not take any parameters.
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(width: 100%, height: 20pt, fill: gradient.linear(..color.map.flare))
|
||||
/// ```
|
||||
///
|
||||
/// ### Crest
|
||||
/// The [`crest`]($color.map.crest) gradient is a blue to white to red gradient .
|
||||
///Crest does not take any parameters.
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(width: 100%, height: 20pt, fill: gradient.linear(..color.map.crest))
|
||||
/// ```
|
||||
///
|
||||
/// ### On other presets
|
||||
/// [Jet](https://jakevdp.github.io/blog/2014/10/16/how-bad-is-your-colormap/)
|
||||
/// is not color blind friendly and should not be used for data visualization,
|
||||
/// which is why it is not included in Typst. Other popular presets are not
|
||||
/// neccesarily under a free licence, which is why we could not include them.
|
||||
///
|
||||
/// Feel free to use or create a package with other presets useful to you!
|
||||
#[ty(scope)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Color {
|
||||
@ -251,7 +215,6 @@ impl Color {
|
||||
pub const MAP: fn() -> Module = || {
|
||||
// Lazy to avoid re-allocating.
|
||||
static MODULE: Lazy<Module> = Lazy::new(map);
|
||||
|
||||
MODULE.clone()
|
||||
};
|
||||
|
||||
@ -276,10 +239,11 @@ impl Color {
|
||||
|
||||
/// Create a grayscale color.
|
||||
///
|
||||
/// A grayscale color is represented internally by a single `lightness` component.
|
||||
/// A grayscale color is represented internally by a single `lightness`
|
||||
/// component.
|
||||
///
|
||||
/// These components are also available using the [`components`]($color.components)
|
||||
/// method.
|
||||
/// These components are also available using the
|
||||
/// [`components`]($color.components) method.
|
||||
///
|
||||
/// ```example
|
||||
/// #for x in range(250, step: 50) {
|
||||
@ -294,7 +258,9 @@ impl Color {
|
||||
/// The lightness component.
|
||||
#[external]
|
||||
lightness: Component,
|
||||
/// The color to convert to grayscale.
|
||||
/// Alternatively: The color to convert to grayscale.
|
||||
///
|
||||
/// If this is given, the `lightness` should not be given.
|
||||
#[external]
|
||||
color: Color,
|
||||
) -> SourceResult<Color> {
|
||||
@ -315,14 +281,15 @@ impl Color {
|
||||
/// - Creating grayscale images with uniform perceived lightness
|
||||
/// - Creating smooth and uniform color transition and gradients
|
||||
///
|
||||
/// A linear Oklab color is represented internally by an array of four components:
|
||||
/// A linear Oklab color is represented internally by an array of four
|
||||
/// components:
|
||||
/// - lightness ([`ratio`]($ratio))
|
||||
/// - a ([`float`]($float) in the range `[-0.4..0.4]`)
|
||||
/// - b ([`float`]($float) in the range `[-0.4..0.4]`)
|
||||
/// - alpha ([`ratio`]($ratio))
|
||||
///
|
||||
/// These components are also available using the [`components`]($color.components)
|
||||
/// method.
|
||||
/// These components are also available using the
|
||||
/// [`components`]($color.components) method.
|
||||
///
|
||||
/// ```example
|
||||
/// #square(
|
||||
@ -346,7 +313,9 @@ impl Color {
|
||||
/// The key component.
|
||||
#[external]
|
||||
alpha: RatioComponent,
|
||||
/// The color to convert to Oklab.
|
||||
/// Alternatively: The color to convert to Oklab.
|
||||
///
|
||||
/// If this is given, the individual components should not be given.
|
||||
#[external]
|
||||
color: Color,
|
||||
) -> SourceResult<Color> {
|
||||
@ -375,19 +344,20 @@ impl Color {
|
||||
/// perform color operations such as blending and interpolation. Although,
|
||||
/// you should prefer to use the [`oklab` function]($color.oklab) for these.
|
||||
///
|
||||
/// A linear RGB(A) color is represented internally by an array of four components:
|
||||
/// A linear RGB(A) color is represented internally by an array of four
|
||||
/// components:
|
||||
/// - red ([`ratio`]($ratio))
|
||||
/// - green ([`ratio`]($ratio))
|
||||
/// - blue ([`ratio`]($ratio))
|
||||
/// - alpha ([`ratio`]($ratio))
|
||||
///
|
||||
/// These components are also available using the [`components`]($color.components)
|
||||
/// method.
|
||||
/// These components are also available using the
|
||||
/// [`components`]($color.components) method.
|
||||
///
|
||||
/// ```example
|
||||
/// #square(
|
||||
/// fill: color.linear-rgb(30%, 50%, 10%)
|
||||
/// )
|
||||
/// #square(fill: color.linear-rgb(
|
||||
/// 30%, 50%, 10%,
|
||||
/// ))
|
||||
/// ```
|
||||
#[func(title = "Linear RGB")]
|
||||
pub fn linear_rgb(
|
||||
@ -406,7 +376,9 @@ impl Color {
|
||||
/// The alpha component.
|
||||
#[external]
|
||||
alpha: Component,
|
||||
/// The color to convert to linear RGB(A).
|
||||
/// Alternatively: The color to convert to linear RGB(A).
|
||||
///
|
||||
/// If this is given, the individual components should not be given.
|
||||
#[external]
|
||||
color: Color,
|
||||
) -> SourceResult<Color> {
|
||||
@ -450,20 +422,6 @@ impl Color {
|
||||
/// The real arguments (the other arguments are just for the docs, this
|
||||
/// function is a bit involved, so we parse the arguments manually).
|
||||
args: Args,
|
||||
/// The color in hexadecimal notation.
|
||||
///
|
||||
/// Accepts three, four, six or eight hexadecimal digits and optionally
|
||||
/// a leading hash.
|
||||
///
|
||||
/// If this string is given, the individual components should not be given.
|
||||
///
|
||||
/// ```example
|
||||
/// #text(16pt, rgb("#239dad"))[
|
||||
/// *Typst*
|
||||
/// ]
|
||||
/// ```
|
||||
#[external]
|
||||
hex: Str,
|
||||
/// The red component.
|
||||
#[external]
|
||||
red: Component,
|
||||
@ -476,7 +434,23 @@ impl Color {
|
||||
/// The alpha component.
|
||||
#[external]
|
||||
alpha: Component,
|
||||
/// The color to convert to RGB(A).
|
||||
/// Alternatively: The color in hexadecimal notation.
|
||||
///
|
||||
/// Accepts three, four, six or eight hexadecimal digits and optionally
|
||||
/// a leading hash.
|
||||
///
|
||||
/// If this is given, the individual components should not be given.
|
||||
///
|
||||
/// ```example
|
||||
/// #text(16pt, rgb("#239dad"))[
|
||||
/// *Typst*
|
||||
/// ]
|
||||
/// ```
|
||||
#[external]
|
||||
hex: Str,
|
||||
/// Alternatively: The color to convert to RGB(a).
|
||||
///
|
||||
/// If this is given, the individual components should not be given.
|
||||
#[external]
|
||||
color: Color,
|
||||
) -> SourceResult<Color> {
|
||||
@ -511,8 +485,8 @@ impl Color {
|
||||
/// - yellow ([`ratio`]($ratio))
|
||||
/// - key ([`ratio`]($ratio))
|
||||
///
|
||||
/// These components are also available using the [`components`]($color.components)
|
||||
/// method.
|
||||
/// These components are also available using the
|
||||
/// [`components`]($color.components) method.
|
||||
///
|
||||
/// ```example
|
||||
/// #square(
|
||||
@ -536,7 +510,9 @@ impl Color {
|
||||
/// The key component.
|
||||
#[external]
|
||||
key: RatioComponent,
|
||||
/// The color to convert to CMYK.
|
||||
/// Alternatively: The color to convert to CMYK.
|
||||
///
|
||||
/// If this is given, the individual components should not be given.
|
||||
#[external]
|
||||
color: Color,
|
||||
) -> SourceResult<Color> {
|
||||
@ -569,8 +545,8 @@ impl Color {
|
||||
/// - lightness ([`ratio`]($ratio))
|
||||
/// - alpha ([`ratio`]($ratio))
|
||||
///
|
||||
/// These components are also available using the [`components`]($color.components)
|
||||
/// method.
|
||||
/// These components are also available using the
|
||||
/// [`components`]($color.components) method.
|
||||
///
|
||||
/// ```example
|
||||
/// #square(
|
||||
@ -594,7 +570,9 @@ impl Color {
|
||||
/// The alpha component.
|
||||
#[external]
|
||||
alpha: Component,
|
||||
/// The color to convert to HSL.
|
||||
/// Alternatively: The color to convert to HSL.
|
||||
///
|
||||
/// If this is given, the individual components should not be given.
|
||||
#[external]
|
||||
color: Color,
|
||||
) -> SourceResult<Color> {
|
||||
@ -627,8 +605,8 @@ impl Color {
|
||||
/// - value ([`ratio`]($ratio))
|
||||
/// - alpha ([`ratio`]($ratio))
|
||||
///
|
||||
/// These components are also available using the [`components`]($color.components)
|
||||
/// method.
|
||||
/// These components are also available using the
|
||||
/// [`components`]($color.components) method.
|
||||
///
|
||||
/// ```example
|
||||
/// #square(
|
||||
@ -652,7 +630,9 @@ impl Color {
|
||||
/// The alpha component.
|
||||
#[external]
|
||||
alpha: Component,
|
||||
/// The color to convert to HSL.
|
||||
/// Alternatively: The color to convert to HSL.
|
||||
///
|
||||
/// If this is given, the individual components should not be given.
|
||||
#[external]
|
||||
color: Color,
|
||||
) -> SourceResult<Color> {
|
||||
@ -673,7 +653,7 @@ impl Color {
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts this color into its components.
|
||||
/// Extracts the components of this color.
|
||||
///
|
||||
/// The size and values of this array depends on the color space. You can
|
||||
/// obtain the color space using [`space`]($color.space). Below is a table
|
||||
|
@ -19,29 +19,41 @@ use crate::syntax::{Span, Spanned};
|
||||
/// the [`gradient.radial` function]($gradient.radial), and conic gradients
|
||||
/// through the [`gradient.conic` function]($gradient.conic).
|
||||
///
|
||||
/// A gradient can be used for the following purposes:
|
||||
/// - As a fill to paint the interior of a shape:
|
||||
/// `{rect(fill: gradient.linear(..))}`
|
||||
/// - As a stroke to paint the outline of a shape:
|
||||
/// `{rect(stroke: 1pt + gradient.linear(..))}`
|
||||
/// - As the fill of text:
|
||||
/// `{set text(fill: gradient.linear(..))}`
|
||||
/// - As a color map you can [sample]($gradient.sample) from:
|
||||
/// `{gradient.linear(..).sample(0.5)}`
|
||||
///
|
||||
/// # Examples
|
||||
/// ```example
|
||||
/// >>> #set square(size: 50pt)
|
||||
/// #stack(
|
||||
/// dir: ltr,
|
||||
/// square(size: 50pt, fill: gradient.linear(..color.map.rainbow)),
|
||||
/// square(size: 50pt, fill: gradient.radial(..color.map.rainbow)),
|
||||
/// square(size: 50pt, fill: gradient.conic(..color.map.rainbow)),
|
||||
/// spacing: 1fr,
|
||||
/// square(fill: gradient.linear(..color.map.rainbow)),
|
||||
/// square(fill: gradient.radial(..color.map.rainbow)),
|
||||
/// square(fill: gradient.conic(..color.map.rainbow)),
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// # Gradients on text
|
||||
/// Gradients are supported on text but only when setting the relativeness to
|
||||
/// either `{auto}` (the default value) or `{"parent"}`. It was decided that
|
||||
/// glyph-by-glyph gradients would not be supported out-of-the-box but can be
|
||||
/// emulated using [show rules]($styling/#show-rules).
|
||||
///
|
||||
/// You can use gradients on text as follows:
|
||||
/// Gradients are also supported on text, but only when setting the
|
||||
/// [relativeness]($gradient.relative) to either `{auto}` (the default value) or
|
||||
/// `{"parent"}`. To create word-by-word or glyph-by-glyph gradients, you can
|
||||
/// wrap the words or characters of your text in [boxes]($box) manually or
|
||||
/// through a [show rule]($styling/#show-rules).
|
||||
///
|
||||
/// ```example
|
||||
/// #set page(margin: 1pt)
|
||||
/// >>> #set page(width: auto, height: auto, margin: 12pt)
|
||||
/// >>> #set text(size: 12pt)
|
||||
/// #set text(fill: gradient.linear(red, blue))
|
||||
/// #let rainbow(content) = {
|
||||
/// set text(fill: gradient.linear(..color.map.rainbow))
|
||||
/// box(content)
|
||||
/// set text(fill: gradient.linear(..color.map.rainbow))
|
||||
/// box(content)
|
||||
/// }
|
||||
///
|
||||
/// This is a gradient on text, but with a #rainbow[twist]!
|
||||
@ -56,24 +68,13 @@ use crate::syntax::{Span, Spanned};
|
||||
/// the offsets when defining a gradient. In this case, Typst will space all
|
||||
/// stops evenly.
|
||||
///
|
||||
/// # Usage
|
||||
/// Gradients can be used for the following purposes:
|
||||
/// - As fills to paint the interior of a shape:
|
||||
/// `{rect(fill: gradient.linear(..))}`
|
||||
/// - As strokes to paint the outline of a shape:
|
||||
/// `{rect(stroke: 1pt + gradient.linear(..))}`
|
||||
/// - As color maps you can [sample]($gradient.sample) from:
|
||||
/// `{gradient.linear(..).sample(0.5)}`
|
||||
///
|
||||
/// Gradients are not currently supported on text.
|
||||
///
|
||||
/// # Relativeness
|
||||
/// The location of the `{0%}` and `{100%}` stops is dependant on the dimensions
|
||||
/// of a container. This container can either be the shape they are painted on,
|
||||
/// or to the closest container ancestor. This is controlled by the `relative`
|
||||
/// argument of a gradient constructor. By default, gradients are relative to
|
||||
/// the shape they are painted on, unless the gradient is applied on text, in
|
||||
/// which case they are relative to the closest ancestor container.
|
||||
/// or to the closest surrounding container. This is controlled by the
|
||||
/// `relative` argument of a gradient constructor. By default, gradients are
|
||||
/// relative to the shape they are painted on, unless the gradient is applied on
|
||||
/// text, in which case they are relative to the closest ancestor container.
|
||||
///
|
||||
/// Typst determines the ancestor container as follows:
|
||||
/// - For shapes that are placed at the root/top level of the document, the
|
||||
@ -98,16 +99,16 @@ use crate::syntax::{Span, Spanned};
|
||||
/// choosing an interpolation space.
|
||||
///
|
||||
/// | Color space | Perceptually uniform? |
|
||||
/// | ------------------------------- |:----------------------|
|
||||
/// | [Oklab]($color.oklab) | *Yes* |
|
||||
/// | [sRGB]($color.rgb) | *No* |
|
||||
/// | ------------------------------- |-----------------------|
|
||||
/// | [Oklab]($color.oklab) | *Yes* |
|
||||
/// | [sRGB]($color.rgb) | *No* |
|
||||
/// | [linear-RGB]($color.linear-rgb) | *Yes* |
|
||||
/// | [CMYK]($color.cmyk) | *No* |
|
||||
/// | [Grayscale]($color.luma) | *Yes* |
|
||||
/// | [HSL]($color.hsl) | *No* |
|
||||
/// | [HSV]($color.hsv) | *No* |
|
||||
/// | [CMYK]($color.cmyk) | *No* |
|
||||
/// | [Grayscale]($color.luma) | *Yes* |
|
||||
/// | [HSL]($color.hsl) | *No* |
|
||||
/// | [HSV]($color.hsv) | *No* |
|
||||
///
|
||||
/// ```example
|
||||
/// ```preview
|
||||
/// >>> #set text(fill: white, font: "IBM Plex Sans", 8pt)
|
||||
/// >>> #set block(spacing: 0pt)
|
||||
/// #let spaces = (
|
||||
@ -141,52 +142,20 @@ use crate::syntax::{Span, Spanned};
|
||||
/// right-to-left, and 270° from bottom-to-top.
|
||||
///
|
||||
/// ```example
|
||||
/// #set block(spacing: 0pt)
|
||||
/// >>> #set square(size: 50pt)
|
||||
/// #stack(
|
||||
/// dir: ltr,
|
||||
/// square(size: 50pt, fill: gradient.linear(red, blue, angle: 0deg)),
|
||||
/// square(size: 50pt, fill: gradient.linear(red, blue, angle: 90deg)),
|
||||
/// square(size: 50pt, fill: gradient.linear(red, blue, angle: 180deg)),
|
||||
/// square(size: 50pt, fill: gradient.linear(red, blue, angle: 270deg)),
|
||||
/// spacing: 1fr,
|
||||
/// square(fill: gradient.linear(red, blue, angle: 0deg)),
|
||||
/// square(fill: gradient.linear(red, blue, angle: 90deg)),
|
||||
/// square(fill: gradient.linear(red, blue, angle: 180deg)),
|
||||
/// square(fill: gradient.linear(red, blue, angle: 270deg)),
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// # Presets
|
||||
/// You can find the full list of presets in the documentation of [`color`]($color),
|
||||
/// below is an overview of them. Note that not all presets are suitable for data
|
||||
/// visualization and full details and relevant sources can be found in the
|
||||
/// documentation of [`color`]($color).
|
||||
///
|
||||
/// ```example
|
||||
/// #set text(fill: white, size: 18pt)
|
||||
/// #set text(top-edge: "bounds", bottom-edge: "bounds")
|
||||
/// #let presets = (
|
||||
/// ("turbo", color.map.turbo),
|
||||
/// ("cividis", color.map.cividis),
|
||||
/// ("rainbow", color.map.rainbow),
|
||||
/// ("spectral", color.map.spectral),
|
||||
/// ("viridis", color.map.viridis),
|
||||
/// ("inferno", color.map.inferno),
|
||||
/// ("magma", color.map.magma),
|
||||
/// ("plasma", color.map.plasma),
|
||||
/// ("rocket", color.map.rocket),
|
||||
/// ("mako", color.map.mako),
|
||||
/// ("vlag", color.map.vlag),
|
||||
/// ("icefire", color.map.icefire),
|
||||
/// ("flare", color.map.flare),
|
||||
/// ("crest", color.map.crest),
|
||||
/// )
|
||||
///
|
||||
/// #stack(
|
||||
/// spacing: 3pt,
|
||||
/// ..presets.map(((name, preset)) => block(
|
||||
/// width: 100%,
|
||||
/// height: 20pt,
|
||||
/// fill: gradient.linear(..preset),
|
||||
/// align(center + horizon, smallcaps(name)),
|
||||
/// ))
|
||||
/// )
|
||||
/// ```
|
||||
/// Typst predefines color maps that you can use with your gradients. See the
|
||||
/// [`color`]($color/#predefined-color-maps) documentation for more details.
|
||||
#[ty(scope)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Gradient {
|
||||
@ -198,13 +167,16 @@ pub enum Gradient {
|
||||
#[scope]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
impl Gradient {
|
||||
/// Creates a new linear gradient.
|
||||
/// Creates a new linear gradient, in which colors transition along a
|
||||
/// straight line.
|
||||
///
|
||||
/// ```example
|
||||
/// #rect(
|
||||
/// width: 100%,
|
||||
/// height: 20pt,
|
||||
/// fill: gradient.linear(..color.map.viridis)
|
||||
/// fill: gradient.linear(
|
||||
/// ..color.map.viridis,
|
||||
/// ),
|
||||
/// )
|
||||
/// ```
|
||||
#[func(title = "Linear Gradient")]
|
||||
@ -225,9 +197,10 @@ impl Gradient {
|
||||
space: ColorSpace,
|
||||
/// The [relative placement](#relativeness) of the gradient.
|
||||
///
|
||||
/// For an element placed at the root/top level of the document, the parent
|
||||
/// is the page itself. For other elements, the parent is the innermost block,
|
||||
/// box, column, grid, or stack that contains the element.
|
||||
/// For an element placed at the root/top level of the document, the
|
||||
/// parent is the page itself. For other elements, the parent is the
|
||||
/// innermost block, box, column, grid, or stack that contains the
|
||||
/// element.
|
||||
#[named]
|
||||
#[default(Smart::Auto)]
|
||||
relative: Smart<Relative>,
|
||||
@ -267,31 +240,34 @@ impl Gradient {
|
||||
})))
|
||||
}
|
||||
|
||||
/// Creates a new radial gradient.
|
||||
/// Creates a new radial gradient, in which colors radiate away from an
|
||||
/// origin.
|
||||
///
|
||||
/// The gradient is defined by two circles: the focal circle and the end
|
||||
/// circle. The focal circle is a circle with center `focal-center` and
|
||||
/// radius `focal-radius`, that defines the points at which the gradient
|
||||
/// starts and has the color of the first stop. The end circle is a circle
|
||||
/// with center `center` and radius `radius`, that defines the points at
|
||||
/// which the gradient ends and has the color of the last stop. The gradient
|
||||
/// is then interpolated between these two circles.
|
||||
///
|
||||
/// Using these four values, also called the focal point for the starting
|
||||
/// circle and the center and radius for the end circle, we can define a
|
||||
/// gradient with more interesting properties than a basic radial gradient:
|
||||
///
|
||||
/// ```example
|
||||
/// #circle(
|
||||
/// radius: 20pt,
|
||||
/// fill: gradient.radial(..color.map.viridis)
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// _Focal Point_
|
||||
/// The gradient is defined by two circles: the focal circle and the end circle.
|
||||
/// The focal circle is a circle with center `focal-center` and radius `focal-radius`,
|
||||
/// that defines the points at which the gradient starts and has the color of the
|
||||
/// first stop. The end circle is a circle with center `center` and radius `radius`,
|
||||
/// that defines the points at which the gradient ends and has the color of the last
|
||||
/// stop. The gradient is then interpolated between these two circles.
|
||||
///
|
||||
/// Using these four values, also called the focal point for the starting circle and
|
||||
/// the center and radius for the end circle, we can define a gradient with more
|
||||
/// interesting properties than a basic radial gradient:
|
||||
///
|
||||
/// ```example
|
||||
/// #circle(
|
||||
/// radius: 20pt,
|
||||
/// fill: gradient.radial(..color.map.viridis, focal-center: (10%, 40%), focal-radius: 5%)
|
||||
/// >>> #set circle(radius: 30pt)
|
||||
/// #stack(
|
||||
/// dir: ltr,
|
||||
/// spacing: 1fr,
|
||||
/// circle(fill: gradient.radial(
|
||||
/// ..color.map.viridis,
|
||||
/// )),
|
||||
/// circle(fill: gradient.radial(
|
||||
/// ..color.map.viridis,
|
||||
/// focal-center: (10%, 40%),
|
||||
/// focal-radius: 5%,
|
||||
/// )),
|
||||
/// )
|
||||
/// ```
|
||||
#[func]
|
||||
@ -316,14 +292,14 @@ impl Gradient {
|
||||
#[named]
|
||||
#[default(Smart::Auto)]
|
||||
relative: Smart<Relative>,
|
||||
/// The center of the last circle of the gradient.
|
||||
/// The center of the end circle of the gradient.
|
||||
///
|
||||
/// A value of `{(50%, 50%)}` means that the end circle is
|
||||
/// centered inside of its container.
|
||||
#[named]
|
||||
#[default(Axes::splat(Ratio::new(0.5)))]
|
||||
center: Axes<Ratio>,
|
||||
/// The radius of the last circle of the gradient.
|
||||
/// The radius of the end circle of the gradient.
|
||||
///
|
||||
/// By default, it is set to `{50%}`. The ending radius must be bigger
|
||||
/// than the focal radius.
|
||||
@ -384,24 +360,24 @@ impl Gradient {
|
||||
})))
|
||||
}
|
||||
|
||||
/// Creates a new conic gradient (i.e a gradient whose color changes
|
||||
/// radially around a center point).
|
||||
/// Creates a new conic gradient, in which colors change radially around a
|
||||
/// center point.
|
||||
///
|
||||
/// ```example
|
||||
/// #circle(
|
||||
/// radius: 20pt,
|
||||
/// fill: gradient.conic(..color.map.viridis)
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// _Center Point_
|
||||
/// You can control the center point of the gradient by using the `center`
|
||||
/// argument. By default, the center point is the center of the shape.
|
||||
///
|
||||
/// ```example
|
||||
/// #circle(
|
||||
/// radius: 20pt,
|
||||
/// fill: gradient.conic(..color.map.viridis, center: (10%, 40%))
|
||||
/// >>> #set circle(radius: 30pt)
|
||||
/// #stack(
|
||||
/// dir: ltr,
|
||||
/// spacing: 1fr,
|
||||
/// circle(fill: gradient.conic(
|
||||
/// ..color.map.viridis,
|
||||
/// )),
|
||||
/// circle(fill: gradient.conic(
|
||||
/// ..color.map.viridis,
|
||||
/// center: (20%, 30%),
|
||||
/// )),
|
||||
/// )
|
||||
/// ```
|
||||
#[func]
|
||||
@ -453,117 +429,18 @@ impl Gradient {
|
||||
})))
|
||||
}
|
||||
|
||||
/// Returns the stops of this gradient.
|
||||
#[func]
|
||||
pub fn stops(&self) -> Vec<Stop> {
|
||||
match self {
|
||||
Self::Linear(linear) => linear
|
||||
.stops
|
||||
.iter()
|
||||
.map(|(color, offset)| Stop { color: *color, offset: Some(*offset) })
|
||||
.collect(),
|
||||
Self::Radial(radial) => radial
|
||||
.stops
|
||||
.iter()
|
||||
.map(|(color, offset)| Stop { color: *color, offset: Some(*offset) })
|
||||
.collect(),
|
||||
Self::Conic(conic) => conic
|
||||
.stops
|
||||
.iter()
|
||||
.map(|(color, offset)| Stop { color: *color, offset: Some(*offset) })
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the mixing space of this gradient.
|
||||
#[func]
|
||||
pub fn space(&self) -> ColorSpace {
|
||||
match self {
|
||||
Self::Linear(linear) => linear.space,
|
||||
Self::Radial(radial) => radial.space,
|
||||
Self::Conic(conic) => conic.space,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the relative placement of this gradient.
|
||||
#[func]
|
||||
pub fn relative(&self) -> Smart<Relative> {
|
||||
match self {
|
||||
Self::Linear(linear) => linear.relative,
|
||||
Self::Radial(radial) => radial.relative,
|
||||
Self::Conic(conic) => conic.relative,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the angle of this gradient.
|
||||
#[func]
|
||||
pub fn angle(&self) -> Option<Angle> {
|
||||
match self {
|
||||
Self::Linear(linear) => Some(linear.angle),
|
||||
Self::Radial(_) => None,
|
||||
Self::Conic(conic) => Some(conic.angle),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the kind of this gradient.
|
||||
#[func]
|
||||
pub fn kind(&self) -> Func {
|
||||
match self {
|
||||
Self::Linear(_) => Self::linear_data().into(),
|
||||
Self::Radial(_) => Self::radial_data().into(),
|
||||
Self::Conic(_) => Self::conic_data().into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sample the gradient at a given position.
|
||||
///
|
||||
/// The position is either a position along the gradient (a [ratio]($ratio)
|
||||
/// between `{0%}` and `{100%}`) or an [angle]($angle). Any value outside
|
||||
/// of this range will be clamped.
|
||||
///
|
||||
/// _The angle will be used for conic gradients once they are available._
|
||||
#[func]
|
||||
pub fn sample(
|
||||
&self,
|
||||
/// The position at which to sample the gradient.
|
||||
t: RatioOrAngle,
|
||||
) -> Color {
|
||||
let value: f64 = t.to_ratio().get();
|
||||
|
||||
match self {
|
||||
Self::Linear(linear) => sample_stops(&linear.stops, linear.space, value),
|
||||
Self::Radial(radial) => sample_stops(&radial.stops, radial.space, value),
|
||||
Self::Conic(conic) => sample_stops(&conic.stops, conic.space, value),
|
||||
}
|
||||
}
|
||||
|
||||
/// Samples the gradient at the given positions.
|
||||
///
|
||||
/// The position is either a position along the gradient (a [ratio]($ratio)
|
||||
/// between `{0%}` and `{100%}`) or an [angle]($angle). Any value outside
|
||||
/// of this range will be clamped.
|
||||
///
|
||||
/// _The angle will be used for conic gradients once they are available._
|
||||
#[func]
|
||||
pub fn samples(
|
||||
&self,
|
||||
/// The positions at which to sample the gradient.
|
||||
#[variadic]
|
||||
ts: Vec<RatioOrAngle>,
|
||||
) -> Array {
|
||||
ts.into_iter().map(|t| self.sample(t).into_value()).collect()
|
||||
}
|
||||
|
||||
/// Creates a sharp version of this gradient.
|
||||
///
|
||||
/// _Sharp gradients_ have discreet jumps between colors, instead of a
|
||||
/// Sharp gradients have discreet jumps between colors, instead of a
|
||||
/// smooth transition. They are particularly useful for creating color
|
||||
/// lists for a preset gradient.
|
||||
///
|
||||
/// ```example
|
||||
/// #set rect(width: 100%, height: 20pt)
|
||||
/// #let grad = gradient.linear(..color.map.rainbow)
|
||||
/// #rect(width: 100%, height: 20pt, fill: grad)
|
||||
/// #rect(width: 100%, height: 20pt, fill: grad.sharp(5))
|
||||
/// #rect(fill: grad)
|
||||
/// #rect(fill: grad.sharp(5))
|
||||
/// #rect(fill: grad.sharp(5, smoothness: 20%))
|
||||
/// ```
|
||||
#[func]
|
||||
pub fn sharp(
|
||||
@ -651,6 +528,15 @@ impl Gradient {
|
||||
|
||||
/// Repeats this gradient a given number of times, optionally mirroring it
|
||||
/// at each repetition.
|
||||
///
|
||||
/// ```example
|
||||
/// #circle(
|
||||
/// radius: 40pt,
|
||||
/// fill: gradient
|
||||
/// .radial(aqua, white)
|
||||
/// .repeat(4),
|
||||
/// )
|
||||
/// ```
|
||||
#[func]
|
||||
pub fn repeat(
|
||||
&self,
|
||||
@ -721,6 +607,100 @@ impl Gradient {
|
||||
})),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the kind of this gradient.
|
||||
#[func]
|
||||
pub fn kind(&self) -> Func {
|
||||
match self {
|
||||
Self::Linear(_) => Self::linear_data().into(),
|
||||
Self::Radial(_) => Self::radial_data().into(),
|
||||
Self::Conic(_) => Self::conic_data().into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the stops of this gradient.
|
||||
#[func]
|
||||
pub fn stops(&self) -> Vec<Stop> {
|
||||
match self {
|
||||
Self::Linear(linear) => linear
|
||||
.stops
|
||||
.iter()
|
||||
.map(|(color, offset)| Stop { color: *color, offset: Some(*offset) })
|
||||
.collect(),
|
||||
Self::Radial(radial) => radial
|
||||
.stops
|
||||
.iter()
|
||||
.map(|(color, offset)| Stop { color: *color, offset: Some(*offset) })
|
||||
.collect(),
|
||||
Self::Conic(conic) => conic
|
||||
.stops
|
||||
.iter()
|
||||
.map(|(color, offset)| Stop { color: *color, offset: Some(*offset) })
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the mixing space of this gradient.
|
||||
#[func]
|
||||
pub fn space(&self) -> ColorSpace {
|
||||
match self {
|
||||
Self::Linear(linear) => linear.space,
|
||||
Self::Radial(radial) => radial.space,
|
||||
Self::Conic(conic) => conic.space,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the relative placement of this gradient.
|
||||
#[func]
|
||||
pub fn relative(&self) -> Smart<Relative> {
|
||||
match self {
|
||||
Self::Linear(linear) => linear.relative,
|
||||
Self::Radial(radial) => radial.relative,
|
||||
Self::Conic(conic) => conic.relative,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the angle of this gradient.
|
||||
#[func]
|
||||
pub fn angle(&self) -> Option<Angle> {
|
||||
match self {
|
||||
Self::Linear(linear) => Some(linear.angle),
|
||||
Self::Radial(_) => None,
|
||||
Self::Conic(conic) => Some(conic.angle),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sample the gradient at a given position.
|
||||
///
|
||||
/// The position is either a position along the gradient (a [ratio]($ratio)
|
||||
/// between `{0%}` and `{100%}`) or an [angle]($angle). Any value outside
|
||||
/// of this range will be clamped.
|
||||
#[func]
|
||||
pub fn sample(
|
||||
&self,
|
||||
/// The position at which to sample the gradient.
|
||||
t: RatioOrAngle,
|
||||
) -> Color {
|
||||
let value: f64 = t.to_ratio().get();
|
||||
|
||||
match self {
|
||||
Self::Linear(linear) => sample_stops(&linear.stops, linear.space, value),
|
||||
Self::Radial(radial) => sample_stops(&radial.stops, radial.space, value),
|
||||
Self::Conic(conic) => sample_stops(&conic.stops, conic.space, value),
|
||||
}
|
||||
}
|
||||
|
||||
/// Samples the gradient at multiple positions at once and returns the
|
||||
/// results as an array.
|
||||
#[func]
|
||||
pub fn samples(
|
||||
&self,
|
||||
/// The positions at which to sample the gradient.
|
||||
#[variadic]
|
||||
ts: Vec<RatioOrAngle>,
|
||||
) -> Array {
|
||||
ts.into_iter().map(|t| self.sample(t).into_value()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Gradient {
|
||||
|
Loading…
x
Reference in New Issue
Block a user