Better caching, bundle viewer.

This commit is contained in:
David 2019-03-08 16:36:25 +01:00
commit 87e883931c
27 changed files with 295 additions and 385 deletions

23
viewer/.gitignore vendored Executable file
View file

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
# /build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View file

@ -0,0 +1,13 @@
{
"main.css": "./static/css/main.6efe09fd.chunk.css",
"main.js": "./static/js/main.db22f45d.chunk.js",
"main.js.map": "./static/js/main.db22f45d.chunk.js.map",
"runtime~main.js": "./static/js/runtime~main.9eb600ee.js",
"runtime~main.js.map": "./static/js/runtime~main.9eb600ee.js.map",
"static/js/2.772a56e7.chunk.js": "./static/js/2.772a56e7.chunk.js",
"static/js/2.772a56e7.chunk.js.map": "./static/js/2.772a56e7.chunk.js.map",
"index.html": "./index.html",
"precache-manifest.15b8d497ab10704d87b84878b92d08cf.js": "./precache-manifest.15b8d497ab10704d87b84878b92d08cf.js",
"service-worker.js": "./service-worker.js",
"static/css/main.6efe09fd.chunk.css.map": "./static/css/main.6efe09fd.chunk.css.map"
}

BIN
viewer/build/favicon.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

1
viewer/build/index.html Normal file
View file

@ -0,0 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="./manifest.json"/><title>Reanimate Playground</title><link href="./static/css/main.6efe09fd.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(l){function e(e){for(var r,t,n=e[0],o=e[1],u=e[2],f=0,i=[];f<n.length;f++)t=n[f],p[t]&&i.push(p[t][0]),p[t]=0;for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(l[r]=o[r]);for(s&&s(e);i.length;)i.shift()();return c.push.apply(c,u||[]),a()}function a(){for(var e,r=0;r<c.length;r++){for(var t=c[r],n=!0,o=1;o<t.length;o++){var u=t[o];0!==p[u]&&(n=!1)}n&&(c.splice(r--,1),e=f(f.s=t[0]))}return e}var t={},p={1:0},c=[];function f(e){if(t[e])return t[e].exports;var r=t[e]={i:e,l:!1,exports:{}};return l[e].call(r.exports,r,r.exports,f),r.l=!0,r.exports}f.m=l,f.c=t,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(r,e){if(1&e&&(r=f(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var n in r)f.d(t,n,function(e){return r[e]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="./";var r=window.webpackJsonp=window.webpackJsonp||[],n=r.push.bind(r);r.push=e,r=r.slice();for(var o=0;o<r.length;o++)e(r[o]);var s=n;a()}([])</script><script src="./static/js/2.772a56e7.chunk.js"></script><script src="./static/js/main.db22f45d.chunk.js"></script></body></html>

15
viewer/build/manifest.json Executable file
View file

@ -0,0 +1,15 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View file

@ -0,0 +1,22 @@
self.__precacheManifest = [
{
"revision": "9eb600ee07a27cdad64f",
"url": "./static/js/runtime~main.9eb600ee.js"
},
{
"revision": "db22f45d36ec0c1e28c1",
"url": "./static/js/main.db22f45d.chunk.js"
},
{
"revision": "772a56e764e5091f7538",
"url": "./static/js/2.772a56e7.chunk.js"
},
{
"revision": "db22f45d36ec0c1e28c1",
"url": "./static/css/main.6efe09fd.chunk.css"
},
{
"revision": "8912fe90ce5c625516525c7cd80ee665",
"url": "./index.html"
}
];

View file

@ -0,0 +1,34 @@
/**
* Welcome to your Workbox-powered service worker!
*
* You'll need to register this file in your web app and you should
* disable HTTP caching for this file too.
* See https://goo.gl/nhQhGp
*
* The rest of the code is auto-generated. Please don't update this file
* directly; instead, make changes to your Workbox build configuration
* and re-run your build process.
* See https://goo.gl/2aRDsh
*/
importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.6.3/workbox-sw.js");
importScripts(
"./precache-manifest.15b8d497ab10704d87b84878b92d08cf.js"
);
workbox.clientsClaim();
/**
* The workboxSW.precacheAndRoute() method efficiently caches and responds to
* requests for URLs in the manifest.
* See https://goo.gl/S9QRab
*/
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
workbox.routing.registerNavigationRoute("./index.html", {
blacklist: [/^\/_/,/\/[^\/]+\.[^\/]+$/],
});

