diff --git a/docs/figma-gradient.md b/docs/figma-gradient.md new file mode 100644 index 00000000..6fef3332 --- /dev/null +++ b/docs/figma-gradient.md @@ -0,0 +1,52 @@ +# Figma Gradient + +- [figma paint - gradient paint](https://www.figma.com/plugin-docs/api/Paint/#gradientpaint) +- [css gradient](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient) + +## gradient type + +- linear gradient +- radial gradient +- angular gradient +- diamond gradient + +### linear gradient + +**css** + +- [linear-gradient()]() + +`linear-gradient()` css function + +```css +background: linear-gradient(45deg, blue, red); +``` + +> **syntax** +> +> wip + +**flutter** + +- [LinearGradient()](https://api.flutter.dev/flutter/painting/LinearGradient-class.html) + +### radial gradient + +**css** + +- [radial-gradient()]() + +```css +background: radial-gradient(red, blue); +``` + +**flutter** + +- [RadialGradient()](https://api.flutter.dev/flutter/painting/RadialGradient-class.html) + +> **gradient paint opacity** +> +> gradient color's opacity \* fill's opacity + +> **gradient paint degree** +> WIP diff --git a/externals/reflect-core b/externals/reflect-core index dde6fca1..cc76dca6 160000 --- a/externals/reflect-core +++ b/externals/reflect-core @@ -1 +1 @@ -Subproject commit dde6fca1a062fa0c4ed8e331d3c28c2a76c0e8fd +Subproject commit cc76dca6a282d323353fbc1fa9d784fa06e949bd diff --git a/packages/builder-css-styles/background/index.ts b/packages/builder-css-styles/background/index.ts index 04f029c2..6275e36d 100644 --- a/packages/builder-css-styles/background/index.ts +++ b/packages/builder-css-styles/background/index.ts @@ -7,6 +7,7 @@ import { color } from "../color"; import { array } from "@reflect-ui/uiutils"; import { Color, GradientType } from "@reflect-ui/core"; import { linearGradient } from "../linear-gradient"; +import { radialGradient } from "../radial-gradient"; /** * @todo - not implemented @@ -29,9 +30,14 @@ export function background(bg: Background): CSSProperties { background: linearGradient(_primary), }; } + case GradientType.RADIAL: { + return { + background: radialGradient(_primary), + }; + } default: console.error( - "other than linear-gradient is not supported yet.", + "other than linear, radial gradient is not supported yet.", _primary ); } diff --git a/packages/builder-css-styles/radial-gradient/index.ts b/packages/builder-css-styles/radial-gradient/index.ts new file mode 100644 index 00000000..60db4811 --- /dev/null +++ b/packages/builder-css-styles/radial-gradient/index.ts @@ -0,0 +1,18 @@ +import { RadialGradientManifest } from "@reflect-ui/core"; +import { CSSProperty } from "@coli.codes/css"; +import { color } from "../color"; + +/** + * https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/radial-gradient() + * + * @param g + * @returns + */ +export function radialGradient(g: RadialGradientManifest): CSSProperty.Color { + // TODO: + // 1. center support + // 2. radius support + + const colors = g.colors.map(color).join(", "); + return `radial-gradient(${colors})`; +} diff --git a/packages/designto-flutter/make/make-flutter-box-decoration.ts b/packages/designto-flutter/make/make-flutter-box-decoration.ts index 2b60aca1..33dd8ea0 100644 --- a/packages/designto-flutter/make/make-flutter-box-decoration.ts +++ b/packages/designto-flutter/make/make-flutter-box-decoration.ts @@ -6,6 +6,7 @@ import { interpretImageFill } from "../interpreter/image.interpret"; import * as painting from "../painting"; import { makeColorFromRGBO } from "./make-flutter-color"; import { tokenizeBorder, tokenize_gradient } from "@designto/token"; +import { LinearGradient, RadialGradient } from "@reflect-ui/core"; type DecorationBackgroundLike = | flutter.Color @@ -106,16 +107,17 @@ export function makeBoxDecorationColorBg( switch (fill.type) { case "GRADIENT_ANGULAR": case "GRADIENT_DIAMOND": - case "GRADIENT_RADIAL": // TODO: handle above gradient types (only linear is handled) - console.log( - "not handled: `GRADIENT_RADIAL` | `GRADIENT_DIAMOND` | `GRADIENT_ANGULAR`" - ); + console.log("not handled: `GRADIENT_DIAMOND` | `GRADIENT_ANGULAR`"); return undefined; case "GRADIENT_LINEAR": - const g = tokenize_gradient(fill as Figma.GradientPaint); - return painting.linearGradient(g); + const lg = tokenize_gradient(fill as Figma.GradientPaint); + return painting.linearGradient(lg as LinearGradient); + case "GRADIENT_RADIAL": + const rg = tokenize_gradient(fill as Figma.GradientPaint); + return painting.radialGradient(rg as RadialGradient); case "SOLID": + console.log("solid color"); return makeColorFromRGBO(fill.color, opacity); default: throw `making colored box decoraton with fill type "${fill?.type}" is not allowed."`; diff --git a/packages/designto-flutter/painting/index.ts b/packages/designto-flutter/painting/index.ts index a71c2c4d..50c252b0 100644 --- a/packages/designto-flutter/painting/index.ts +++ b/packages/designto-flutter/painting/index.ts @@ -6,6 +6,7 @@ export * from "./painting-box-shape"; export * from "./painting-box-shadow"; export * from "./painting-border"; export * from "./painting-border-side"; +export * from "./painting-radial-gradient"; export * from "./painting-text-style"; export * from "./painting-text-decoration"; export * from "./painting-font-style"; diff --git a/packages/designto-flutter/painting/painting-box-decoration.ts b/packages/designto-flutter/painting/painting-box-decoration.ts index 6fcf9b5f..e2fc7a17 100644 --- a/packages/designto-flutter/painting/painting-box-decoration.ts +++ b/packages/designto-flutter/painting/painting-box-decoration.ts @@ -1,7 +1,9 @@ import { BoxDecoration } from "@flutter-builder/flutter"; -import { Color } from "@reflect-ui/core"; +import { Color, Gradient, GradientType } from "@reflect-ui/core"; import { Background } from "@reflect-ui/core/lib/background"; import * as dartui from "../dart-ui"; +import { linearGradient } from "./painting-linear-gradient"; +import { radialGradient } from "./painting-radial-gradient"; function fromColor(color: Color): BoxDecoration { return new BoxDecoration({ @@ -19,7 +21,7 @@ function fromBackground(b: Background): BoxDecoration { } else { switch (b.type) { case "gradient": { - console.error("gradient bg not ready"); + return fromGradient(b as Gradient); break; } case "graphics": { @@ -33,8 +35,32 @@ function fromBackground(b: Background): BoxDecoration { } } -function fromGradient(): BoxDecoration { - throw "not ready."; +function fromGradient(g: Gradient): BoxDecoration { + switch (g?._type) { + case GradientType.LINEAR: { + return new BoxDecoration({ + gradient: linearGradient(g), + }); + } + case GradientType.RADIAL: { + return new BoxDecoration({ + gradient: radialGradient(g), + }); + } + + // It is only used to make it safer in case of an emergency. + case undefined: { + return; + } + default: { + // TODO: add; + // GRADIENT_ANGULAR; + // GRADIENT_DIAMOND; + throw new Error( + `Gradient type of "${g}" is not yet supported on flutter platform.` + ); + } + } } function fromImage(): BoxDecoration { diff --git a/packages/designto-flutter/painting/painting-radial-gradient.ts b/packages/designto-flutter/painting/painting-radial-gradient.ts new file mode 100644 index 00000000..27396036 --- /dev/null +++ b/packages/designto-flutter/painting/painting-radial-gradient.ts @@ -0,0 +1,12 @@ +import { RadialGradient } from "@reflect-ui/core"; +import * as flutter from "@flutter-builder/flutter"; +import * as dartui from "../dart-ui"; + +export function radialGradient(g: RadialGradient): flutter.RadialGradient { + return new flutter.RadialGradient({ + // TODO: add center + // TODO: add radius + colors: g.colors.map((c) => dartui.color(c)), + stops: g.stops, + }); +} diff --git a/packages/designto-flutter/tokens-to-flutter-widget/index.ts b/packages/designto-flutter/tokens-to-flutter-widget/index.ts index 81fecddf..7cc135f1 100644 --- a/packages/designto-flutter/tokens-to-flutter-widget/index.ts +++ b/packages/designto-flutter/tokens-to-flutter-widget/index.ts @@ -280,8 +280,8 @@ function compose( ..._deco_part_shape_and_border_radius, ..._deco_part_bg, boxShadow: painting.boxShadow(widget.boxShadow), - // TODO: - // background: + // TODO: background list + // background: painting.linearGradient(widget.background.gradient), }), // key: _key, }); diff --git a/packages/designto-token/token-gradient/gradient.ts b/packages/designto-token/token-gradient/gradient.ts index 7ff59262..8e1dc088 100644 --- a/packages/designto-token/token-gradient/gradient.ts +++ b/packages/designto-token/token-gradient/gradient.ts @@ -1,13 +1,16 @@ import { Figma } from "@design-sdk/figma-types"; -import { Color, LinearGradient } from "@reflect-ui/core"; +import { + Color, + LinearGradient, + Gradient, + RadialGradient, +} from "@reflect-ui/core"; import { color_utils } from "@design-sdk/core"; import { tokenize_gradient_direction_from_angle } from "../token-gradient"; import { roundNumber } from "@reflect-ui/uiutils"; -export function tokenize_gradient( - gradient: Figma.GradientPaint -): LinearGradient { - // TODO Handle transform percisely. +export function tokenize_gradient(gradient: Figma.GradientPaint): Gradient { + // TODO: Handle transform percisely. // https://www.figma.com/plugin-docs/api/Transform/ // https://www.mathworks.com/discovery/affine-transformation.html const direction = tokenize_gradient_direction_from_angle( @@ -45,16 +48,21 @@ export function tokenize_gradient( stops: stopPoints, }); case "GRADIENT_RADIAL": - console.error("GRADIENT_RADIAL not handled"); - // TODO - break; + return new RadialGradient({ + center: direction.begin, + colors: colors, + stops: stopPoints, + // TODO: support radius + }); + + // TODO: case "GRADIENT_ANGULAR": console.error("GRADIENT_ANGULAR not handled"); - // TODO + // TODO: break; case "GRADIENT_DIAMOND": console.error("GRADIENT_DIAMOND not handled"); - // TODO + // TODO: break; } }