Skip to content

Commit

Permalink
Merge pull request #23 from joseemds/feat/add-transform-api
Browse files Browse the repository at this point in the history
feat: add initial transform API
  • Loading branch information
ghivert authored Sep 3, 2024
2 parents 3ae1750 + 646d3be commit 34b2416
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 0 deletions.
8 changes: 8 additions & 0 deletions sketch/src/sketch.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import sketch/internals/cache/setup as cache
import sketch/internals/style
import sketch/media.{type Query}
import sketch/size.{type Size}
import sketch/transform.{type Transform}

// Types

Expand Down Expand Up @@ -1983,10 +1984,17 @@ pub fn touch_action(value: String) {
property("touch-action", value)
}

/// `transform` will be turned into `transform_` in 4.0.0
pub fn transform(transform: String) {
property("transform", transform)
}

/// `transform_` uses `sketch.transform` to offer an enhanced API for CSS transforms
pub fn transform_(transform_args: List(Transform)) {
let transform_string = transform.to_string(transform_args)
property("transform", transform_string)
}

pub fn transform_box(transform_box: String) {
property("transform-box", transform_box)
}
Expand Down
33 changes: 33 additions & 0 deletions sketch/src/sketch/angle.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import gleam/float

pub opaque type Angle {
Deg(Float)
Rad(Float)
Grad(Float)
Turn(Float)
}

pub fn deg(value: Float) {
Deg(value)
}

pub fn rad(value: Float) {
Rad(value)
}

pub fn grad(value: Float) {
Grad(value)
}

pub fn turn(value: Float) {
Turn(value)
}

pub fn to_string(angle: Angle) {
case angle {
Deg(value) -> float.to_string(value) <> "deg"
Rad(value) -> float.to_string(value) <> "rad"
Grad(value) -> float.to_string(value) <> "grad"
Turn(value) -> float.to_string(value) <> "turn"
}
}
91 changes: 91 additions & 0 deletions sketch/src/sketch/transform.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import gleam/float
import gleam/list
import gleam/string
import sketch/angle.{type Angle}
import sketch/size.{type Size}

pub opaque type Transform {
Translate(Size, Size)
TranslateX(Size)
TranslateY(Size)
Scale(Float, Float)
ScaleX(Float)
ScaleY(Float)
Rotate(Angle)
SkewX(Angle)
SkewY(Angle)
}

fn transform_to_string(value: Transform) {
case value {
Translate(x, y) ->
"translate("
<> string.join([size.to_string(x), size.to_string(y)], ",")
<> ")"
TranslateX(x) -> "translateX(" <> size.to_string(x) <> ")"
TranslateY(y) -> "translateY(" <> size.to_string(y) <> ")"
Scale(x, y) ->
"scale("
<> string.join([float.to_string(x), float.to_string(y)], ",")
<> ")"
ScaleX(x) -> "scaleX(" <> float.to_string(x) <> ")"
ScaleY(y) -> "scaleY(" <> float.to_string(y) <> ")"
Rotate(ang) -> "rotate(" <> angle.to_string(ang) <> ")"
SkewX(x) -> "skewX(" <> angle.to_string(x) <> ")"
SkewY(y) -> "skewY(" <> angle.to_string(y) <> ")"
}
}

pub fn translate2(x: Size, y: Size) {
Translate(x, y)
}

/// `translate(x)` is `translate2(x, size.percent(0))`
pub fn translate(x: Size) {
translate2(x, size.percent(0))
}

pub fn translate_x(x: Size) {
TranslateX(x)
}

pub fn translate_y(y: Size) {
TranslateY(y)
}

pub fn scale2(x: Float, y: Float) {
Scale(x, y)
}

/// `scale(x)` is `scale2(x, x)`
pub fn scale(x: Float) {
scale2(x, x)
}

pub fn scale_x(x: Float) {
ScaleX(x)
}

pub fn scale_y(y: Float) {
ScaleY(y)
}

pub fn rotate(value: Angle) {
Rotate(value)
}

pub fn skew_x(x: Angle) {
SkewX(x)
}

pub fn skew_y(x: Angle) {
SkewY(x)
}

pub fn to_string(value: List(Transform)) {
case value {
[] -> "none"
transform_list ->
list.map(transform_list, transform_to_string) |> string.join(" ")
}
}
91 changes: 91 additions & 0 deletions sketch/test/transform_test.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import gleeunit/should
import sketch/angle
import sketch/size
import sketch/transform

pub fn translate_test() {
[transform.translate(size.px(10))]
|> transform.to_string
|> should.equal("translate(10.0px,0.0%)")
}

pub fn translate2_test() {
[transform.translate2(size.px(10), size.rem(3.0))]
|> transform.to_string
|> should.equal("translate(10.0px,3.0rem)")
}

pub fn translate_x() {
[transform.translate_x(size.px(10))]
|> transform.to_string
|> should.equal("translateX(10px)")
}

pub fn translate_y() {
[transform.translate_y(size.px(10))]
|> transform.to_string
|> should.equal("translateY(10px)")
}

pub fn scale2_test() {
[transform.scale2(10.0, 10.0)]
|> transform.to_string
|> should.equal("scale(10.0,10.0)")
}

pub fn scale_test() {
[transform.scale(10.0)]
|> transform.to_string
|> should.equal("scale(10.0,10.0)")
}

pub fn scale_x_test() {
[transform.scale_x(10.0)]
|> transform.to_string
|> should.equal("scaleX(10.0)")
}

pub fn scale_y_test() {
[transform.scale_y(10.0)]
|> transform.to_string
|> should.equal("scaleY(10.0)")
}

pub fn rotate_test() {
[transform.rotate(angle.rad(2.0))]
|> transform.to_string
|> should.equal("rotate(2.0rad)")
}

pub fn skew_x() {
[transform.skew_x(angle.rad(2.0))]
|> transform.to_string
|> should.equal("skewX(2.0rad)")
}

pub fn skew_y() {
[transform.skew_y(angle.rad(2.0))]
|> transform.to_string
|> should.equal("skewY(2.0rad)")
}

pub fn translate_equiv_test() {
let current = [transform.translate(size.px(10))] |> transform.to_string
let expected =
[transform.translate2(size.px(10), size.percent(0))]
|> transform.to_string

should.equal(current, expected)
}

pub fn scale_equiv_test() {
let current = [transform.scale(10.0)] |> transform.to_string
let expected = [transform.scale2(10.0, 10.0)] |> transform.to_string

should.equal(current, expected)
}

pub fn transform_none_test() {
transform.to_string([])
|> should.equal("none")
}

0 comments on commit 34b2416

Please sign in to comment.