Blendend Intro

View Source
Mix.install(
  [
    {:blendend, path: Path.expand("..", __DIR__)},
    {:kino, "~> 0.18.0"}
  ])

Load drawing macros

use Blendend.Draw

A lightweight tour of Blendend in Livebook.

Note: Run from the project main directory so Mix.install/1 can load the local blendend dependency.

Canvas + Clear

Create a canvas, clear it with a color, and show the image as PNG.

{:ok, b64} =
  draw 240, 120 do
    clear(fill: rgb(235, 240, 245))
  end

Kino.Image.new(Base.decode64!(b64), "image/png")

Fill vs Stroke

Draw simple shapes with fill and stroke options.

{:ok, b64} =
  draw 320, 200 do
    clear(fill: rgb(245, 245, 245))

    rect 30, 30, 120, 80, fill: rgb(40, 140, 200)
    circle 220, 70, 50, stroke: rgb(200, 80, 60), stroke_width: 6
  end

Kino.Image.new(Base.decode64!(b64), "image/png")

Paths with a Small DSL

Use the path macro to build and reuse shapes with move_to/2, line_to/2, and close/0.

star =
  path do
    move_to 100, 20
    line_to 120, 80
    line_to 60, 45
    line_to 140, 45
    line_to 80, 80
    close()
  end

{:ok, b64} =
  draw 200, 120 do
    clear(fill: rgb(250, 250, 250))
    fill_path star, fill: rgb(255, 215, 0)
    stroke_path star, stroke: rgb(30, 30, 30), stroke_width: 2
  end

Kino.Image.new(Base.decode64!(b64), "image/png")

Gradients

Build a gradient once, then use it as a fill.

grad =
  linear_gradient 0, 0, 0, 200 do
    add_stop 0.0, rgb(40, 120, 240)
    add_stop 1.0, rgb(200, 240, 255)
  end

{:ok, b64} =
  draw 260, 180 do
    clear(fill: rgb(240, 240, 240))
    rect 20, 20, 220, 140, fill: grad
  end

Kino.Image.new(Base.decode64!(b64), "image/png")

Reusing a Path with Transforms

Cache a path and place copies with a transform matrix.


path leaf do
  move_to(0, 0)
  quad_to(20, -10, 40, 0)
  quad_to(20, 10, 0, 0)
  close()
end

{:ok, b64} =
  draw 240, 180 do
    clear(fill: rgb(250, 250, 250))

    for i <- 0..4 do
      m = matrix()

      matrix from: m do
        translate(40 + i * 35, 90.0)
        rotate(i * 0.35)
      end

      dst = path()

      Blendend.Path.add_path!(dst, leaf, m)
      fill_path(dst, fill: rgb(60 + i * 30, 160, 100 + i * 20))
    end
  end

Kino.Image.new(Base.decode64!(b64), "image/png")

Blur / Shadow a Path

We can blur a path and drop a soft shadow.

tri =
  path do
    move_to 50, 30
    line_to 150, 30
    line_to 100, 120
    close()
  end

{:ok, b64} =
  draw 220, 160 do
    clear(fill: rgb(250, 250, 250))
    shadow_path(tri, 6, 6, 8, fill: rgb(0, 0, 0, 60))
    fill_path(tri, fill: rgb(80, 140, 220))
  end

Kino.Image.new(Base.decode64!(b64), "image/png")