View file

@ -0,0 +1,2 @@
body{margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}.App{height:100vh;background-color:#282c34;color:#fff;display:grid;grid-template-columns:1fr;grid-template-rows:auto;grid-auto-flow:column;-webkit-align-items:center;align-items:center;overflow:hidden}.controls{text-align:center}.controls svg{padding-left:5px;padding-right:5px}.viewer{position:static}.viewer svg{max-width:100vw;max-height:100vh;margin-top:auto;margin-bottom:auto}div.messages{position:fixed;top:0;width:100%;background:#282c34}div.messages pre{margin:0}.home{color:#fff;text-align:center;float:right;margin-right:2em}
/*# sourceMappingURL=main.6efe09fd.chunk.css.map */

View file

@ -0,0 +1 @@
{"version":3,"sources":["/home/lemmih/Coding/Haskell/reanimate/viewer/src/index.css","main.6efe09fd.chunk.css","/home/lemmih/Coding/Haskell/reanimate/viewer/src/App.css"],"names":[],"mappings":"AAAA,KACE,QAAA,CACA,SAAA,CACA,mICEY,CDCZ,kCAAA,CACA,iCCCF,CDEA,KACE,uECEF,CCbA,KAGE,YAAA,CACA,wBAAA,CACA,UAAA,CACA,YAAA,CACA,yBAAA,CACA,uBAAA,CAEA,qBAAA,CACA,0BAAA,CAAA,kBAAA,CACA,eDiBF,CCZA,UACE,iBDiBF,CCfA,cACE,gBAAA,CACA,iBDiBF,CCfA,QACE,eDiBF,CCfA,YACE,eAAA,CACA,gBAAA,CACA,eAAA,CACA,kBDiBF,CCfA,aACE,cAAA,CACA,KAAA,CACA,UAAA,CACA,kBDiBF,CCfA,iBACE,QDiBF,CCfA,MACE,UAAA,CACA,iBAAA,CACA,WAAA,CACA,gBDiBF","file":"main.6efe09fd.chunk.css","sourcesContent":["body {\n margin: 0;\n padding: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\",\n \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\",\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\",\n monospace;\n}\n","body {\n margin: 0;\n padding: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\",\n \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\",\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\",\n monospace;\n}\n\n.App {\n /* text-align: center; */\n /* min-height: 100vh; */\n height: 100vh;\n background-color: #282c34;\n color: white;\n display: grid;\n grid-template-columns: 1fr;\n grid-template-rows: auto;\n /* grid-gap: 1em; */\n grid-auto-flow: column;\n -webkit-align-items: center;\n align-items: center;\n overflow: hidden;\n}\n.editor {\n /* min-width: 35em; */\n}\n.controls {\n text-align:center;\n}\n.controls svg {\n padding-left: 5px;\n padding-right: 5px;\n}\n.viewer {\n position: static;\n}\n.viewer svg {\n max-width: 100vw;\n max-height: 100vh;\n margin-top: auto;\n margin-bottom: auto;\n}\ndiv.messages {\n position: fixed;\n top: 0;\n width: 100%;\n background: #282c34;\n}\ndiv.messages pre {\n margin: 0;\n}\n.home {\n color: white;\n text-align: center;\n float:right;\n margin-right: 2em;\n}\n\n\n#editor {\n\n}\n\n",".App {\n /* text-align: center; */\n /* min-height: 100vh; */\n height: 100vh;\n background-color: #282c34;\n color: white;\n display: grid;\n grid-template-columns: 1fr;\n grid-template-rows: auto;\n /* grid-gap: 1em; */\n grid-auto-flow: column;\n align-items: center;\n overflow: hidden;\n}\n.editor {\n /* min-width: 35em; */\n}\n.controls {\n text-align:center;\n}\n.controls svg {\n padding-left: 5px;\n padding-right: 5px;\n}\n.viewer {\n position: static;\n}\n.viewer svg {\n max-width: 100vw;\n max-height: 100vh;\n margin-top: auto;\n margin-bottom: auto;\n}\ndiv.messages {\n position: fixed;\n top: 0;\n width: 100%;\n background: #282c34;\n}\ndiv.messages pre {\n margin: 0;\n}\n.home {\n color: white;\n text-align: center;\n float:right;\n margin-right: 2em;\n}\n\n\n#editor {\n\n}\n"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[0],{10:function(e,n,t){e.exports=t(18)},16:function(e,n,t){},17:function(e,n,t){},18:function(e,n,t){"use strict";t.r(n);var s=t(0),a=t.n(s),o=t(4),r=t.n(o),i=(t(16),t(2)),c=t(5),l=t(6),m=t(9),g=t(7),u=t(1),d=t(8),v=(t(17),function(e){function n(e){var t;Object(c.a)(this,n),(t=Object(m.a)(this,Object(g.a)(n).call(this,e))).connect=function(){var e=new WebSocket("ws://localhost:9161");e.onopen=function(n){t.setState(function(e){return Object(i.a)({},e,{message:"Connected."})}),e.send("60")},e.onclose=function(e){t.setState(function(e){return Object(i.a)({},e,{message:"Disconnected."})}),setTimeout(t.connect,1e3)},e.onmessage=function(e){if("Success!"===e.data)console.log("Success");else if("Compiling"===e.data)t.setState({message:"Compiling..."});else if("Rendering"===e.data)t.setState({message:"Rendering..."}),t.nFrames_new=0,t.svgs_new=[];else if("Done"===e.data)t.setState({message:""}),console.log("Done"),t.nFrames=t.nFrames_new,t.svgs=t.svgs_new,t.nFrames_new=0,t.svgs_new=[],t.start=Date.now();else if(e.data.startsWith("Error"))console.log("Error"),t.setState({message:e.data.substring(5)});else{t.setState({message:"Rendering: ".concat(t.nFrames_new)}),t.nFrames_new++;var n=document.createElement("div");n.innerHTML=e.data,t.svgs_new.push(n)}},t.setState(function(n){return Object(i.a)({},n,{socket:e,message:"Connecting..."})})},t.onLoad=function(e){setTimeout(function(){e.resize()},0)},t.state={},setTimeout(t.connect,0),t.nFrames_new=0,t.svgs_new=[],t.nFrames=0,t.svgs=[],t.start=Date.now();var s=Object(u.a)(t);return requestAnimationFrame(function e(){var n=Date.now(),a=s.nFrames,o=Math.round((n-t.start)/1e3*60)%a;if(s.svgs_new.length){for(;s.svg.firstChild;)s.svg.removeChild(s.svg.firstChild);s.svg.appendChild(s.svgs_new[s.svgs_new.length-1])}else if(a){for(;s.svg.firstChild;)s.svg.removeChild(s.svg.firstChild);s.svg.appendChild(s.svgs[o])}else s.svg.innerText="";requestAnimationFrame(e)}),t}return Object(d.a)(n,e),Object(l.a)(n,[{key:"render",value:function(){var e=this,n=this.state.message;return a.a.createElement("div",{className:"App"},a.a.createElement("div",{className:"viewer"},a.a.createElement("div",{ref:function(n){return e.svg=n}}),a.a.createElement("div",{className:"messages"},a.a.createElement("pre",null,n))))}}]),n}(s.Component));Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/));r.a.render(a.a.createElement(v,null),document.getElementById("root")),"serviceWorker"in navigator&&navigator.serviceWorker.ready.then(function(e){e.unregister()})}},[[10,1,2]]]);
//# sourceMappingURL=main.db22f45d.chunk.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,2 @@
!function(e){function r(r){for(var n,f,i=r[0],l=r[1],a=r[2],c=0,s=[];c<i.length;c++)f=i[c],o[f]&&s.push(o[f][0]),o[f]=0;for(n in l)Object.prototype.hasOwnProperty.call(l,n)&&(e[n]=l[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,a||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var l=t[i];0!==o[l]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={1:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"===typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="./";var i=window.webpackJsonp=window.webpackJsonp||[],l=i.push.bind(i);i.push=r,i=i.slice();for(var a=0;a<i.length;a++)r(i[a]);var p=l;t()}([]);
//# sourceMappingURL=runtime~main.9eb600ee.js.map

File diff suppressed because one or more lines are too long

View file

@ -2365,11 +2365,6 @@
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
},
"brace": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/brace/-/brace-0.11.1.tgz",
"integrity": "sha1-SJb8ydVE7vRfS7dmDbMg07N5/lg="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -4400,11 +4395,6 @@
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
},
"diff-match-patch": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.4.tgz",
"integrity": "sha512-Uv3SW8bmH9nAtHKaKSanOQmj2DnlH65fUpcrMdfdaOxUG02QQ4YGZ8AE7kKOMisF7UqvOlGKVYWRvezdncW9lg=="
},
"diffie-hellman": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
@ -8860,11 +8850,6 @@
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
},
"lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
},
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@ -12490,18 +12475,6 @@
"scheduler": "^0.13.2"
}
},
"react-ace": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/react-ace/-/react-ace-6.4.0.tgz",
"integrity": "sha512-woTTgGk9x4GRRWiM4QLNOspjaJAYLX3UZ3J2XRYQvJiN6wyxrFY9x7rdOKc+4Tj+khb/ccPiDj/kll4UeJEDPw==",
"requires": {
"brace": "^0.11.1",
"diff-match-patch": "^1.0.4",
"lodash.get": "^4.4.2",
"lodash.isequal": "^4.5.0",
"prop-types": "^15.6.2"
}
},
"react-app-polyfill": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-0.2.1.tgz",

