249 | let requirePaths =
250 | if not (attrs.ContainsKey("require-paths")) then "" else
251 | Regex.Match(attrs.["require-paths"], "(.*)
").Groups.[1].Value
252 |
253 | let externalScript =
254 | if not (attrs.ContainsKey("external-script")) then "" else
255 | Regex.Match(attrs.["external-script"], "(.*)
").Groups.[1].Value
256 |
257 |
258 | // Get `title` and `tagline` from the attrs and generate sample page
259 | let html =
260 | { Root = siteRoot;
261 | Active = "samples"; Name = name; Document = document
262 | Application = app; Head = appHead
263 | ExternalScript = externalScript
264 | Title = attrs.["title"]
265 | GithubLink = githubLink
266 | Introduction = if attrs.ContainsKey("intro") then attrs.["intro"] else ""
267 | Tagline = attrs.["tagline"]
268 | AppStyle = appStyle }
269 | |> DotLiquid.page samplePage
270 | ensureDirectory(output > "samples" > outerDir > name)
271 | File.WriteAllText(output > "samples" > outerDir > name > "index.html", html)
272 |
273 |
274 | /// Generates pages from all samples & optionally recompiles the JS too
275 | let generateSamplePages siteRoot recompile () =
276 | traceImportant "Updating sample pages"
277 | let lastEdit path = Directory.GetFiles(path) |> Seq.map File.GetLastWriteTime |> Seq.fold max DateTime.MinValue
278 |
279 | printfn "Samples: %A" (samples |> Seq.toList)
280 | for sample, outerDir in samples do
281 | let outOfDate =
282 | if Directory.Exists(output > "samples" > outerDir > Path.GetFileName(sample)) |> not
283 | then true
284 | else
285 | let sourceModified = lastEdit (fableRoot > sample)
286 | let outputModified = lastEdit (output > "samples" > outerDir > Path.GetFileName(sample))
287 | sourceModified > outputModified
288 | if outOfDate then
289 | let dir = Path.GetFileName(Path.GetDirectoryName(sample))
290 | let name = Path.GetFileName(sample)
291 | traceImportant (sprintf "Generating sample page: %s" name)
292 | generateSamplePage siteRoot dir name sample outerDir
293 | if recompile then
294 | traceImportant (sprintf "Compiling sample: %s" name)
295 | compileSample true name sample outerDir
296 |
297 |
298 | // --------------------------------------------------------------------------------------
299 | // Local Suave server for hosting page during development (with WebSockets refresh!)
300 | // --------------------------------------------------------------------------------------
301 |
302 | open Suave.Sockets
303 | open Suave.Sockets.Control
304 | open Suave.WebSocket
305 | open Suave.Operators
306 |
307 | let refreshEvent = new Event()
308 |
309 | let socketHandler (webSocket : WebSocket) cx = socket {
310 | while true do
311 | let! refreshed =
312 | Control.Async.AwaitEvent(refreshEvent.Publish)
313 | |> Suave.Sockets.SocketOp.ofAsync
314 | do! webSocket.send Text (Suave.Utils.ASCII.bytes "refreshed") true }
315 |
316 | let startWebServer () =
317 | let port = 8911
318 | let serverConfig =
319 | { defaultConfig with
320 | homeFolder = Some (FullName output)
321 | bindings = [ HttpBinding.mkSimple HTTP "127.0.0.1" port ] }
322 | let app =
323 | choose [
324 | Filters.path "/websocket" >=> handShake socketHandler
325 | Writers.setHeader "Cache-Control" "no-cache, no-store, must-revalidate"
326 | >=> Writers.setHeader "Pragma" "no-cache"
327 | >=> Writers.setHeader "Expires" "0"
328 | >=> choose [ Files.browseHome; Filters.path "/" >=> Files.browseFileHome "index.html" ] ]
329 |
330 | let addMime f = function
331 | | ".wav" -> Writers.mkMimeType "audio/wav" false
332 | | ".tsv" -> Writers.mkMimeType "text/tsv" false | ext -> f ext
333 | let app ctx = app { ctx with runtime = { ctx.runtime with mimeTypesMap = addMime ctx.runtime.mimeTypesMap } }
334 |
335 | startWebServerAsync serverConfig app |> snd |> Async.Start
336 | System.Diagnostics.Process.Start (sprintf "http://localhost:%d/index.html" port) |> ignore
337 |
338 |
339 | // --------------------------------------------------------------------------------------
340 | // FAKE targets for generating and releasing documentation
341 | // --------------------------------------------------------------------------------------
342 |
343 | Target "CleanDocs" (fun _ ->
344 | CleanDirs [output]
345 | )
346 |
347 | Target "GenerateDocs" (fun _ ->
348 | prepareDependencies ()
349 | generateStaticPages publishSite true ()
350 | generateSamplePages publishSite true ()
351 | )
352 |
353 | Target "BrowseDocs" (fun _ ->
354 | // Update static pages & sample pages (but don't recompile JS)
355 | let root = "http://localhost:8911"
356 | prepareDependencies ()
357 | generateStaticPages root true ()
358 | generateSamplePages root false ()
359 |
360 | // Setup watchers to regenerate things as needed
361 | let watchAndRefresh f = WatchChanges (fun _ ->
362 | try f(); refreshEvent.Trigger() with e -> traceException e)
363 | use w1 = !! (source + "/**/*.*") |> watchAndRefresh (generateStaticPages root false)
364 | use w2 = !! (templates + "/*.*") |> watchAndRefresh (generateSamplePages root false >> generateStaticPages root true)
365 | use w3 = !! (samplesRoot + "/**/*.*") |> watchAndRefresh (generateSamplePages root true)
366 |
367 | // Start local server
368 | startWebServer ()
369 | traceImportant "Waiting for page edits. Press ^C to kill the process."
370 | System.Threading.Thread.Sleep(-1)
371 | )
372 |
373 | Target "PublishDocs" (fun _ ->
374 | CleanDir temp
375 | Repository.cloneSingleBranch "" githubLink publishBranch temp
376 |
377 | CopyRecursive output temp true |> tracefn "%A"
378 | StageAll temp
379 | Git.Commit.Commit temp (sprintf "Update site (%s)" (DateTime.Now.ToShortDateString()))
380 | Branches.push temp
381 | )
382 |
383 | // --------------------------------------------------------------------------------------
384 | // Regenerate all docs when publishing, by default just generate & browse
385 | // --------------------------------------------------------------------------------------
386 |
387 | "CleanDocs"
388 | ==> "GenerateDocs"
389 | ==> "PublishDocs"
390 |
391 | RunTargetOrDefault "BrowseDocs"
392 |
--------------------------------------------------------------------------------
/docs/helpers.fs:
--------------------------------------------------------------------------------
1 | module Helpers
2 | open System.IO
3 | open Fake
4 | open System
5 |
6 | /// Recursively process all files in the directory tree
7 | let rec processDirectory force indir outdir (exts:seq<_>) func =
8 | let exts = exts |> Seq.map (fun (s:string) -> s.ToLower()) |> set
9 | ensureDirectory outdir
10 | for d in Directory.EnumerateDirectories(indir) do
11 | let name = Path.GetFileName(d)
12 | processDirectory force (Path.Combine(indir, name)) (Path.Combine(outdir, name)) exts func
13 | for file in Directory.GetFiles(indir, "*.*") do
14 | let dir = Path.GetDirectoryName(file)
15 | let name = Path.GetFileNameWithoutExtension(file)
16 | let output = Path.Combine(outdir, sprintf "%s.html" name)
17 |
18 | // Update only when needed
19 | let changeTime = File.GetLastWriteTime(file)
20 | let generateTime = File.GetLastWriteTime(output)
21 | let ext = Path.GetExtension file
22 | if force || changeTime > generateTime then
23 | if exts.Contains(ext) then
24 | func file outdir
25 |
26 | let rec directoryCopy(sourceDirName, destDirName, copySubDirs) =
27 | // Get the subdirectories for the specified directory.
28 | let dir = DirectoryInfo sourceDirName
29 | if not(dir.Exists) then
30 | DirectoryNotFoundException(
31 | "Source directory does not exist or could not be found: "
32 | + sourceDirName) |> raise
33 |
34 | let dirs = dir.GetDirectories()
35 | // If the destination directory doesn't exist, create it.
36 | if not(Directory.Exists(destDirName)) then
37 | Directory.CreateDirectory(destDirName) |> ignore
38 |
39 | // Get the files in the directory and copy them to the new location.
40 | let files = dir.GetFiles()
41 | for file in files do
42 | let temppath = Path.Combine(destDirName, file.Name)
43 | file.CopyTo(temppath, true) |> ignore
44 |
45 | // If copying subdirectories, copy them and their contents to new location.
46 | if copySubDirs then
47 | for subdir in dirs do
48 | let temppath = Path.Combine(destDirName, subdir.Name)
49 | directoryCopy(subdir.FullName, temppath, copySubDirs)
50 |
51 | /// Generates a temp file and deletes it when disposed (to be used via `use`)
52 | type TempFile() =
53 | let name = System.IO.Path.GetTempFileName()
54 | member x.Name = name
55 | static member New() = new TempFile()
56 | interface System.IDisposable with
57 | member x.Dispose() =
58 | File.Delete(name)
59 |
60 |
61 | /// Utils for running NPM and Node
62 | module Util =
63 | let run workingDir fileName args =
64 | let ok =
65 | execProcess (fun info ->
66 | info.FileName <- fileName
67 | info.WorkingDirectory <- workingDir
68 | info.Arguments <- args) TimeSpan.MaxValue
69 | if not ok then failwith (sprintf "'%s> %s %s' task failed" workingDir fileName args)
70 |
71 | module Node =
72 | let run workingDir script args =
73 | let args = sprintf "%s %s" script (String.concat " " args)
74 | Util.run workingDir "node" args
75 |
76 | module Npm =
77 | let npmFilePath args =
78 | if EnvironmentHelper.isUnix
79 | then "npm", args
80 | else "cmd", ("/C npm " + args)
81 |
82 | let run workingDir script args =
83 | sprintf "%s %s" script (String.concat " " args)
84 | |> npmFilePath ||> Util.run workingDir
85 |
86 | let install workingDir modules =
87 | run workingDir "install" modules
88 |
--------------------------------------------------------------------------------
/docs/liquid.fs:
--------------------------------------------------------------------------------
1 | module Suave.DotLiquid
2 |
3 | open System
4 | open System.IO
5 | open DotLiquid
6 | open Microsoft.FSharp.Reflection
7 |
8 | // -------------------------------------------------------------------------------------------------
9 | // Registering things with DotLiquid
10 | // -------------------------------------------------------------------------------------------------
11 |
12 | /// Represents a local file system relative to the specified 'root'
13 | let private localFileSystem roots =
14 | { new DotLiquid.FileSystems.IFileSystem with
15 | member this.ReadTemplateFile(context, templateName) =
16 | let templatePath = context.[templateName] :?> string
17 | let fullPath =
18 | roots |> Seq.pick (fun root ->
19 | let fn = Path.Combine(root, templatePath)
20 | if File.Exists fn then Some fn else None)
21 | if not (File.Exists(fullPath)) then failwithf "File not found: %s" fullPath
22 | File.ReadAllText(fullPath) }
23 |
24 | /// Protects accesses to various DotLiquid internal things
25 | let private safe =
26 | let o = obj()
27 | fun f -> lock o f
28 |
29 | /// Given a type which is an F# record containing seq<_>, list<_> and other
30 | /// records, register the type with DotLiquid so that its fields are accessible
31 | let private registerTypeTree =
32 | let registered = System.Collections.Generic.Dictionary<_, _>()
33 | let rec loop ty =
34 | if not (registered.ContainsKey ty) then
35 | if FSharpType.IsRecord ty then
36 | let fields = FSharpType.GetRecordFields(ty)
37 | Template.RegisterSafeType(ty, [| for f in fields -> f.Name |])
38 | for f in fields do loop f.PropertyType
39 | elif ty.IsGenericType &&
40 | ( let t = ty.GetGenericTypeDefinition()
41 | in t = typedefof> || t = typedefof> ) then
42 | loop (ty.GetGenericArguments().[0])
43 | registered.[ty] <- true
44 | fun ty -> safe (fun () -> loop ty)
45 |
46 | /// Use the ruby naming convention by default
47 | do Template.NamingConvention <- DotLiquid.NamingConventions.RubyNamingConvention()
48 |
49 | // -------------------------------------------------------------------------------------------------
50 | // Parsing and loading DotLiquid templates and caching the results
51 | // -------------------------------------------------------------------------------------------------
52 |
53 | /// Memoize asynchronous function. An item is recomputed when `isValid` returns `false`
54 | let private asyncMemoize isValid f =
55 | let cache = Collections.Concurrent.ConcurrentDictionary<_ , _>()
56 | fun x -> async {
57 | match cache.TryGetValue(x) with
58 | | true, res when isValid x res -> return res
59 | | _ ->
60 | let! res = f x
61 | cache.[x] <- res
62 | return res }
63 |
64 | /// Parse the specified template & register the type that we want to use as "model"
65 | let private parseTemplate template ty =
66 | registerTypeTree ty
67 | let t = Template.Parse(template)
68 | fun k v -> t.Render(Hash.FromDictionary(dict [k, v]))
69 |
70 | /// Asynchronously loads a template & remembers the last write time
71 | /// (so that we can automatically reload the template when file changes)
72 | let private loadTemplate (ty, fileName) = async {
73 | let writeTime = File.GetLastWriteTime(fileName)
74 | use file = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
75 | use reader = new StreamReader(file)
76 | let! razorTemplate = reader.ReadToEndAsync() |> Async.AwaitTask
77 | return writeTime, parseTemplate razorTemplate ty }
78 |
79 | /// Load template & memoize & automatically reload when the file changes
80 | let private loadTemplateCached =
81 | loadTemplate |> asyncMemoize (fun (_, templatePath) (lastWrite, _) ->
82 | File.GetLastWriteTime(templatePath) <= lastWrite )
83 |
84 | // -------------------------------------------------------------------------------------------------
85 | // Public API
86 | // -------------------------------------------------------------------------------------------------
87 |
88 | let mutable private templatesDirs : string list option = None
89 |
90 | /// Set the root directory where DotLiquid is looking for templates. For example, you can
91 | /// write something like this:
92 | ///
93 | /// DotLiquid.setTemplatesDirs (__SOURCE_DIRECTORY__ + "/templates")
94 | ///
95 | /// The current directory is a global variable and so it should not change between
96 | /// multiple HTTP requests. This is a DotLiquid limitation.
97 | let setTemplatesDirs dirs =
98 | if templatesDirs <> Some dirs then
99 | templatesDirs <- Some dirs
100 | safe (fun () -> Template.FileSystem <- localFileSystem dirs)
101 |
102 | /// Render a page using DotLiquid template. Takes a path (relative to the directory specified
103 | /// using `setTemplatesDirs` and a value that is exposed as the "model" variable. You can use
104 | /// any F# record type, seq<_> and list<_> without having to explicitly register the fields.
105 | ///
106 | /// type Page = { Total : int }
107 | /// let app = page "index.html" { Total = 42 }
108 | ///
109 | let page<'T> path (model : 'T) =
110 | let path =
111 | if Path.IsPathRooted path then path else
112 | match templatesDirs with
113 | | None -> failwith "Templates directory not set!"
114 | | Some roots ->
115 | roots |> Seq.pick (fun root ->
116 | let fn = Path.Combine(root, path)
117 | if File.Exists fn then Some fn else None)
118 | let writeTime, renderer =
119 | loadTemplateCached (typeof<'T>, path)
120 | |> Async.RunSynchronously
121 | renderer "model" (box model)
122 |
123 | /// Register functions from a module as filters available in DotLiquid templates.
124 | /// For example, the following snippet lets you write `{{ model.Total | nuce_num }}`:
125 | ///
126 | /// module MyFilters =
127 | /// let niceNum i = if i > 10 then "lot" else "not much"
128 | ///
129 | /// do registerFiltersByName "MyFilters"
130 | ///
131 | let registerFiltersByName name =
132 | let asm = System.Reflection.Assembly.GetExecutingAssembly()
133 | let typ =
134 | [ for t in asm.GetTypes() do
135 | if t.FullName.EndsWith(name) && not(t.FullName.Contains(" Seq.last
137 | Template.RegisterFilter(typ)
138 |
139 | /// Similar to `registerFiltersByName`, but the module is speicfied by its `System.Type`
140 | /// (This is more cumbersome, but safer alternative.)
141 | let registerFiltersByType typ =
142 | Template.RegisterFilter(typ)
143 |
--------------------------------------------------------------------------------
/docs/source/content/custom.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Josefin Sans', sans-serif;
3 | }
4 |
5 | /* Navigation bar - links at the top */
6 | .fb-navbar {
7 | background:#202020;
8 | padding:0px;
9 | }
10 | .navbar {
11 | font-size:18pt;
12 | background:transparent;
13 | border-style:none;
14 | margin:0px;
15 | }
16 | .navbar .navbar-brand {
17 | padding:15px 40px 15px 0px;
18 | font-weight:600;
19 | font-size:22pt;
20 | color:#686868;
21 | }
22 | .navbar li a {
23 | font-weight:300;
24 | font-size:18pt;
25 | padding:15px 25px 15px 25px;
26 | }
27 | .nav .active a {
28 | background-color:#303030 !important;
29 | color:#e0e0e0 !important;
30 | }
31 | .nav li > a:hover {
32 | color:#e0e0e0 !important;
33 | }
34 | .navbar-wrapper {
35 | max-width:550px;
36 | margin:0px auto 0px auto;
37 | }
38 |
39 |
40 |
41 | /* Heading - purple box */
42 | .fb-heading {
43 | background:#7A325D;
44 | color:#f0f0f0;
45 | padding:25px 0px 40px 0px;
46 | text-align:center;
47 | }
48 | .fb-heading h1 {
49 | font-weight:400;
50 | font-size:35pt;
51 | }
52 | .fb-heading p {
53 | font-size:20pt;
54 | }
55 |
56 |
57 | /* Standard page formatting */
58 | .fb-content {
59 | padding:30px 20px 80px 20px;
60 | }
61 | .fb-content-wrapper p, .fb-content-wrapper li {
62 | font-size:14pt;
63 | }
64 | .fb-content-wrapper code {
65 | font:11pt 'Roboto Mono',consolas,monospace;
66 | }
67 | .fb-content-wrapper h1 {
68 | font-size:30pt;
69 | font-weight:500;
70 | }
71 | .fb-content-wrapper h2 {
72 | font-size:24pt;
73 | font-weight:500;
74 | }
75 | .fb-content-wrapper h3 {
76 | font-size:16pt;
77 | font-weight:700;
78 | }
79 | .fb-content-wrapper h3 .anchor, .fb-content-wrapper h2 .anchor, .fb-content-wrapper h1 .anchor {
80 | color:#7A325D;
81 | }
82 | .fb-content-wrapper h3 a.anchor:hover, .fb-content-wrapper h2 a.anchor:hover, .fb-content-wrapper h1 a.anchor:hover {
83 | text-decoration:none;
84 | }
85 | .fb-content-wrapper table code {
86 | background:transparent;
87 | }
88 | .fb-content-wrapper table p {
89 | margin:0px;
90 | }
91 | .fb-content-wrapper th {
92 | background:#f0f0f0;
93 | }
94 | .fb-content-wrapper tr:nth-child(even) {
95 | background:#f8f8f8;
96 | }
97 | .fb-content-wrapper td, .fb-content-wrapper th {
98 | padding:2px 10px 2px 10px;
99 | }
100 | .fb-content-wrapper table {
101 | margin:0px 20px 0px 20px;
102 | border-left:1px solid #e0e0e0;
103 | border-top:1px solid #e0e0e0;
104 | }
105 | .fb-content-wrapper td, .fb-content-wrapper th {
106 | border-right:1px solid #e0e0e0;
107 | border-bottom:1px solid #e0e0e0;
108 | }
109 | .fb-content-wrapper .pre, .fb-content-wrapper .pre td {
110 | border-style:none;
111 | }
112 |
113 | /* Styles for some of the special pages */
114 | .fb-docs .fa {
115 | margin:0px 10px 5px 10px;
116 | float:right;
117 | font-size:40px;
118 | }
119 | .fb-gettingstarted {
120 | background:#f4f4f4;
121 | margin:30px 0px 30px 0px;
122 | }
123 | .fb-buzzwords {
124 | padding:30px 0px 30px 0px;
125 | }
126 | .fb-buzzwords p {
127 | font-size:14pt;
128 | }
129 | .fb-buzzwords .fa {
130 | margin:25px 20px 20px 0px;
131 | float:left;
132 | font-size:40px;
133 | }
134 | .fb-homepage pre {
135 | font-size:11pt;
136 | line-height:18pt;
137 | padding:12px;
138 | }
139 | @media(max-width:768px) {
140 | .fb-gettingstarted {
141 | padding:0px 20px 0px 20px;
142 | }
143 | .fb-buzzwords {
144 | padding:20px 30px 20px 30px;
145 | }
146 | }
147 |
148 |
149 |
150 | /* Hide GitHub button so that it does not overlap with menu */
151 | .gh-forkme { display:none; }
152 | @media (min-width: 768px) {
153 | .gh-forkme { display:block; }
154 | }
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 | /**/
163 |
--------------------------------------------------------------------------------
/docs/source/content/snippets.css:
--------------------------------------------------------------------------------
1 | /*--------------------------------------------------------------------------
2 | Formatting for F# code snippets
3 | /*--------------------------------------------------------------------------*/
4 |
5 | /* strings --- and stlyes for other string related formats */
6 | span.s { color:#E0E268; }
7 | /* printf formatters */
8 | span.pf { color:#E0C57F; }
9 | /* escaped chars */
10 | span.e { color:#EA8675; }
11 |
12 | /* identifiers --- and styles for more specific identifier types */
13 | span.i { color:#d1d1d1; }
14 | /* type or module */
15 | span.t { color:#43AEC6; }
16 | /* function */
17 | span.f { color:#e1e1e1; }
18 | /* DU case or active pattern */
19 | span.p { color:#4ec9b0; }
20 |
21 | /* keywords */
22 | span.k { color:#FAB11D; }
23 | /* comment */
24 | span.c { color:#808080; }
25 | /* operators */
26 | span.o { color:#af75c1; }
27 | /* numbers */
28 | span.n { color:#96C71D; }
29 | /* line number */
30 | span.l { color:#80b0b0; }
31 | /* mutable var or ref cell */
32 | span.v { color:#d1d1d1; font-weight: bold; }
33 | /* inactive code */
34 | span.inactive { color:#808080; }
35 | /* preprocessor */
36 | span.prep { color:#af75c1; }
37 | /* fsi output */
38 | span.fsi { color:#808080; }
39 |
40 | /* omitted */
41 | span.omitted {
42 | background:#3c4e52;
43 | border-radius:5px;
44 | color:#808080;
45 | padding:0px 0px 1px 0px;
46 | }
47 | /* tool tip */
48 | div.tip {
49 | background:#475b5f;
50 | border-radius:4px;
51 | font-size:11pt;
52 | padding:6px 8px 6px 8px;
53 | display:none;
54 | color:#d1d1d1;
55 | z-index:1;
56 | }
57 | table.pre pre {
58 | padding:0px;
59 | margin:0px;
60 | border:none;
61 | }
62 | table.pre, pre.fssnip, pre {
63 | line-height:13pt;
64 | border:1px solid #d8d8d8;
65 | border-collapse:separate;
66 | white-space:pre;
67 | font: 9pt 'Roboto Mono',consolas,monospace;
68 | width:90%;
69 | margin:10px 20px 20px 20px;
70 | background-color:#343434;
71 | padding:10px;
72 | border-radius:5px;
73 | color:#d1d1d1;
74 | }
75 | pre.fssnip code {
76 | font: 9pt 'Roboto Mono',consolas,monospace;
77 | }
78 | table.pre pre {
79 | padding:0px;
80 | margin:0px;
81 | border-radius:0px;
82 | width: 100%;
83 | }
84 | table.pre td {
85 | padding:0px;
86 | white-space:normal;
87 | margin:0px;
88 | }
89 | table.pre td.lines {
90 | width:30px;
91 | }
92 |
93 | pre {
94 | word-wrap: inherit;
95 | overflow: hidden;
96 | }
97 |
--------------------------------------------------------------------------------
/docs/source/content/tips.js:
--------------------------------------------------------------------------------
1 | var currentTip = null;
2 | var currentTipElement = null;
3 |
4 | function hideTip(evt, name, unique) {
5 | var el = document.getElementById(name);
6 | el.style.display = "none";
7 | currentTip = null;
8 | }
9 |
10 | function findPos(obj) {
11 | var curleft = 0;
12 | var curtop = obj.offsetHeight;
13 | while (obj) {
14 | var pos = $(obj).css("position");
15 | if (pos == "relative" || pos == "absolute") break;
16 | curleft += obj.offsetLeft;
17 | curtop += obj.offsetTop;
18 | obj = obj.offsetParent;
19 | };
20 | return [curleft, curtop];
21 | }
22 |
23 | function hideUsingEsc(e) {
24 | if (!e) { e = event; }
25 | hideTip(e, currentTipElement, currentTip);
26 | }
27 |
28 | function showTip(evt, name, unique, owner) {
29 | document.onkeydown = hideUsingEsc;
30 | if (currentTip == unique) return;
31 | currentTip = unique;
32 | currentTipElement = name;
33 |
34 | var pos = findPos(owner ? owner : (evt.srcElement ? evt.srcElement : evt.target));
35 | var posx = pos[0];
36 | var posy = pos[1];
37 |
38 | var el = document.getElementById(name);
39 | var parent = (document.documentElement == null) ? document.body : document.documentElement;
40 | el.style.position = "absolute";
41 | el.style.left = posx + "px";
42 | el.style.top = posy + "px";
43 | el.style.display = "block";
44 | }
--------------------------------------------------------------------------------
/docs/source/images/fsharp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/docs/source/images/fsharp.png
--------------------------------------------------------------------------------
/docs/source/images/hpscreen.pdn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/docs/source/images/hpscreen.pdn
--------------------------------------------------------------------------------
/docs/source/images/hpscreen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/docs/source/images/hpscreen.png
--------------------------------------------------------------------------------
/docs/source/index.md:
--------------------------------------------------------------------------------
1 | - tagline: Explore Fable-graphics through demos!
2 |
3 | # Fable-graphics
4 |
5 | Fable-graphics is a project grouping several binding for graphics library with Fable.
6 |
7 | The current bindings available are:
8 |
9 | - [dc.js](http://dc-js.github.io/dc.js/)
10 | - [d3js](https://d3js.org/)
11 | - [PixiJS](http://www.pixijs.com/) (only v3 for the moment)
12 | - [Three.js](http://threejs.org/)
13 |
14 | You can also contribute more examples by sending us a pull
15 | request [for the samples directory](https://github.com/fable-compiler/fable-graphics/tree/master/samples)!
16 |
17 | ## Samples
18 |
19 | ### dc.js
20 |
21 | *No sample available for the moment*
22 |
23 | ### d3.js
24 |
25 | * [Bar chart](samples/d3/barchart/index.html)
26 |
27 | ### PixiJS
28 |
29 | Here is a selection of some official Pixi.js sampes ported to F#/Fable.
30 | They work with Pixi.js v3.0.11 and v4.x.x although we don't support v4 officially at the moment.
31 |
32 | Each sample displays both the resulting animation and the F# source code
33 |
34 | * [Basic - Your very first pixi sample](samples/pixi/basic/index.html)
35 | * [Graphics - How to use the graphics API](samples/pixi/graphics/index.html)
36 | * [Dragging - Play with mouse events and add interactivity](samples/pixi/dragging/index.html)
37 | * [Blur Filter - How to use a common filter](samples/pixi/blur-filter/index.html)
38 | * [Text - Add simple text and bitmap text with style!](samples/pixi/text/index.html)
39 | * [MovieClip - Load your spritesheet in a movieclip fashion](samples/pixi/movieclip/index.html)
40 | * [Particles - Zounds of sprites with ParticleContainer!](samples/pixi/particle-container/index.html)
41 | * [Render Texture - Eye bleeding effects! ](samples/pixi/render-texture/index.html)
42 | * [Masking - Masking unleashed! ](samples/pixi/masking/index.html)
43 |
44 | ### Three.js
45 |
46 | *No sample available for the moment*
47 |
--------------------------------------------------------------------------------
/docs/source/samples.md:
--------------------------------------------------------------------------------
1 | - tagline: Explore Fable-graphics through fun demos!
2 |
3 | # Fable-graphics samples
4 |
5 | Fable-graphics is great for building modern web application following the [elm architecture](http://guide.elm-lang.org/architecture/index.html).
6 | Hopefully the samples here show you how to get started and gives you some inspiration about how to build your application using Fable-graphics.
7 |
8 | You can also contribute more examples by sending us a pull
9 | request [for the samples directory](https://github.com/fable-compiler/fable-graphics/tree/master/samples)!
10 |
11 | ## Sample applications
12 |
13 | * [Hello world - simple application with one input](samples/helloworld/index.html)
14 | * [Clock - demo of how to have the app consume events from outside the app using a producer](samples/clock/index.html)
15 |
--------------------------------------------------------------------------------
/docs/source/samples/images/add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/docs/source/samples/images/add.png
--------------------------------------------------------------------------------
/docs/templates/content.html:
--------------------------------------------------------------------------------
1 | {% extends "page.html" %}
2 | {% block head %}
3 | {{ model.Heading }} - F# |> BABEL
4 |
5 | {% endblock %}
6 |
7 | {% block content %}
8 |
9 |
10 |
11 |
12 | {{ model.Heading }}
13 | {{ model.Tagline }}
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | {{ model.Content }}
24 |
25 |
26 |
27 |
28 | {% endblock %}
29 |
--------------------------------------------------------------------------------
/docs/templates/page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
32 | {% block head %}
33 | {% endblock %}
34 |
35 |
36 |
37 |
62 |
63 |
64 | {% block content %} {% endblock %}
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/docs/templates/sample.html:
--------------------------------------------------------------------------------
1 | {% extends "page.html" %}
2 | {% block head %}
3 | {{ model.Title }} - F# |> BABEL
4 | {{ model.Head }}
5 |
6 | {% endblock %}
7 |
8 | {% block content %}
9 |
10 |
11 |
12 |
13 | {{ model.Title }}
14 | {{ model.Tagline }} (go to source)
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | {{ model.Introduction }}
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | {{ model.Application }}
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | {{ model.Document }}
43 |
44 |
45 |
46 |
47 | {% endblock %}
48 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "fable-graphics",
4 | "version": "1.0.0",
5 | "description": "Fable bindings and helpers for graphic JS tools",
6 | "main": "index.js",
7 | "scripts": {
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/fable-compiler/fable-graphics.git"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "bugs": {
18 | "url": "https://github.com/fable-graphics/issues"
19 | },
20 | "homepage": "https://github.com/fable-graphics#readme",
21 | "devDependencies": {
22 | "fable-core": "^0.7.25"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/paket.dependencies:
--------------------------------------------------------------------------------
1 | source https://www.nuget.org/api/v2
2 | nuget FAKE
3 | nuget FSharp.Core
4 |
5 | group Docs
6 | source https://www.nuget.org/api/v2
7 |
8 | nuget FAKE
9 | nuget Suave
10 | nuget DotLiquid
11 | nuget FSharp.Formatting 2.14.4
--------------------------------------------------------------------------------
/paket.lock:
--------------------------------------------------------------------------------
1 | NUGET
2 | remote: https://www.nuget.org/api/v2
3 | FAKE (4.37.2)
4 | FSharp.Core (4.0.0.1)
5 |
6 | GROUP Docs
7 | NUGET
8 | remote: https://www.nuget.org/api/v2
9 | DotLiquid (2.0.26)
10 | FAKE (4.37.2)
11 | FSharp.Compiler.Service (2.0.0.6)
12 | FSharp.Core (4.0.0.1)
13 | FSharp.Formatting (2.14.4)
14 | FSharp.Compiler.Service (2.0.0.6)
15 | FSharpVSPowerTools.Core (>= 2.3 < 2.4)
16 | FSharpVSPowerTools.Core (2.3)
17 | FSharp.Compiler.Service (>= 2.0.0.3)
18 | Suave (1.1.3)
19 | FSharp.Core (>= 3.1.2.5)
20 |
--------------------------------------------------------------------------------
/samples/README.md:
--------------------------------------------------------------------------------
1 | # fable-graphics-samples
2 |
3 | * [node.js](http://nodejs.org) and [F#](http://fsharp.org) must be installed in your system.
4 |
5 | * Install first common dependencies. In this directory, type: `npm install`
6 |
7 | * To build any sample, go to its directory (e.g. `samples/pixi/basic`)
8 | and type: `npm run build`
9 |
10 | * After that, to run the sample, in the same directory type: `npm start`
--------------------------------------------------------------------------------
/samples/d3/barchart/README.md:
--------------------------------------------------------------------------------
1 | # To build and run the sample
2 |
3 | * [node.js](http://nodejs.org) and [F#](http://fsharp.org) must be installed in your system.
4 |
5 | * Be sure common dependencies are installed (in `samples` directory, type: `npm install`).
6 |
7 | * To compile the F# code to JS, in this directory type: `npm run build`
8 |
9 | * To start a local server and open a web with the sample, type: `npm start`
10 |
11 | > If you want to listen for changes and recompile
12 | the F# code, you can use `npm build -- --watch`.
13 | Then you need to run `npm start` in a different
14 | terminal window.
15 |
--------------------------------------------------------------------------------
/samples/d3/barchart/barchart.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | - title: Bar chart sample
3 | - tagline: Bar chart implemented using Fable-D3 bindings
4 | - app-style: width:800px; margin:20px auto 50px auto;
5 | - intro: Creating a bar chart using Fable-D3 bindings
6 | *)
7 |
8 | #r "../../node_modules/fable-core/Fable.Core.dll"
9 | #load "../../node_modules/fable-import-d3/Fable.Import.D3.fs"
10 |
11 | open Fable.Core
12 | open Fable.Core.JsInterop
13 | open Fable.Import
14 | open Fable.Import.Browser
15 |
16 | let random = new System.Random()
17 | let dataset = Array.init 25 (fun _ -> (random.Next(3,25)))
18 | let barHeight x = x * 5
19 | let barPadding = 1.
20 | let width = 500.
21 | let height = 100.
22 | let dataSetLength = float dataset.Length
23 |
24 | let svg = D3.Globals.select("#display")
25 | .append("svg")
26 | .attr("width", U3.Case1 width)
27 | .attr("height", U3.Case1 height)
28 |
29 | svg.selectAll("rect")
30 | .data(dataset)
31 | |> fun x -> (unbox> x).enter()
32 | |> fun x -> x.append("rect")
33 | |> fun x -> x.attr("width", fun _ _ _ -> U3.Case1 (System.Math.Abs(width / dataSetLength - barPadding)))
34 | .attr("height", fun data _ _ -> U3.Case1 (float data * 4.))
35 | .attr("x", fun _ x _ -> U3.Case1 (x * (width/dataSetLength)))
36 | .attr("y", fun data _ _ -> U3.Case1 (height - float data * 4.))
37 | .attr("fill", fun data _ _ -> U3.Case2 (sprintf "rgb(63,%A,150)" (data * 10)))
38 | |> ignore
39 |
40 |
41 | svg.selectAll("text")
42 | .data(dataset)
43 | |> fun x -> (unbox> x).enter()
44 | |> fun x -> x.append("text")
45 | |> fun x -> x.text(fun data _ _ -> U3.Case2 (string data))
46 | .attr("x", fun _ x _ -> U3.Case1 (x * (width/dataSetLength)))
47 | .attr("y", fun data _ _ -> U3.Case1 (height - (float data * 4.)))
48 | |> ignore
--------------------------------------------------------------------------------
/samples/d3/barchart/fableconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "sourceMaps": true,
3 | "targets": {
4 | "umd": {
5 | "projFile": "./barchart.fsx",
6 | "rollup": {
7 | "dest": "./public/Main.js",
8 | "external": ["d3"],
9 | "globals": {
10 | "d3": "d3"
11 | },
12 | "format": "umd"
13 | }
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/samples/d3/barchart/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
13 |
14 |
15 |
16 |
17 |
18 | Barchart sample
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/samples/d3/barchart/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "fable-d3-samples",
4 | "version": "0.0.1",
5 | "description": "Creating bar chart using D3 bindings",
6 | "main": "index.js",
7 | "scripts": {
8 | "build": "node ../../node_modules/fable-compiler --target umd",
9 | "start": "node ../../server"
10 | },
11 | "author": "Leo Lorenzo Luis",
12 | "license": "MIT"
13 | }
--------------------------------------------------------------------------------
/samples/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "fable-graphics-samples",
4 | "version": "1.0.0",
5 | "description": "",
6 | "main": "index.js",
7 | "scripts": {
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "finalhandler": "^0.5.0",
15 | "open": "0.0.5",
16 | "pixi.js": "^3.0.11",
17 | "requirejs": "^2.2.0",
18 | "serve-static": "^1.11.1",
19 | "core-js": "^2.4.1",
20 | "fable-compiler": "^0.7.19",
21 | "fable-core": "^0.7.15",
22 | "fable-import-pixi": "0.0.10",
23 | "babel-plugin-transform-runtime": "^6.15.0",
24 | "fable-import-d3": "0.0.4"
25 | }
26 | }
--------------------------------------------------------------------------------
/samples/pixi/basic/README.md:
--------------------------------------------------------------------------------
1 | # To build and run the sample
2 |
3 | * [node.js](http://nodejs.org) and [F#](http://fsharp.org) must be installed in your system.
4 |
5 | * Be sure common dependencies are installed (in `samples` directory, type: `npm install`).
6 |
7 | * To compile the F# code to JS, in this directory type: `npm run build`
8 |
9 | * To start a local server and open a web with the sample, type: `npm start`
10 |
11 | > If you wan to listen for changes and recompile
12 | the F# code, you can use `npm build -- --watch`.
13 | Then you need to run `npm start` in a different
14 | terminal window.
--------------------------------------------------------------------------------
/samples/pixi/basic/basic.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | - title: Basic sample
3 | - tagline: Basic sample implemented with fable-pixi
4 | - app-style: width:800px; margin:20px auto 50px auto;
5 | - external-script: `"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/3.0.11/pixi.min.js"`
6 | - intro: This is a port from [basic sample](http://pixijs.github.io/examples/#/basics/basic.js)
7 | *)
8 |
9 | #r "../../node_modules/fable-core/Fable.Core.dll"
10 | #load "../../node_modules/fable-import-pixi/Fable.Import.Pixi.fs"
11 |
12 | open System
13 | open Fable.Core
14 | open Fable.Core.JsInterop
15 | open Fable.Import.PIXI
16 | open Fable.Import.Browser
17 |
18 | importAll "core-js"
19 |
20 | let options = [
21 | BackgroundColor (float 0x1099bb)
22 | Resolution 1.
23 | ]
24 |
25 | let renderer =
26 | Globals.autoDetectRenderer( 800., 600., options )
27 | |> unbox
28 |
29 | let gameDiv = document.getElementById("game")
30 | gameDiv.appendChild( renderer.view )
31 |
32 | // create the root of the scene graph
33 | let stage = Container()
34 |
35 | // create a texture from an image path
36 | let texture = Texture.fromImage("public/assets/bunny.png")
37 |
38 | // create a new Sprite using the texture
39 | let bunny = Sprite(texture)
40 |
41 | // center the sprite's anchor point
42 | bunny.anchor.x <- 0.5
43 | bunny.anchor.y <- 0.5
44 |
45 | // move the sprite
46 | bunny.position.x <- 200.
47 | bunny.position.y <- 150.
48 |
49 | // Add the bunny to the scene we are building.
50 | stage.addChild(bunny) |> ignore
51 |
52 | let rec animate (dt:float) =
53 | window.requestAnimationFrame(FrameRequestCallback animate) |> ignore
54 |
55 | // just for fun, let's rotate mr rabbit a little
56 | bunny.rotation <- bunny.rotation + 0.1
57 |
58 | // render the container
59 | renderer.render(stage)
60 |
61 | // start animating
62 | animate 0.
63 |
--------------------------------------------------------------------------------
/samples/pixi/basic/fableconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "projFile": "./basic.fsx",
3 | "sourceMaps": true,
4 | "babelPlugins": ["transform-runtime"],
5 | "rollup": {
6 | "dest": "public/bundle.js",
7 | // PIXI will be loaded directly from a script tag
8 | "external": ["PIXI"],
9 | "globals": {
10 | "PIXI": "PIXI"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/basic/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Herebris - IMGUI
6 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/samples/pixi/basic/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "fable-pixi-samples",
4 | "version": "0.0.1",
5 | "description": "F# port of pixi.js official samples",
6 | "main": "index.js",
7 | "scripts": {
8 | "build": "node ../../node_modules/fable-compiler",
9 | "start": "node ../../server"
10 | },
11 | "author": "François Nicaise",
12 | "license": "MIT"
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/basic/public/assets/bunny.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/basic/public/assets/bunny.png
--------------------------------------------------------------------------------
/samples/pixi/blur-filter/README.md:
--------------------------------------------------------------------------------
1 | # To build and run the sample
2 |
3 | * [node.js](http://nodejs.org) and [F#](http://fsharp.org) must be installed in your system.
4 |
5 | * Be sure common dependencies are installed (in `samples` directory, type: `npm install`).
6 |
7 | * To compile the F# code to JS, in this directory type: `npm run build`
8 |
9 | * To start a local server and open a web with the sample, type: `npm start`
10 |
11 | > If you wan to listen for changes and recompile
12 | the F# code, you can use `npm build -- --watch`.
13 | Then you need to run `npm start` in a different
14 | terminal window.
--------------------------------------------------------------------------------
/samples/pixi/blur-filter/blur-filter.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | - title: Blur Filter sample
3 | - tagline: Basic sample implemented with fable-pixi
4 | - app-style: width:800px; margin:20px auto 50px auto;
5 | - external-script: `"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/3.0.11/pixi.min.js"`
6 | - intro: This is a port from [blur filter sample](http://pixijs.github.io/examples/#/filters/blur-filter.js)
7 | *)
8 |
9 | #r "../../node_modules/fable-core/Fable.Core.dll"
10 | #load "../../node_modules/fable-import-pixi/Fable.Import.Pixi.fs"
11 |
12 | open System
13 | open Fable.Core
14 | open Fable.Core.JsInterop
15 | open Fable.Import.PIXI
16 | open Fable.Import.Browser
17 | open Fable.Import.JS
18 |
19 | importAll "core-js"
20 |
21 | let renderer =
22 | Globals.autoDetectRenderer(800., 600.)
23 | |> unbox
24 |
25 | let gameDiv = document.getElementById("game")
26 | gameDiv.appendChild( renderer.view )
27 |
28 | // create the root of the scene graph
29 | let stage = Container()
30 |
31 | let bg = Sprite.fromImage("./public/assets/depth_blur_BG.jpg")
32 | bg.width <- renderer.width
33 | bg.height <- renderer.height
34 | stage.addChild(bg)
35 |
36 | let littleDudes = Sprite.fromImage("./public/assets/depth_blur_dudes.jpg")
37 | littleDudes.position.x <- (renderer.width / 2.) - 315.
38 | littleDudes.position.y <- 200.
39 | stage.addChild(littleDudes)
40 |
41 | let littleRobot = Sprite.fromImage("./public/assets/depth_blur_moby.jpg")
42 | littleRobot.position.x <- (renderer.width / 2.) - 200.
43 | littleRobot.position.y <- 100.
44 | stage.addChild(littleRobot)
45 |
46 | let blurFilter1 = filters.BlurFilter()
47 | let blurFilter2 = filters.BlurFilter()
48 |
49 | littleDudes.filters <- Some(ResizeArray[|blurFilter1 :> AbstractFilter|])
50 | littleRobot.filters <- Some(ResizeArray[|blurFilter2 :> AbstractFilter|])
51 |
52 | let rec animate =
53 | let mutable count = 0.
54 | let rec animate (dt:float) =
55 | count <- count + 0.005
56 | let blurAmount = Math.cos(count)
57 | let blurAmount2 = Math.sin(count)
58 | blurFilter1.blur <- 20. * (blurAmount)
59 | blurFilter2.blur <- 20. * (blurAmount2)
60 | window.requestAnimationFrame(FrameRequestCallback animate) |> ignore
61 | renderer.render(stage)
62 | animate
63 |
64 | // start animating
65 | animate 0.
66 |
--------------------------------------------------------------------------------
/samples/pixi/blur-filter/fableconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "projFile": "./blur-filter.fsx",
3 | "sourceMaps": true,
4 | "babelPlugins": ["transform-runtime"],
5 | "rollup": {
6 | "dest": "public/bundle.js",
7 | // PIXI will be loaded directly from a script tag
8 | "external": ["PIXI"],
9 | "globals": {
10 | "PIXI": "PIXI"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/blur-filter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Herebris - IMGUI
6 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/samples/pixi/blur-filter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "fable-pixi-samples",
4 | "version": "0.0.1",
5 | "description": "F# port of pixi.js official samples",
6 | "main": "index.js",
7 | "scripts": {
8 | "build": "node ../../node_modules/fable-compiler",
9 | "start": "node ../../server"
10 | },
11 | "author": "François Nicaise",
12 | "license": "MIT"
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/blur-filter/public/assets/depth_blur_BG.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/blur-filter/public/assets/depth_blur_BG.jpg
--------------------------------------------------------------------------------
/samples/pixi/blur-filter/public/assets/depth_blur_dudes.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/blur-filter/public/assets/depth_blur_dudes.jpg
--------------------------------------------------------------------------------
/samples/pixi/blur-filter/public/assets/depth_blur_moby.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/blur-filter/public/assets/depth_blur_moby.jpg
--------------------------------------------------------------------------------
/samples/pixi/dragging/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/dragging/.DS_Store
--------------------------------------------------------------------------------
/samples/pixi/dragging/README.md:
--------------------------------------------------------------------------------
1 | # To build and run the sample
2 |
3 | * [node.js](http://nodejs.org) and [F#](http://fsharp.org) must be installed in your system.
4 |
5 | * Be sure common dependencies are installed (in `samples` directory, type: `npm install`).
6 |
7 | * To compile the F# code to JS, in this directory type: `npm run build`
8 |
9 | * To start a local server and open a web with the sample, type: `npm start`
10 |
11 | > If you wan to listen for changes and recompile
12 | the F# code, you can use `npm build -- --watch`.
13 | Then you need to run `npm start` in a different
14 | terminal window.
--------------------------------------------------------------------------------
/samples/pixi/dragging/dragging.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | - title: Dragging sample
3 | - tagline: Basic sample implemented with fable-pixi
4 | - app-style: width:800px; margin:20px auto 50px auto;
5 | - external-script: `"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/3.0.11/pixi.min.js"`
6 | - intro: This is a port from [dragging sample](http://pixijs.github.io/examples/#/demos/dragging.js)
7 | *)
8 |
9 | #r "../../node_modules/fable-core/Fable.Core.dll"
10 | #load "../../node_modules/fable-import-pixi/Fable.Import.Pixi.fs"
11 |
12 | open System
13 | open Fable.Core
14 | open Fable.Core.JsInterop
15 | open Fable.Import.PIXI
16 | open Fable.Import.Browser
17 | open Fable.Import.JS
18 |
19 | importAll "core-js"
20 |
21 | let renderer =
22 | Globals.autoDetectRenderer( 800., 600. )
23 | |> unbox
24 |
25 | let gameDiv = document.getElementById("game")
26 | gameDiv.appendChild( renderer.view )
27 |
28 | // create the root of the scene graph
29 | let stage = Container()
30 |
31 | let texture = Texture.fromImage("./public/assets/bunny.png")
32 |
33 | type MyBunny(texture) =
34 | inherit Sprite(texture)
35 |
36 | member this.noop() = console.log("click")
37 | member this.tap = this.noop
38 | member this.click = this.noop
39 |
40 | member this.mousedown(event) =
41 | this?data <- event?data
42 | this?alpha <- 0.5
43 | this?dragging <- true
44 |
45 | member this.mouseup() =
46 | this?data <- None
47 | this?alpha <- 1.
48 | this?dragging <- false
49 |
50 | member this.mousemove() =
51 | if unbox this?dragging then
52 | let newPosition = this?data?getLocalPosition(this?parent)
53 | this.position.x <- unbox newPosition?x
54 | this.position.y <- unbox newPosition?y
55 |
56 | member this.touchstart = this.mousedown
57 | member this.touchend = this.mouseup
58 | member this.touchendoutside = this.mouseup
59 | member this.mouseupoutside = this.mouseup
60 | member this.touchmove = this.mousemove
61 |
62 | let createBunny x y =
63 | let bunny = MyBunny(texture)
64 | bunny.interactive <- true
65 | bunny.buttonMode <- true
66 | bunny.anchor.set(0.5)
67 | bunny.scale.set(3.)
68 | bunny.position.x <- x
69 | bunny.position.y <- y
70 | stage.addChild(bunny)
71 |
72 | for i in 0..9 do
73 | let x = Math.floor(Math.random() * 800.)
74 | let y = Math.floor(Math.random() * 600.)
75 | createBunny x y |> ignore
76 |
77 | let rec animate (dt:float) =
78 | window.requestAnimationFrame(FrameRequestCallback animate) |> ignore
79 | // render the container
80 | renderer.render(stage)
81 |
82 | animate 0.
83 |
--------------------------------------------------------------------------------
/samples/pixi/dragging/fableconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "projFile": "./dragging.fsx",
3 | "sourceMaps": true,
4 | "babelPlugins": ["transform-runtime"],
5 | "rollup": {
6 | "dest": "public/bundle.js",
7 | // PIXI will be loaded directly from a script tag
8 | "external": ["PIXI"],
9 | "globals": {
10 | "PIXI": "PIXI"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/dragging/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Herebris - IMGUI
6 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/samples/pixi/dragging/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "fable-pixi-samples",
4 | "version": "0.0.1",
5 | "description": "F# port of pixi.js official samples",
6 | "main": "index.js",
7 | "scripts": {
8 | "build": "node ../../node_modules/fable-compiler",
9 | "start": "node ../../server"
10 | },
11 | "author": "François Nicaise",
12 | "license": "MIT"
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/dragging/public/assets/bunny.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/dragging/public/assets/bunny.png
--------------------------------------------------------------------------------
/samples/pixi/graphics/README.md:
--------------------------------------------------------------------------------
1 | # To build and run the sample
2 |
3 | * [node.js](http://nodejs.org) and [F#](http://fsharp.org) must be installed in your system.
4 |
5 | * Be sure common dependencies are installed (in `samples` directory, type: `npm install`).
6 |
7 | * To compile the F# code to JS, in this directory type: `npm run build`
8 |
9 | * To start a local server and open a web with the sample, type: `npm start`
10 |
11 | > If you wan to listen for changes and recompile
12 | the F# code, you can use `npm build -- --watch`.
13 | Then you need to run `npm start` in a different
14 | terminal window.
--------------------------------------------------------------------------------
/samples/pixi/graphics/fableconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "projFile": "./graphics.fsx",
3 | "sourceMaps": true,
4 | "babelPlugins": ["transform-runtime"],
5 | "rollup": {
6 | "dest": "public/bundle.js",
7 | // PIXI will be loaded directly from a script tag
8 | "external": ["PIXI"],
9 | "globals": {
10 | "PIXI": "PIXI"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/graphics/graphics.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | - title: Graphics sample
3 | - tagline: Basic sample implemented with fable-pixi
4 | - app-style: width:800px; margin:20px auto 50px auto;
5 | - external-script: `"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/3.0.11/pixi.min.js"`
6 | - intro: This is a port from [graphics sample](http://pixijs.github.io/examples/#/demos/graphics-demo.js)
7 | *)
8 |
9 | #r "../../node_modules/fable-core/Fable.Core.dll"
10 | #load "../../node_modules/fable-import-pixi/Fable.Import.Pixi.fs"
11 |
12 | open System
13 | open Fable.Core
14 | open Fable.Core.JsInterop
15 | open Fable.Import.PIXI
16 | open Fable.Import.Browser
17 | open Fable.Import.JS
18 |
19 | importAll "core-js"
20 |
21 | let options = [
22 | Antialias true
23 | ]
24 |
25 | let renderer =
26 | Globals.autoDetectRenderer(800., 600., options)
27 | |> unbox
28 |
29 | let gameDiv = document.getElementById("game")
30 | gameDiv.appendChild( renderer.view )
31 |
32 | // create the root of the scene graph
33 | let stage = Container()
34 |
35 | let graphics = Graphics()
36 |
37 | // set a fill and line style
38 | graphics.beginFill(float 0xFF3300)
39 | graphics.lineStyle(4., float 0xffd900, 1.)
40 |
41 | // draw a shape
42 | graphics.moveTo(50.,50.)
43 | graphics.lineTo(250., 50.)
44 | graphics.lineTo(100., 100.)
45 | graphics.lineTo(50., 50.)
46 | graphics.endFill()
47 |
48 | // set a fill and line style again
49 | graphics.lineStyle(10., float 0xFF0000, 0.8)
50 | graphics.beginFill(float 0xFF700B, 1.)
51 |
52 | // draw a second shape
53 | graphics.moveTo(210.,300.)
54 | graphics.lineTo(450.,320.)
55 | graphics.lineTo(570.,350.)
56 | graphics.quadraticCurveTo(600., 0., 480.,100.)
57 | graphics.lineTo(330.,120.)
58 | graphics.lineTo(410.,200.)
59 | graphics.lineTo(210.,300.)
60 | graphics.endFill()
61 |
62 | // draw a rectangle
63 | graphics.lineStyle(2., float 0x0000FF, 1.)
64 | graphics.drawRect(50., 250., 100., 100.)
65 |
66 | // draw a circle
67 | graphics.lineStyle(0.)
68 | graphics.beginFill(float 0xFFFF0B, 0.5)
69 | graphics.drawCircle(470., 200.,100.)
70 | graphics.endFill()
71 |
72 | graphics.lineStyle(20., float 0x33FF00)
73 | graphics.moveTo(30.,30.)
74 | graphics.lineTo(600., 300.)
75 |
76 | stage.addChild(graphics)
77 |
78 | // let's create a moving shape
79 | let thing = Graphics()
80 | stage.addChild(thing)
81 | thing.position.x <- 620. / 2.
82 | thing.position.y <- 380. / 2.
83 |
84 | let onClick() =
85 | graphics.lineStyle(
86 | Math.random() * 30., Math.random() * float 0xFFFFFF, 1.) |>ignore
87 | graphics.moveTo(
88 | Math.random() * 620., Math.random() * 380.) |>ignore
89 | graphics.bezierCurveTo(
90 | Math.random() * 620., Math.random() * 380.,
91 | Math.random() * 620., Math.random() * 380.,
92 | Math.random() * 620., Math.random() * 380.) |> ignore
93 |
94 | stage.interactive <- true
95 | // Just click on the stage to draw random lines
96 | stage.on_click(fun _ -> onClick())
97 | stage.on_tap(fun _ -> onClick())
98 |
99 | let animate =
100 | let mutable count = 0.
101 | let rec animate (dt:float) =
102 | thing.clear() |> ignore
103 | count <- count + 0.1
104 | thing.clear() |> ignore
105 | thing.lineStyle(10., float 0xff0000, 1.) |> ignore
106 | thing.beginFill(float 0xffFF00, 0.5) |> ignore
107 | thing.moveTo(
108 | -120. + Math.sin(count) * 20.,
109 | -100. + Math.cos(count)* 20.) |> ignore
110 | thing.lineTo(
111 | 120. + Math.cos(count) * 20.,
112 | -100. + Math.sin(count)* 20.) |> ignore
113 | thing.lineTo(
114 | 120. + Math.sin(count) * 20.,
115 | 100. + Math.cos(count)* 20.) |> ignore
116 | thing.lineTo(
117 | -120. + Math.cos(count)* 20.,
118 | 100. + Math.sin(count)* 20.) |> ignore
119 | thing.lineTo(
120 | -120. + Math.sin(count) * 20.,
121 | -100. + Math.cos(count)* 20.) |> ignore
122 | thing.rotation <- count * 0.1
123 | window.requestAnimationFrame(FrameRequestCallback animate) |> ignore
124 | renderer.render(stage)
125 | animate
126 |
127 | // start animating
128 | animate 0.
129 |
--------------------------------------------------------------------------------
/samples/pixi/graphics/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Herebris - IMGUI
6 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/samples/pixi/graphics/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "fable-pixi-samples",
4 | "version": "0.0.1",
5 | "description": "F# port of pixi.js official samples",
6 | "main": "index.js",
7 | "scripts": {
8 | "build": "node ../../node_modules/fable-compiler",
9 | "start": "node ../../server"
10 | },
11 | "author": "François Nicaise",
12 | "license": "MIT"
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/masking/README.md:
--------------------------------------------------------------------------------
1 | # To build and run the sample
2 |
3 | * [node.js](http://nodejs.org) and [F#](http://fsharp.org) must be installed in your system.
4 |
5 | * Be sure common dependencies are installed (in `samples` directory, type: `npm install`).
6 |
7 | * To compile the F# code to JS, in this directory type: `npm run build`
8 |
9 | * To start a local server and open a web with the sample, type: `npm start`
10 |
11 | > If you wan to listen for changes and recompile
12 | the F# code, you can use `npm build -- --watch`.
13 | Then you need to run `npm start` in a different
14 | terminal window.
--------------------------------------------------------------------------------
/samples/pixi/masking/fableconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "projFile": "./masking.fsx",
3 | "sourceMaps": true,
4 | "babelPlugins": ["transform-runtime"],
5 | "rollup": {
6 | "dest": "public/bundle.js",
7 | // PIXI will be loaded directly from a script tag
8 | "external": ["PIXI"],
9 | "globals": {
10 | "PIXI": "PIXI"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/masking/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Herebris - IMGUI
6 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/samples/pixi/masking/masking.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | - title: Masking sample
3 | - tagline: Basic sample implemented with fable-pixi
4 | - app-style: width:800px; margin:20px auto 50px auto;
5 | - external-script: `"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/3.0.11/pixi.min.js"`
6 | - intro: This is a port from [Masking sample](http://pixijs.github.io/examples/#/demos/masking.js)
7 | *)
8 |
9 | #r "../../node_modules/fable-core/Fable.Core.dll"
10 | #load "../../node_modules/fable-import-pixi/Fable.Import.Pixi.fs"
11 |
12 | open System
13 | open Fable.Core
14 | open Fable.Core.JsInterop
15 | open Fable.Import
16 | open Fable.Import.PIXI
17 | open Fable.Import.Browser
18 | open Fable.Import.JS
19 |
20 | importAll "core-js"
21 |
22 | let renderer = WebGLRenderer( 800., 600. )
23 |
24 | let gameDiv = document.getElementById("game")
25 | gameDiv.appendChild( renderer.view )
26 |
27 | // create the root of the scene graph
28 | let stage = Container()
29 | stage.interactive <- true
30 |
31 | let bg = Sprite.fromImage("./public/assets/BGrotate.jpg")
32 |
33 | bg.anchor.x <- 0.5
34 | bg.anchor.y <- 0.5
35 |
36 | bg.position.x <- renderer.width / 2.
37 | bg.position.y <- renderer.height / 2.
38 |
39 | stage.addChild(bg)
40 |
41 | let container = Container()
42 | container.position.x <- renderer.width / 2.
43 | container.position.y <- renderer.height / 2.
44 |
45 | // add a bunch of sprites
46 | let bgFront = Sprite.fromImage("./public/assets/SceneRotate.jpg")
47 | bgFront.anchor.x <- 0.5
48 | bgFront.anchor.y <- 0.5
49 |
50 | container.addChild(bgFront)
51 |
52 | let light2 = Sprite.fromImage("./public/assets/LightRotate2.png")
53 | light2.anchor.x <- 0.5
54 | light2.anchor.y <- 0.5
55 | container.addChild(light2)
56 |
57 | let light1 = Sprite.fromImage("./public/assets/LightRotate1.png")
58 | light1.anchor.x <- 0.5
59 | light1.anchor.y <- 0.5
60 | container.addChild(light1)
61 |
62 | let panda = Sprite.fromImage("./public/assets/panda.png")
63 | panda.anchor.x <- 0.5
64 | panda.anchor.y <- 0.5
65 |
66 | container.addChild(panda)
67 |
68 | stage.addChild(container)
69 |
70 | // let's create a moving shape
71 | let thing = Graphics()
72 | stage.addChild(thing)
73 | thing.position.x <- renderer.width / 2.
74 | thing.position.y <- renderer.height / 2.
75 | thing.lineStyle(0.)
76 |
77 | container.mask <- Some(U2.Case1 thing)
78 |
79 | let onClick() =
80 | match container.mask with
81 | | None -> container.mask <- Some(U2.Case1 thing)
82 | | Some mask -> container.mask <- None
83 |
84 | stage.on_click(fun _ -> onClick())
85 | stage.on_tap(fun _ -> onClick())
86 |
87 | let style = [
88 | Font "bold 12pt Arial"
89 | Fill (U2.Case1 "white")
90 | ]
91 | let help = PIXI.Text("Click to turn masking on / off.", style)
92 | help.position.y <- renderer.height - 26.
93 | help.position.x <- 10.
94 | stage.addChild(help)
95 |
96 | let animate =
97 | let mutable count = 0.
98 | let rec animate (dt:float) =
99 | bg.rotation <- bg.rotation + 0.01
100 | bgFront.rotation <- bgFront.rotation - 0.01
101 |
102 | light1.rotation <- light1.rotation + 0.02
103 | light2.rotation <- light2.rotation + 0.01
104 |
105 | panda.scale.x <- 1. + Math.sin(count) * 0.04
106 | panda.scale.y <- 1. + Math.cos(count) * 0.04
107 |
108 | count <- count + 0.1
109 |
110 | thing.clear() |> ignore
111 |
112 | (*
113 | Version specifics:
114 | v3: clipping (you should see some edges blinking)
115 | v4: no clipping
116 | *)
117 | thing.beginFill(float 0x8bc5ff, 0.4) |> ignore
118 | let myangle = 20.
119 | let mysin = Math.sin(count) * myangle
120 | let mycos = Math.cos(count) * myangle
121 | thing.moveTo(-120. + mysin, -100. + mycos) |> ignore
122 | thing.lineTo(-320. + mycos, 100. + mysin) |> ignore
123 | thing.lineTo(120. + mycos, -100. + mysin) |> ignore
124 | thing.lineTo(120. + mysin, 100. + mycos) |> ignore
125 | thing.lineTo(-120. + mycos, 100. + mysin) |> ignore
126 | thing.lineTo(-120. + mysin, -300. + mycos) |> ignore
127 | thing.lineTo(-320. + mysin, -100. + mycos) |> ignore
128 | thing.rotation <- count * 0.1
129 |
130 | window.requestAnimationFrame(FrameRequestCallback animate) |> ignore
131 | renderer.render(stage)
132 |
133 | animate // Return `animate` function with `count` trapped in a closure
134 |
135 | // start animating
136 | animate 0.
137 |
--------------------------------------------------------------------------------
/samples/pixi/masking/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "fable-pixi-samples",
4 | "version": "0.0.1",
5 | "description": "F# port of pixi.js official samples",
6 | "main": "index.js",
7 | "scripts": {
8 | "build": "node ../../node_modules/fable-compiler",
9 | "start": "node ../../server"
10 | },
11 | "author": "François Nicaise",
12 | "license": "MIT"
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/masking/public/assets/BGrotate.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/masking/public/assets/BGrotate.jpg
--------------------------------------------------------------------------------
/samples/pixi/masking/public/assets/LightRotate1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/masking/public/assets/LightRotate1.png
--------------------------------------------------------------------------------
/samples/pixi/masking/public/assets/LightRotate2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/masking/public/assets/LightRotate2.png
--------------------------------------------------------------------------------
/samples/pixi/masking/public/assets/SceneRotate.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/masking/public/assets/SceneRotate.jpg
--------------------------------------------------------------------------------
/samples/pixi/masking/public/assets/panda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/masking/public/assets/panda.png
--------------------------------------------------------------------------------
/samples/pixi/movieclip/README.md:
--------------------------------------------------------------------------------
1 | # To build and run the sample
2 |
3 | * [node.js](http://nodejs.org) and [F#](http://fsharp.org) must be installed in your system.
4 |
5 | * Be sure common dependencies are installed (in `samples` directory, type: `npm install`).
6 |
7 | * To compile the F# code to JS, in this directory type: `npm run build`
8 |
9 | * To start a local server and open a web with the sample, type: `npm start`
10 |
11 | > If you wan to listen for changes and recompile
12 | the F# code, you can use `npm build -- --watch`.
13 | Then you need to run `npm start` in a different
14 | terminal window.
--------------------------------------------------------------------------------
/samples/pixi/movieclip/fableconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "projFile": "./movieclip.fsx",
3 | "sourceMaps": true,
4 | "babelPlugins": ["transform-runtime"],
5 | "rollup": {
6 | "dest": "public/bundle.js",
7 | // PIXI will be loaded directly from a script tag
8 | "external": ["PIXI"],
9 | "globals": {
10 | "PIXI": "PIXI"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/movieclip/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Herebris - IMGUI
6 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/samples/pixi/movieclip/movieclip.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | - title: MovieClip sample
3 | - tagline: Basic sample implemented with fable-pixi
4 | - app-style: width:800px; margin:20px auto 50px auto;
5 | - external-script: `"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/3.0.11/pixi.min.js"`
6 | - intro: This is a port from [MovieClip sample](http://pixijs.github.io/examples/#/demos/movieclip-demo.js)
7 | *)
8 |
9 | #r "../../node_modules/fable-core/Fable.Core.dll"
10 | #load "../../node_modules/fable-import-pixi/Fable.Import.Pixi.fs"
11 |
12 | open System
13 | open Fable.Core
14 | open Fable.Core.JsInterop
15 | open Fable.Import.PIXI
16 | open Fable.Import.Browser
17 | open Fable.Import.JS
18 |
19 | importAll "core-js"
20 |
21 | let renderer = WebGLRenderer( 800., 600. )
22 |
23 | let gameDiv = document.getElementById("game")
24 | gameDiv.appendChild( renderer.view )
25 |
26 | // create the root of the scene graph
27 | let stage = Container()
28 |
29 | let rec animate (dt:float) =
30 | window.requestAnimationFrame(FrameRequestCallback animate) |> ignore
31 | // render the container
32 | renderer.render(stage)
33 |
34 | let onLoad resources =
35 | // create an array to store the textures
36 | let explosionTextures = ResizeArray()
37 | for i in 0..25 do
38 | Texture.fromFrame(sprintf "Explosion_Sequence_A %i.png" (i+1))
39 | |> explosionTextures.Add
40 | for i in 0..49 do
41 | let explosion = extras.MovieClip(explosionTextures)
42 | explosion.position.x <- Math.random() * 800.
43 | explosion.position.y <- Math.random() * 600.
44 | explosion.anchor.x <- 0.5
45 | explosion.anchor.y <- 0.5
46 | explosion.rotation <- Math.random() * Math.PI
47 | explosion.scale.set(0.75 + Math.random() * 0.5)
48 | explosion.gotoAndPlay(Math.random() * 27.)
49 | stage.addChild(explosion) |> ignore
50 | animate 0.
51 |
52 | Globals.loader
53 | .add("spritesheet","./public/assets/mc.json")
54 | .load(Func<_,_,_>(fun _ resources ->
55 | onLoad(resources)))
56 |
--------------------------------------------------------------------------------
/samples/pixi/movieclip/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "fable-pixi-samples",
4 | "version": "0.0.1",
5 | "description": "F# port of pixi.js official samples",
6 | "main": "index.js",
7 | "scripts": {
8 | "build": "node ../../node_modules/fable-compiler",
9 | "start": "node ../../server"
10 | },
11 | "author": "François Nicaise",
12 | "license": "MIT"
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/movieclip/public/assets/mc.json:
--------------------------------------------------------------------------------
1 | {"frames": {
2 |
3 | "Explosion_Sequence_A 1.png":
4 | {
5 | "frame": {"x":244,"y":1454,"w":240,"h":240},
6 | "rotated": false,
7 | "trimmed": false,
8 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
9 | "sourceSize": {"w":240,"h":240}
10 | },
11 | "Explosion_Sequence_A 10.png":
12 | {
13 | "frame": {"x":244,"y":970,"w":240,"h":240},
14 | "rotated": false,
15 | "trimmed": false,
16 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
17 | "sourceSize": {"w":240,"h":240}
18 | },
19 | "Explosion_Sequence_A 11.png":
20 | {
21 | "frame": {"x":2,"y":970,"w":240,"h":240},
22 | "rotated": false,
23 | "trimmed": false,
24 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
25 | "sourceSize": {"w":240,"h":240}
26 | },
27 | "Explosion_Sequence_A 12.png":
28 | {
29 | "frame": {"x":728,"y":728,"w":240,"h":240},
30 | "rotated": false,
31 | "trimmed": false,
32 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
33 | "sourceSize": {"w":240,"h":240}
34 | },
35 | "Explosion_Sequence_A 13.png":
36 | {
37 | "frame": {"x":486,"y":728,"w":240,"h":240},
38 | "rotated": false,
39 | "trimmed": false,
40 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
41 | "sourceSize": {"w":240,"h":240}
42 | },
43 | "Explosion_Sequence_A 14.png":
44 | {
45 | "frame": {"x":244,"y":728,"w":240,"h":240},
46 | "rotated": false,
47 | "trimmed": false,
48 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
49 | "sourceSize": {"w":240,"h":240}
50 | },
51 | "Explosion_Sequence_A 15.png":
52 | {
53 | "frame": {"x":2,"y":728,"w":240,"h":240},
54 | "rotated": false,
55 | "trimmed": false,
56 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
57 | "sourceSize": {"w":240,"h":240}
58 | },
59 | "Explosion_Sequence_A 16.png":
60 | {
61 | "frame": {"x":728,"y":486,"w":240,"h":240},
62 | "rotated": false,
63 | "trimmed": false,
64 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
65 | "sourceSize": {"w":240,"h":240}
66 | },
67 | "Explosion_Sequence_A 17.png":
68 | {
69 | "frame": {"x":486,"y":486,"w":240,"h":240},
70 | "rotated": false,
71 | "trimmed": false,
72 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
73 | "sourceSize": {"w":240,"h":240}
74 | },
75 | "Explosion_Sequence_A 18.png":
76 | {
77 | "frame": {"x":244,"y":486,"w":240,"h":240},
78 | "rotated": false,
79 | "trimmed": false,
80 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
81 | "sourceSize": {"w":240,"h":240}
82 | },
83 | "Explosion_Sequence_A 19.png":
84 | {
85 | "frame": {"x":2,"y":486,"w":240,"h":240},
86 | "rotated": false,
87 | "trimmed": false,
88 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
89 | "sourceSize": {"w":240,"h":240}
90 | },
91 | "Explosion_Sequence_A 2.png":
92 | {
93 | "frame": {"x":728,"y":1212,"w":240,"h":240},
94 | "rotated": false,
95 | "trimmed": false,
96 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
97 | "sourceSize": {"w":240,"h":240}
98 | },
99 | "Explosion_Sequence_A 20.png":
100 | {
101 | "frame": {"x":728,"y":244,"w":240,"h":240},
102 | "rotated": false,
103 | "trimmed": false,
104 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
105 | "sourceSize": {"w":240,"h":240}
106 | },
107 | "Explosion_Sequence_A 21.png":
108 | {
109 | "frame": {"x":486,"y":244,"w":240,"h":240},
110 | "rotated": false,
111 | "trimmed": false,
112 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
113 | "sourceSize": {"w":240,"h":240}
114 | },
115 | "Explosion_Sequence_A 22.png":
116 | {
117 | "frame": {"x":244,"y":244,"w":240,"h":240},
118 | "rotated": false,
119 | "trimmed": false,
120 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
121 | "sourceSize": {"w":240,"h":240}
122 | },
123 | "Explosion_Sequence_A 23.png":
124 | {
125 | "frame": {"x":2,"y":244,"w":240,"h":240},
126 | "rotated": false,
127 | "trimmed": false,
128 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
129 | "sourceSize": {"w":240,"h":240}
130 | },
131 | "Explosion_Sequence_A 24.png":
132 | {
133 | "frame": {"x":728,"y":2,"w":240,"h":240},
134 | "rotated": false,
135 | "trimmed": false,
136 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
137 | "sourceSize": {"w":240,"h":240}
138 | },
139 | "Explosion_Sequence_A 25.png":
140 | {
141 | "frame": {"x":486,"y":2,"w":240,"h":240},
142 | "rotated": false,
143 | "trimmed": false,
144 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
145 | "sourceSize": {"w":240,"h":240}
146 | },
147 | "Explosion_Sequence_A 26.png":
148 | {
149 | "frame": {"x":244,"y":2,"w":240,"h":240},
150 | "rotated": false,
151 | "trimmed": false,
152 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
153 | "sourceSize": {"w":240,"h":240}
154 | },
155 | "Explosion_Sequence_A 27.png":
156 | {
157 | "frame": {"x":2,"y":2,"w":240,"h":240},
158 | "rotated": false,
159 | "trimmed": false,
160 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
161 | "sourceSize": {"w":240,"h":240}
162 | },
163 | "Explosion_Sequence_A 3.png":
164 | {
165 | "frame": {"x":486,"y":1212,"w":240,"h":240},
166 | "rotated": false,
167 | "trimmed": false,
168 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
169 | "sourceSize": {"w":240,"h":240}
170 | },
171 | "Explosion_Sequence_A 4.png":
172 | {
173 | "frame": {"x":244,"y":1212,"w":240,"h":240},
174 | "rotated": false,
175 | "trimmed": false,
176 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
177 | "sourceSize": {"w":240,"h":240}
178 | },
179 | "Explosion_Sequence_A 5.png":
180 | {
181 | "frame": {"x":2,"y":1696,"w":240,"h":240},
182 | "rotated": false,
183 | "trimmed": false,
184 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
185 | "sourceSize": {"w":240,"h":240}
186 | },
187 | "Explosion_Sequence_A 6.png":
188 | {
189 | "frame": {"x":2,"y":1454,"w":240,"h":240},
190 | "rotated": false,
191 | "trimmed": false,
192 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
193 | "sourceSize": {"w":240,"h":240}
194 | },
195 | "Explosion_Sequence_A 7.png":
196 | {
197 | "frame": {"x":2,"y":1212,"w":240,"h":240},
198 | "rotated": false,
199 | "trimmed": false,
200 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
201 | "sourceSize": {"w":240,"h":240}
202 | },
203 | "Explosion_Sequence_A 8.png":
204 | {
205 | "frame": {"x":728,"y":970,"w":240,"h":240},
206 | "rotated": false,
207 | "trimmed": false,
208 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
209 | "sourceSize": {"w":240,"h":240}
210 | },
211 | "Explosion_Sequence_A 9.png":
212 | {
213 | "frame": {"x":486,"y":970,"w":240,"h":240},
214 | "rotated": false,
215 | "trimmed": false,
216 | "spriteSourceSize": {"x":0,"y":0,"w":240,"h":240},
217 | "sourceSize": {"w":240,"h":240}
218 | }},
219 | "meta": {
220 | "app": "http://www.texturepacker.com",
221 | "version": "1.0",
222 | "image": "mc.png",
223 | "format": "RGBA8888",
224 | "size": {"w":1024,"h":2048},
225 | "scale": "1",
226 | "smartupdate": "$TexturePacker:SmartUpdate:17e4a2d92ff3e27832c3f4938cec7c85$"
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/samples/pixi/movieclip/public/assets/mc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/movieclip/public/assets/mc.png
--------------------------------------------------------------------------------
/samples/pixi/particle-container/README.md:
--------------------------------------------------------------------------------
1 | # To build and run the sample
2 |
3 | * [node.js](http://nodejs.org) and [F#](http://fsharp.org) must be installed in your system.
4 |
5 | * Be sure common dependencies are installed (in `samples` directory, type: `npm install`).
6 |
7 | * To compile the F# code to JS, in this directory type: `npm run build`
8 |
9 | * To start a local server and open a web with the sample, type: `npm start`
10 |
11 | > If you wan to listen for changes and recompile
12 | the F# code, you can use `npm build -- --watch`.
13 | Then you need to run `npm start` in a different
14 | terminal window.
--------------------------------------------------------------------------------
/samples/pixi/particle-container/fableconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "projFile": "./particle-container.fsx",
3 | "sourceMaps": true,
4 | "babelPlugins": ["transform-runtime"],
5 | "rollup": {
6 | "dest": "public/bundle.js",
7 | // PIXI will be loaded directly from a script tag
8 | "external": ["PIXI"],
9 | "globals": {
10 | "PIXI": "PIXI"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/particle-container/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Herebris - IMGUI
6 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/samples/pixi/particle-container/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "fable-pixi-samples",
4 | "version": "0.0.1",
5 | "description": "F# port of pixi.js official samples",
6 | "main": "index.js",
7 | "scripts": {
8 | "build": "node ../../node_modules/fable-compiler",
9 | "start": "node ../../server"
10 | },
11 | "author": "François Nicaise",
12 | "license": "MIT"
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/particle-container/particle-container.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | - title: Particle Container sample
3 | - tagline: Basic sample implemented with fable-pixi
4 | - app-style: width:800px; margin:20px auto 50px auto;
5 | - external-script: `"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/3.0.11/pixi.min.js"`
6 | - intro: This is a port from [Particle Container sample](http://pixijs.github.io/examples/#/demos/batch-v3.js)
7 | *)
8 |
9 | #r "../../node_modules/fable-core/Fable.Core.dll"
10 | #load "../../node_modules/fable-import-pixi/Fable.Import.Pixi.fs"
11 |
12 | open System
13 | open Fable.Core
14 | open Fable.Core.JsInterop
15 | open Fable.Import.PIXI
16 | open Fable.Import.Browser
17 | open Fable.Import.JS
18 |
19 | importAll "core-js"
20 |
21 | let isWebGL, renderer =
22 | match Globals.autoDetectRenderer(800., 600.) with
23 | | U2.Case1 webgl -> true, webgl :> SystemRenderer
24 | | U2.Case2 canvas -> false, canvas :> SystemRenderer
25 |
26 | let gameDiv = document.getElementById("game")
27 | gameDiv.appendChild( renderer.view )
28 |
29 | // create the root of the scene graph
30 | let stage = Container()
31 |
32 | type PCP = ParticleContainerProperties
33 | let options = [
34 | PCP.Scale true
35 | PCP.Position true
36 | PCP.Rotation true
37 | PCP.Uvs true
38 | PCP.Alpha true
39 | ]
40 | let sprites = ParticleContainer(10000., options)
41 | stage.addChild(sprites)
42 |
43 | // create an array to store a reference to the dudes
44 | let maggots = ResizeArray()
45 | let totalSprites = if isWebGL then 10000 else 100
46 |
47 | for i in 0..totalSprites-1 do
48 | // create a new Sprite that uses the image name
49 | // we just generated as its source
50 | let dude = Sprite.fromImage("./public/assets/tinyMaggot.png")
51 |
52 | // Exists in code but is not used in actual demo
53 | // http://pixijs.github.io/examples/#/demos/batch-v3.js
54 | //dude.tint <- Math.random() * (float 0xE8D4CD)
55 |
56 | dude.anchor.set(0.5)
57 |
58 | // set a random scale for the dude
59 | dude.scale.set(0.8 + Math.random() * 0.3)
60 |
61 | // finally let"s set the dude to be at a random position...
62 | dude.position.x <- Math.floor(Math.random() * renderer.width)
63 | dude.position.y <- Math.floor(Math.random() * renderer.height)
64 |
65 | // Exists in code but is not used in actual demo
66 | // http://pixijs.github.io/examples/#/demos/batch-v3.js
67 | //dude.tint <- Math.random() * (float 0x808080)
68 |
69 | // create some extra properties that will control movement
70 | // create a random direction in radians. This is a number
71 | // between 0 and PI*2 which is the equivalent of 0 - 360 degrees
72 | dude?direction <- Math.random() * Math.PI * 2.
73 |
74 | // this number will be used to modify the direction of the dude over time
75 | dude?turningSpeed <- Math.random() - 0.8
76 |
77 | // create a random speed between 0 - 2, and these maggots are slooww
78 | dude?speed <- 2. + Math.random() * 2. * 0.2
79 |
80 | dude?offset <- Math.random() * 100.
81 |
82 | // push the dude into the maggots so it can be easily accessed later
83 | maggots.Add(dude)
84 |
85 | stage.addChild(dude) |> ignore
86 |
87 |
88 | // create a bounding box box for the little dudes
89 | let dudeBoundsPadding = 100.
90 |
91 | let dudeBounds = Rectangle(-dudeBoundsPadding,
92 | -dudeBoundsPadding,
93 | renderer.width + dudeBoundsPadding * 2.,
94 | renderer.height + dudeBoundsPadding * 2.)
95 |
96 | let animate =
97 | let mutable tick = 0.
98 | let rec animate (dt:float) =
99 | // iterate through the dudes and update the positions
100 | let dc = maggots.Count - 1
101 | for i in 0..dc do
102 | let dude = maggots.[i]
103 | dude.scale.y <-
104 | 0.95 + Math.sin(tick + unbox dude?offset) * 0.05
105 |
106 | dude?direction <-
107 | (unbox dude?direction) + (unbox dude?turningSpeed) * 0.01
108 |
109 | dude.position.x <-
110 | dude.position.x + Math.sin(unbox dude?direction)
111 | * (unbox dude?speed) * dude.scale.y
112 |
113 | dude.position.y <-
114 | dude.position.y + Math.cos(unbox dude?direction)
115 | * (unbox dude?speed) * dude.scale.y
116 |
117 | dude.rotation <-
118 | -(unbox dude?direction) - Math.PI
119 |
120 | // wrap the dudes by testing their bounds...
121 | if (dude.position.x < dudeBounds.x)
122 | then dude.position.x <- dude.position.x + dudeBounds.width
123 | elif (dude.position.x > dudeBounds.x + dudeBounds.width)
124 | then dude.position.x <- dude.position.x - dudeBounds.width
125 |
126 | if (dude.position.y < dudeBounds.y)
127 | then dude.position.y <- dude.position.y + dudeBounds.height
128 | elif (dude.position.y > dudeBounds.y + dudeBounds.height)
129 | then dude.position.y <- dude.position.y - dudeBounds.height
130 |
131 | // increment the ticker
132 | tick <- tick + 0.1
133 | window.requestAnimationFrame(FrameRequestCallback animate) |> ignore
134 | renderer.render(stage)
135 |
136 | animate // Return `animate` function with `tick` trapped in a closure
137 |
138 | // start animating
139 | animate 0.
140 |
--------------------------------------------------------------------------------
/samples/pixi/particle-container/public/assets/tinyMaggot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/particle-container/public/assets/tinyMaggot.png
--------------------------------------------------------------------------------
/samples/pixi/render-texture/README.md:
--------------------------------------------------------------------------------
1 | # To build and run the sample
2 |
3 | * [node.js](http://nodejs.org) and [F#](http://fsharp.org) must be installed in your system.
4 |
5 | * Be sure common dependencies are installed (in `samples` directory, type: `npm install`).
6 |
7 | * To compile the F# code to JS, in this directory type: `npm run build`
8 |
9 | * To start a local server and open a web with the sample, type: `npm start`
10 |
11 | > If you wan to listen for changes and recompile
12 | the F# code, you can use `npm build -- --watch`.
13 | Then you need to run `npm start` in a different
14 | terminal window.
--------------------------------------------------------------------------------
/samples/pixi/render-texture/fableconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "projFile": "./render-texture.fsx",
3 | "sourceMaps": true,
4 | "babelPlugins": ["transform-runtime"],
5 | "rollup": {
6 | "dest": "public/bundle.js",
7 | // PIXI will be loaded directly from a script tag
8 | "external": ["PIXI"],
9 | "globals": {
10 | "PIXI": "PIXI"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/render-texture/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Herebris - IMGUI
6 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/samples/pixi/render-texture/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "fable-pixi-samples",
4 | "version": "0.0.1",
5 | "description": "F# port of pixi.js official samples",
6 | "main": "index.js",
7 | "scripts": {
8 | "build": "node ../../node_modules/fable-compiler",
9 | "start": "node ../../server"
10 | },
11 | "author": "François Nicaise",
12 | "license": "MIT"
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/render-texture/public/assets/spinObj_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/render-texture/public/assets/spinObj_01.png
--------------------------------------------------------------------------------
/samples/pixi/render-texture/public/assets/spinObj_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/render-texture/public/assets/spinObj_02.png
--------------------------------------------------------------------------------
/samples/pixi/render-texture/public/assets/spinObj_03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/render-texture/public/assets/spinObj_03.png
--------------------------------------------------------------------------------
/samples/pixi/render-texture/public/assets/spinObj_04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/render-texture/public/assets/spinObj_04.png
--------------------------------------------------------------------------------
/samples/pixi/render-texture/public/assets/spinObj_05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/render-texture/public/assets/spinObj_05.png
--------------------------------------------------------------------------------
/samples/pixi/render-texture/public/assets/spinObj_06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/render-texture/public/assets/spinObj_06.png
--------------------------------------------------------------------------------
/samples/pixi/render-texture/public/assets/spinObj_07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/render-texture/public/assets/spinObj_07.png
--------------------------------------------------------------------------------
/samples/pixi/render-texture/public/assets/spinObj_08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/render-texture/public/assets/spinObj_08.png
--------------------------------------------------------------------------------
/samples/pixi/render-texture/render-texture.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | - title: Render Texture sample
3 | - tagline: Basic sample implemented with fable-pixi
4 | - app-style: width:800px; margin:20px auto 50px auto;
5 | - external-script: `"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/3.0.11/pixi.min.js"`
6 | - intro: This is a port from [Render texture sample](http://pixijs.github.io/examples/#/demos/render-texture-demo.js)
7 | *)
8 |
9 | #r "../../node_modules/fable-core/Fable.Core.dll"
10 | #load "../../node_modules/fable-import-pixi/Fable.Import.Pixi.fs"
11 |
12 | open System
13 | open Fable.Core
14 | open Fable.Core.JsInterop
15 | open Fable.Import.PIXI
16 | open Fable.Import.Browser
17 | open Fable.Import.JS
18 |
19 | importAll "core-js"
20 |
21 | let renderer = WebGLRenderer( 800., 600. )
22 |
23 | let gameDiv = document.getElementById("game")
24 | gameDiv.appendChild( renderer.view )
25 |
26 | // create the root of the scene graph
27 | let stage = Container()
28 |
29 | let mutable renderTexture =
30 | RenderTexture( U2.Case2 renderer, renderer.width, renderer.height)
31 |
32 | let mutable renderTexture2 =
33 | RenderTexture( U2.Case2 renderer, renderer.width, renderer.height)
34 |
35 | // create a new sprite that uses the render texture we created above
36 | let outputSprite = Sprite(renderTexture)
37 |
38 | // align the sprite
39 | outputSprite.position.x <- 400.
40 | outputSprite.position.y <- 300.
41 | outputSprite.anchor.set(0.5)
42 |
43 | // add to stage
44 | stage.addChild(outputSprite)
45 |
46 | let stuffContainer = Container()
47 | stuffContainer.position.x <- 400.
48 | stuffContainer.position.y <- 300.
49 | stage.addChild(stuffContainer)
50 |
51 | // create an array of image ids
52 | let fruits =
53 | ResizeArray [|
54 | "./public/assets/spinObj_01.png";
55 | "./public/assets/spinObj_02.png";
56 | "./public/assets/spinObj_03.png";
57 | "./public/assets/spinObj_04.png";
58 | "./public/assets/spinObj_05.png";
59 | "./public/assets/spinObj_06.png";
60 | "./public/assets/spinObj_07.png";
61 | "./public/assets/spinObj_08.png"
62 | |]
63 |
64 | // create an array of items
65 | let items = ResizeArray()
66 |
67 | // now create some items and randomly position them in the stuff container
68 | for i in 0..19 do
69 | let item = Sprite.fromImage(fruits.[i % fruits.Count])
70 | item.position.x <- Math.random() * 400. - 200.
71 | item.position.y <- Math.random() * 400. - 200.
72 | item.anchor.set(0.5)
73 | stuffContainer.addChild(item) |> ignore
74 | items.Add(item)
75 |
76 | let animate =
77 | let mutable count = 0.
78 | let rec animate (dt:float) =
79 | window.requestAnimationFrame(FrameRequestCallback animate)
80 | |> ignore
81 |
82 | let il = items.Count - 1
83 | console.log(il)
84 | for i in 0..il do
85 | let item = items.[i]
86 | item.rotation <- item.rotation + 0.1
87 |
88 | count <- count + 0.01
89 |
90 | // swap the buffers ...
91 | let temp = renderTexture
92 | renderTexture <- renderTexture2
93 | renderTexture2 <- temp
94 |
95 | // set the new texture
96 | outputSprite.texture <- renderTexture
97 |
98 | // twist this up!
99 | stuffContainer.rotation <- stuffContainer.rotation - 0.01
100 | outputSprite.scale.set(1. + Math.sin(float count) * 0.2)
101 |
102 | // render the stage to the texture
103 | // the 'true' clears the texture before the content is rendered
104 | renderTexture2.render(displayObject=stage, clear=false)
105 |
106 | // render the container
107 | renderer.render(stage)
108 |
109 | animate // Return `animate` function with `count` trapped in a closure
110 |
111 | animate 0.
112 |
--------------------------------------------------------------------------------
/samples/pixi/text/README.md:
--------------------------------------------------------------------------------
1 | # To build and run the sample
2 |
3 | * [node.js](http://nodejs.org) and [F#](http://fsharp.org) must be installed in your system.
4 |
5 | * Be sure common dependencies are installed (in `samples` directory, type: `npm install`).
6 |
7 | * To compile the F# code to JS, in this directory type: `npm run build`
8 |
9 | * To start a local server and open a web with the sample, type: `npm start`
10 |
11 | > If you wan to listen for changes and recompile
12 | the F# code, you can use `npm build -- --watch`.
13 | Then you need to run `npm start` in a different
14 | terminal window.
--------------------------------------------------------------------------------
/samples/pixi/text/fableconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "projFile": "./text.fsx",
3 | "sourceMaps": true,
4 | "babelPlugins": ["transform-runtime"],
5 | "rollup": {
6 | "dest": "public/bundle.js",
7 | // PIXI will be loaded directly from a script tag
8 | "external": ["PIXI"],
9 | "globals": {
10 | "PIXI": "PIXI"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/text/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Herebris - IMGUI
6 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/samples/pixi/text/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "fable-pixi-samples",
4 | "version": "0.0.1",
5 | "description": "F# port of pixi.js official samples",
6 | "main": "index.js",
7 | "scripts": {
8 | "build": "node ../../node_modules/fable-compiler",
9 | "start": "node ../../server"
10 | },
11 | "author": "François Nicaise",
12 | "license": "MIT"
13 | }
14 |
--------------------------------------------------------------------------------
/samples/pixi/text/public/assets/desyrel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/text/public/assets/desyrel.png
--------------------------------------------------------------------------------
/samples/pixi/text/public/assets/textDemoBG.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fable-compiler/fable-graphics/777629763c49a7632dd7885b058e9aa21cbf28c3/samples/pixi/text/public/assets/textDemoBG.jpg
--------------------------------------------------------------------------------
/samples/pixi/text/text.fsx:
--------------------------------------------------------------------------------
1 | (**
2 | - title: Text sample
3 | - tagline: Basic sample implemented with fable-pixi
4 | - app-style: width:800px; margin:20px auto 50px auto;
5 | - external-script: `"https://cdnjs.cloudflare.com/ajax/libs/pixi.js/3.0.11/pixi.min.js"`
6 | - intro: This is a port from [text sample](http://pixijs.github.io/examples/#/demos/text-demo.js)
7 | *)
8 |
9 | #r "../../node_modules/fable-core/Fable.Core.dll"
10 | #load "../../node_modules/fable-import-pixi/Fable.Import.Pixi.fs"
11 |
12 | open System
13 | open Fable.Core
14 | open Fable.Core.JsInterop
15 | open Fable.Import
16 | open Fable.Import.PIXI
17 | open Fable.Import.Browser
18 | open Fable.Import.JS
19 |
20 | importAll "core-js"
21 |
22 | let renderer =
23 | Globals.autoDetectRenderer( 620., 400. )
24 | |> unbox
25 |
26 | renderer.view.style.display <- "block"
27 | renderer.view.style.margin <- "0 auto"
28 |
29 | let gameDiv = document.getElementById("game")
30 | gameDiv.appendChild( renderer.view )
31 |
32 | // create the root of the scene graph
33 | let stage = Container()
34 |
35 | let onAssetsLoad resources =
36 | let fontStyle = [
37 | extras.Font (U2.Case1 "35px Desyrel")
38 | extras.Align "right"
39 | ]
40 | let bitmapFontText =
41 | extras.BitmapText("bitmap fonts are\n now supported", fontStyle)
42 | bitmapFontText.position.x <- 600. - bitmapFontText.textWidth
43 | bitmapFontText.position.y <- 20.
44 | stage.addChild(bitmapFontText)
45 | |> ignore
46 |
47 | // add a shiny background...
48 | let background = Sprite.fromImage("./public/assets/textDemoBG.jpg")
49 | stage.addChild( background)
50 |
51 | // create some white text using the Snippet webfont
52 | let style = [
53 | TextStyle.Font "35px Arial"
54 | TextStyle.Fill (U2.Case1 "white")
55 | TextStyle.Align "left"
56 | ]
57 | let textSample = PIXI.Text("Pixi.js can have\n multiline text!", style)
58 | textSample.position.set(20.)
59 |
60 | // create a text object with a nice stroke
61 | let funStyle = [
62 | TextStyle.Font "bold 60px Arial"
63 | TextStyle.Fill (U2.Case1 "#cc00ff")
64 | TextStyle.Align "center"
65 | TextStyle.Stroke (U2.Case1 "#FFFFFF")
66 | TextStyle.StrokeThickness 6.
67 | ]
68 | let spinningText = PIXI.Text("I\'m fun!", funStyle)
69 | spinningText.anchor.set(0.5)
70 | spinningText.position.x <- 310.
71 | spinningText.position.y <- 200.
72 |
73 | let countingStyle = [
74 | TextStyle.Font "bold italic 60px Arial"
75 | TextStyle.Fill (U2.Case1 "#3e1707")
76 | TextStyle.Align "center"
77 | TextStyle.Stroke (U2.Case1 "#a4410e")
78 | TextStyle.StrokeThickness 7.
79 | ]
80 | let countingText = PIXI.Text("COUNT 4EVAR: 0", countingStyle)
81 | countingText.position.x <- 310.
82 | countingText.position.y <- 320.
83 | countingText.anchor.x <- 0.5
84 |
85 | stage.addChild(textSample)
86 | stage.addChild(spinningText)
87 | stage.addChild(countingText)
88 |
89 | Globals.loader
90 | .add("desyrel","./public/assets/desyrel.xml")
91 | .load(Func<_,_,_>(fun _ resources ->
92 | onAssetsLoad(resources)))
93 |
94 | let animate =
95 | let mutable count = 0.
96 | let rec animate (dt:float) =
97 | // render the container
98 | renderer.render(stage)
99 | count <- count + 0.5
100 | // update the text with a new string
101 | countingText.text <- sprintf "COUNT 4EVAR: %.0f" (Math.floor(count))
102 | // let's spin the spinning text
103 | spinningText.rotation <- spinningText.rotation + 0.03
104 | window.requestAnimationFrame(FrameRequestCallback animate) |> ignore
105 | animate
106 |
107 | // start animating
108 | animate 0.
109 |
--------------------------------------------------------------------------------
/samples/server/fableconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "module": "commonjs",
3 | "projFile": "index.fsx"
4 | }
--------------------------------------------------------------------------------
/samples/server/index.fsx:
--------------------------------------------------------------------------------
1 | #r "../node_modules/fable-core/Fable.Core.dll"
2 | open System
3 | open Fable.Core
4 | open Fable.Core.JsInterop
5 | open Fable.Import
6 | open Fable.Import.Node
7 |
8 | let finalhandler = importDefault "finalhandler"
9 | let serveStatic = importDefault "serve-static"
10 | let opener = importDefault "open"
11 |
12 | let port =
13 | match ``process``.argv with
14 | | args when args.Count >= 3 -> int args.[2]
15 | | _ -> 8080
16 |
17 | let samplesPath = path.resolve("../..")
18 | let relPath = path.relative(samplesPath, ".")
19 |
20 | let server =
21 | let serve = serveStatic$(samplesPath)
22 | let server =
23 | http.createServer(Func<_,_,_>(fun req res ->
24 | let isDone = finalhandler$(req, res)
25 | serve$(req, res, isDone)
26 | |> ignore))
27 | server.listen(port)
28 |
29 | opener$(sprintf "http://localhost:%i/%s" port relPath)
30 |
--------------------------------------------------------------------------------
/samples/server/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.server = exports.relPath = exports.samplesPath = exports.port = exports.opener = exports.serveStatic = exports.finalhandler = undefined;
7 |
8 | var _finalhandler = require("finalhandler");
9 |
10 | var _finalhandler2 = _interopRequireDefault(_finalhandler);
11 |
12 | var _serveStatic = require("serve-static");
13 |
14 | var _serveStatic2 = _interopRequireDefault(_serveStatic);
15 |
16 | var _open = require("open");
17 |
18 | var _open2 = _interopRequireDefault(_open);
19 |
20 | var _path = require("path");
21 |
22 | var path = _interopRequireWildcard(_path);
23 |
24 | var _http = require("http");
25 |
26 | var http = _interopRequireWildcard(_http);
27 |
28 | var _fableCore = require("fable-core");
29 |
30 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
31 |
32 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33 |
34 | var finalhandler = exports.finalhandler = _finalhandler2.default;
35 | var serveStatic = exports.serveStatic = _serveStatic2.default;
36 | var opener = exports.opener = _open2.default;
37 |
38 | var port = exports.port = function () {
39 | var matchValue = process.argv;
40 |
41 | if (matchValue.length >= 3) {
42 | return Number.parseInt(matchValue[2]);
43 | } else {
44 | return 8080;
45 | }
46 | }();
47 |
48 | var samplesPath = exports.samplesPath = path.resolve("../..");
49 | var relPath = exports.relPath = path.relative(samplesPath, ".");
50 |
51 | var server = exports.server = function () {
52 | var serve = serveStatic(samplesPath);
53 | var server = http.createServer(function (req, res) {
54 | var isDone = finalhandler(req, res);
55 | serve(req, res, isDone);
56 | });
57 | return server.listen(port);
58 | }();
59 |
60 | opener(_fableCore.String.fsFormat("http://localhost:%i/%s")(function (x) {
61 | return x;
62 | })(port)(relPath));
--------------------------------------------------------------------------------