2013-03-06 17:24:17 +00:00
|
|
|
|
|
|
|
module Graphics.Collage where
|
|
|
|
|
2013-04-29 03:57:48 +00:00
|
|
|
import List
|
|
|
|
import Native.Utils (toFloat)
|
2013-03-06 17:24:17 +00:00
|
|
|
import Either
|
2013-04-28 12:21:46 +00:00
|
|
|
import Native.Matrix2D as Matrix
|
2013-03-21 09:29:23 +00:00
|
|
|
import Native.Graphics.Collage as N
|
|
|
|
import Graphics.Element
|
2013-04-28 12:21:46 +00:00
|
|
|
import Color as Color
|
2013-03-06 17:24:17 +00:00
|
|
|
|
2013-03-21 09:29:23 +00:00
|
|
|
type Form = {
|
|
|
|
theta : Float,
|
|
|
|
scale : Float,
|
|
|
|
x : Float,
|
|
|
|
y : Float,
|
|
|
|
form : BasicForm
|
|
|
|
}
|
2013-03-06 17:24:17 +00:00
|
|
|
|
|
|
|
data FillStyle
|
2013-03-21 09:29:23 +00:00
|
|
|
= Solid Color
|
2013-03-06 17:24:17 +00:00
|
|
|
| Texture String
|
|
|
|
| Gradient Gradient
|
|
|
|
|
2013-03-27 01:50:18 +00:00
|
|
|
data LineCap = Butt | Round | Square
|
|
|
|
data LineJoin = Smooth | Sharp | Clipped
|
|
|
|
|
|
|
|
type LineStyle = {
|
|
|
|
color : Color,
|
|
|
|
width : Float,
|
|
|
|
cap : LineCap,
|
|
|
|
join : LineJoin,
|
|
|
|
miterLimit : Float,
|
|
|
|
dashing : [Int],
|
|
|
|
dashOffset : Int
|
|
|
|
}
|
|
|
|
|
2013-05-05 19:11:45 +00:00
|
|
|
defaultLine : LineStyle
|
2013-03-27 01:50:18 +00:00
|
|
|
defaultLine = {
|
|
|
|
color = Color.black,
|
|
|
|
width = 1,
|
|
|
|
cap = Butt,
|
|
|
|
join = Sharp,
|
|
|
|
dashing = [],
|
|
|
|
dashOffset = 0,
|
|
|
|
miterLimit = 10
|
|
|
|
}
|
|
|
|
|
2013-05-11 20:44:28 +00:00
|
|
|
-- default LineStyles
|
2013-05-05 19:11:45 +00:00
|
|
|
solid : Color -> LineStyle
|
2013-03-27 16:52:16 +00:00
|
|
|
solid clr = { defaultLine | color <- clr }
|
2013-05-05 19:11:45 +00:00
|
|
|
dashed : Color -> LineStyle
|
2013-03-27 16:52:16 +00:00
|
|
|
dashed clr = { defaultLine | color <- clr, dashing <- [8,4] }
|
2013-05-05 19:11:45 +00:00
|
|
|
dotted : Color -> LineStyle
|
2013-03-27 16:52:16 +00:00
|
|
|
dotted clr = { defaultLine | color <- clr, dashing <- [3,3] }
|
2013-03-27 01:50:18 +00:00
|
|
|
|
2013-03-06 17:24:17 +00:00
|
|
|
data BasicForm
|
2013-03-16 08:11:15 +00:00
|
|
|
= FPath LineStyle Path
|
2013-03-06 17:24:17 +00:00
|
|
|
| FShape (Either LineStyle FillStyle) Shape
|
|
|
|
| FImage Int Int (Int,Int) String
|
|
|
|
| FElement Element
|
2013-03-24 06:54:00 +00:00
|
|
|
| FGroup Matrix [Form]
|
2013-03-06 17:24:17 +00:00
|
|
|
|
2013-03-21 09:29:23 +00:00
|
|
|
form f = { theta = 0, scale = 1, x = 0, y = 0, form = f }
|
2013-03-16 20:00:59 +00:00
|
|
|
|
2013-03-21 09:29:23 +00:00
|
|
|
fill style shape = form (FShape (Right style) shape)
|
2013-03-06 17:24:17 +00:00
|
|
|
|
|
|
|
filled : Color -> Shape -> Form
|
|
|
|
filled color shape = fill (Solid color) shape
|
|
|
|
|
|
|
|
textured : String -> Shape -> Form
|
|
|
|
textured src shape = fill (Texture src) shape
|
|
|
|
|
|
|
|
gradient : Gradient -> Shape -> Form
|
|
|
|
gradient grad shape = fill (Gradient grad) shape
|
|
|
|
|
2013-03-24 06:54:00 +00:00
|
|
|
outlined : LineStyle -> Shape -> Form
|
|
|
|
outlined style shape = form (FShape (Left style) shape)
|
2013-03-06 17:24:17 +00:00
|
|
|
|
2013-03-24 06:54:00 +00:00
|
|
|
traced : LineStyle -> Path -> Form
|
|
|
|
traced style path = form (FPath style path)
|
2013-03-16 08:11:15 +00:00
|
|
|
|
2013-05-11 20:44:28 +00:00
|
|
|
-- Draw a sprite
|
|
|
|
-- w width
|
|
|
|
-- h height
|
|
|
|
-- pos (px,py) coordinates into the sprite map
|
|
|
|
-- src The location of the image
|
2013-03-16 08:11:15 +00:00
|
|
|
sprite : Int -> Int -> (Int,Int) -> String -> Form
|
2013-03-21 09:29:23 +00:00
|
|
|
sprite w h pos src = form (FImage w h pos src)
|
2013-03-16 08:11:15 +00:00
|
|
|
|
|
|
|
toForm : Element -> Form
|
2013-03-21 09:29:23 +00:00
|
|
|
toForm e = form (FElement e)
|
2013-03-06 17:24:17 +00:00
|
|
|
|
2013-03-21 09:29:23 +00:00
|
|
|
group : [Form] -> Form
|
2013-03-24 06:54:00 +00:00
|
|
|
group fs = form (FGroup Matrix.identity fs)
|
|
|
|
|
|
|
|
groupTransform : Matrix -> [Form] -> Form
|
|
|
|
groupTransform matrix fs = form (FGroup matrix fs)
|
2013-03-06 17:24:17 +00:00
|
|
|
|
2013-03-21 09:29:23 +00:00
|
|
|
rotate : Float -> Form -> Form
|
|
|
|
rotate t f = { f | theta <- f.theta + t }
|
2013-03-06 17:24:17 +00:00
|
|
|
|
2013-05-05 19:11:45 +00:00
|
|
|
scale : Float -> Form -> Form
|
|
|
|
scale s f = { f | scale <- f.scale * s }
|
2013-03-21 09:29:23 +00:00
|
|
|
|
2013-05-16 20:10:50 +00:00
|
|
|
move : (Float,Float) -> Form -> Form
|
|
|
|
move (x,y) f = { f | x <- f.x + x, y <- f.y + y }
|
2013-05-05 19:11:45 +00:00
|
|
|
|
|
|
|
moveX : Float -> Form -> Form
|
|
|
|
moveX x f = { f | x <- f.x + x }
|
|
|
|
|
|
|
|
moveY : Float -> Form -> Form
|
|
|
|
moveY y f = { f | y <- f.y + y }
|
2013-03-21 09:29:23 +00:00
|
|
|
|
|
|
|
collage : Int -> Int -> [Form] -> Element
|
2013-04-29 03:57:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
type Path = [(Float,Float)]
|
|
|
|
|
|
|
|
path : [(Number a,Number a)] -> Path
|
|
|
|
path ps = ps
|
|
|
|
|
|
|
|
segment : (Number a,Number a) -> (Number a,Number a) -> Path
|
|
|
|
segment p1 p2 = [p1,p2]
|
|
|
|
|
|
|
|
type Shape = [(Float,Float)]
|
|
|
|
|
|
|
|
polygon : [(Number a,Number a)] -> Shape
|
|
|
|
polygon points = points
|
|
|
|
|
|
|
|
rect : Number a -> Number a -> Shape
|
|
|
|
rect w h = [ (0-w/2,0-h/2), (0-w/2,h/2), (w/2,h/2), (w/2,0-h/2) ]
|
|
|
|
|
|
|
|
oval : Number a -> Number a -> Shape
|
|
|
|
oval w h =
|
|
|
|
let n = 50
|
|
|
|
t = 2 * Math.PI / n
|
|
|
|
hw = w/2
|
|
|
|
hh = h/2
|
|
|
|
f i = (hw * Math.cos (t*i), hh * Math.sin (t*i))
|
|
|
|
in map f [0..n-1]
|
|
|
|
|
|
|
|
circle : Number a -> Shape
|
|
|
|
circle r = oval (2*r) (2*r)
|
|
|
|
|
|
|
|
ngon : Int -> Number a -> Shape
|
|
|
|
ngon n r =
|
|
|
|
let m = toFloat n
|
|
|
|
t = 2 * Math.PI / m
|
|
|
|
f i = ( r * Math.cos (t*i), r * Math.sin (t*i) )
|
|
|
|
in map f [0..n-1]
|