View file

@ -2,10 +2,9 @@
"name": "viewer",
"version": "0.1.0",
"private": true,
"homepage": "https://lemmih.github.io/reanimate",
"homepage": ".",
"dependencies": {
"react": "^16.8.2",
"react-ace": "^6.4.0",
"react-dom": "^16.8.2",
"react-scripts": "2.1.5"
},

View file

@ -1,11 +1,5 @@
import React, {Component} from 'react';
import './App.css';
import AceEditor from 'react-ace';
import 'brace/mode/haskell';
import 'brace/theme/github';
import 'brace/theme/monokai';
import preset from './Presets';
class App extends Component {
connect = () => {
@ -64,7 +58,6 @@ class App extends Component {
super(props);
this.state = {
program: preset[0].programs[0].code
};
setTimeout(this.connect, 0);
this.nFrames_new = 0;
@ -101,27 +94,8 @@ class App extends Component {
ace.resize();
}, 0);
}
onChange = text => {
this.setState({program: text});
if (this.timeout)
clearTimeout(this.timeout);
const socket = this.state.socket
const self = this;
this.timeout = setTimeout(function() {
console.log('change', text);
self.setState(state => ({
...state,
message: "Compiling..."
}));
socket.send(text);
}, 500);
};
selectPreset = evt => {
this.onChange(evt.target.value);
};
render() {
const {message, program} = this.state;
const {message} = this.state;
return (
<div className="App">
<div className="viewer">

View file

@ -1,217 +0,0 @@
const latex_draw =
`animation :: Animation
animation =
bg \`sim\` (autoReverse $ drawText \`andThen\` fillText)
where
bg = mkAnimation 0 $ emit (mkBackground "black")
msg = "\\\\sum_{k=1}^\\\\infty {1 \\\\over k^2} = {\\\\pi^2 \\\\over 6}"
glyphs = center $ latexAlign msg
fillText = mkAnimation 1 $ do
s <- signal 0 1
emit $ scale 5 $ withFillColor "white" $ withFillOpacity s glyphs
drawText = mkAnimation 2 $ do
s <- signal 0 1
emit $ scale 5 $
withStrokeColor "white" $ withFillOpacity 0 $ withStrokeWidth (Num 0.1) $
partialSvg s glyphs`;
const bbox =
`animation :: Animation
animation = bg \`sim\`
mapA (translate (-50) 0) bbox1 \`sim\`
mapA (translate 50 0) bbox2
where
bg = mkAnimation 0 $ emit $ mkBackground "black"
bbox1 :: Animation
bbox1 = mkAnimation 5 $ do
s <- signal 0 1
emit $ mkGroup
[ mkBoundingBox $ rotate (360*s) svg
, withFillColor "white" $ rotate (360*s) svg ]
where
svg = scale 3 $ center $ latexAlign "\\\\sum_{k=1}^\\\\infty"
bbox2 :: Animation
bbox2 = autoReverse $ mkAnimation 2.5 $ do
s <- signal 0 1
emit $ mkGroup
[ mkBoundingBox $ partialSvg s heartShape
, withStrokeColor "white" $ withFillOpacity 0 $ partialSvg s heartShape ]
mkBoundingBox :: Tree -> Tree
mkBoundingBox svg = withStrokeColor "red" $ withFillOpacity 0 $
mkRect (S.Num x, S.Num y) (S.Num w) (S.Num h)
where
(x, y, w, h) = boundingBox svg
heartShape =
center $ rotateAroundCenter 225 $ mkPathString
"M0.0,40.0 v-40.0 h40.0a20.0 20.0 90.0 0 1 0.0,40.0a20.0 20.0 90.0 0 1 -40.0,0.0 Z"`;
const sinewave =
`animation :: Ani ()
animation = proc () -> do
duration 10 -< ()
emit -< toHtml $ mkBackground "black"
idx <- signalOscillate 0 1 -< ()
emit -< do
defs_ $ clipPath_ [id_ "clip"] $ toHtml $
mkRect (Num 0, Num (-height)) (Num $ idx*width) (Num 320)
toHtml $ translate margin height $ withStrokeColor "white" $
withClipPathRef (Ref "clip") $ mkPathText $ renderPathText $ approxFnData 100 wave
toHtml $ withStrokeColor "white" $
mkLine (Num margin, Num 10) (Num margin, Num 170)
toHtml $ withStrokeColor "white" $
mkLine (Num margin, Num height) (Num (margin+width), Num height)
let (circX, circY) = wave idx
emit -< g_ [transform_ $ Lucid.translate margin height] $
circle_ [num_ cx_ circX, num_ cy_ circY, r_ "3", fill_ "red"]
where
freq = 3; margin = 30; width = 260; height = 90
wave idx = (idx*width, sin (idx*pi*2*freq) * 50)`;
const morph_wave =
`animation :: Animation
animation = autoReverse $ mkAnimation 2.5 $ do
morph <- signal 0 1
emit $ mkBackground "black"
emit $ withStrokeColor "white" $ translate (-320/2) (-180/2) $ mkGroup
[ translate 30 50 $ mkLinePath wave1
, translate 30 130 $ mkLinePath wave2
, translate 30 90 $ mkLinePath $ morphPath wave1 wave2 morph
, mkLine (Num 30, Num 10) (Num 30, Num 170)
, mkLine (Num 30, Num 90) (Num 290, Num 90) ]
where
freq = 3; width = 260
wave1 = approxFnData 100 $ \\idx -> (idx*width, sin (idx*pi*2*freq) * 20)
wave2 = approxFnData 100 $ \\idx -> (idx*width, sin (idx*pi*2*(freq*3)) * 20)`;
const morph_wave_circle =
`animation :: Animation
animation = autoReverse $ mkAnimation 2.5 $ do
idx <- signal 0 1
emit $ mkBackground "black"
emit $ withStrokeColor "white" $ translate (-320/2) (-180/2) $ mkGroup
[ translate 30 90 $ mkLinePath $ morphPath circle wave1 idx
, mkLine (Num 30, Num 10) (Num 30, Num 170)
, mkLine (Num 30, Num 90) (Num 290, Num 90) ]
where
freq = 5; width = 260; radius = 50
wave1 = approxFnData 100 $ \\idx -> (idx*width, sin (idx*pi*2*freq) * 20)
circle = approxFnData 100 $ \\idx ->
(cos (idx*pi*2+pi/2)*radius + width/2, sin (idx*pi*2+pi/2)*radius)`;
const progressMeters =
`animation :: Animation
animation =
bg \`sim\` labels \`sim\`
mapA (translate (-100) 0) (adjustSpeed 1.0 progressMeter) \`simLoop\`
mapA (translate 0 0) (adjustSpeed 2.0 progressMeter) \`simLoop\`
mapA (translate 100 0) (adjustSpeed 0.5 progressMeter)
where
bg = mkAnimation 0 $ emit $ mkBackground "black"
labels = mkAnimation 0 $ emit $ translate 0 70 $ withFillColor "white" $ mkGroup
[ translate (-100) 0 $ scale 2 $ center $ latex "1x"
, translate 0 0 $ scale 2 $ center $ latex "2x"
, translate 100 0 $ scale 2 $ center $ latex "0.5x"
]
progressMeter :: Animation
progressMeter = mkAnimation 3 $ do
h <- signal 0 100
emit $ center $ mkGroup
[ withStrokeColor "white" $ withStrokeWidth (Num 2) $ withFillOpacity 0 $
mkRect (Num 0, Num 0) (Num 30) (Num 100)
, withFillColor "white" $
mkRect (Num 0, Num 0) (Num 30) (Num h) ]`
const latex_basic =
`animation :: Animation
animation = autoReverse $ mkAnimation 2 $ do
s <- signal 0 1
emit $ mkGroup
[ mkBackground "black"
, withStrokeColor "white" $ withFillOpacity 0 $ withStrokeWidth (Num 0.1) text
, withFillColor "white" $ withFillOpacity s text ]
where
text = scale 4 $ center $ latexAlign
"\\\\sum_{k=1}^\\\\infty {1 \\\\over k^2} = {\\\\pi^2 \\\\over 6}"`
const latex_color =
`animation :: Animation
animation = mkAnimation 1 $ do
emit $ mkBackground "black"
emit $ withStrokeWidth (Num 0.2) $
withStrokeColor "white" $
withSubglyphs [0] (withFillColor "blue") $
withSubglyphs [1] (withFillColor "yellow") $
withSubglyphs [2] (withFillColor "green") $
withSubglyphs [3] (withFillColor "red") $
withSubglyphs [4] (withFillColor "darkslategrey") $
svg
where
svg = scale 10 $ center $ latex "\\\\LaTeX"`;
const valentine =
`animation :: Animation
animation =
all_red \`before\`
( background \`sim\`
(backgroundDelay \`before\`
foldr1 sim [ pause p \`before\` fallingLove p x | (p, x) <- falling ]
) \`sim\`
(heart_ani \`before\` heart_disappear) \`sim\`
(pause 1 \`before\` repeatAnimation 10 (message ai))
)
where
falling = [(6.4, 0.09), (4.9, 0.12), (4.5, 0.88), (0.3, 0.43), (5.3, 0.93)
,(0.1, 0.80), (1.1, 0.39), (2.3, 0.21), (2.9, 0.77), (3.4, 0.46)
,(6.2, 0.88), (5.9, 0.80), (3.2, 0.14), (7.7, 0.99), (3.4, 0.35)
,(0.4, 0.51), (7.1, 0.60), (7.7, 0.65)]
ai = center $ xelatex "爱"
all_red = mkAnimation 1 $ emit $ mkBackground "red"
background = mkAnimation 2 $ do
n <- round <$> signal 0 0xFF
emit $ mkBackgroundPixel $ PixelRGBA8 0xFF n n 0xFF
backgroundDelay = pause (duration background-1)
heart_ani = repeatAnimation 10 $ mkAnimation 1 $ do
n <- oscillate $ signalSCurve 2 0.9 1.1
mapF (scale n) $ drawHeart
heart_disappear = mkAnimation 3 $ do
n <- signal 0.9 10
o <- oscillate $ signal 0 1.5
mapF (scale n) drawHeart
mapF (scale (n*4)) $ emit $ withFillOpacity o $ withFillColor "white" ai
fallingLove rand xPos = mkAnimation 2 $ do
n <- signal (-100) 90
o <- signal 0 5
emit $ withStrokeColor "black" $ withFillColor "red" $
translate ((xPos*2-1)*(320/2)) n $ scale 0.3 $ rotate (60*(o+rand+xPos)) heartShape
message txt = mkAnimation 1 $ do
o <- oscillate $ signal 0 1
n <- oscillate $ signalSCurve 2 0.9 1.1
emit $ scale n $ scale 2 $ withFillColor "white" $ withFillOpacity o txt
drawHeart = emit $ withFillColor "red" $ heartShape
heartShape =
center $ rotateAroundCenter 225 $ mkPathString
"M0.0,40.0 v-40.0 h40.0a20.0 20.0 90.0 0 1 0.0,40.0a20.0 20.0 90.0 0 1 -40.0,0.0 Z"`;
export default [
{ name: "Examples"
, programs:
[ {name: "LaTeX Draw", code: latex_draw }
, {name: "LaTeX Color", code: latex_color }
, {name: "LaTeX Basic", code: latex_basic }
, {name: "Bounding boxes", code: bbox }
// , {name: "Sinewave", code: sinewave }
, {name: "Morphwave", code: morph_wave }
, {name: "Morphwave Circle", code: morph_wave_circle }
, {name: "Progress meters", code: progressMeters }
, {name: "Valentine", code: valentine }
// , {name: "Highlight", code: highlight }
]
},
];