Browse Source

clean up

gh-pages
Jongmin Kim 5 years ago
parent
commit
03d2bcd144
  1. 4
      .gitignore
  2. 21
      LICENSE
  3. 129
      README.md
  4. 1
      dist/leon.js
  5. 111
      examples/all.html
  6. 120
      examples/canvas-basic.html
  7. 144
      examples/color-pattern.html
  8. 113
      examples/colorful.html
  9. 109
      examples/gradient.html
  10. 94
      examples/grid.html
  11. 267
      examples/index.html
  12. 199
      examples/mask-tiling-pixi.html
  13. 230
      examples/metaball-pixi.html
  14. 232
      examples/morphing-pixi.html
  15. 94
      examples/pattern.html
  16. 227
      examples/plants-pixi.html
  17. 82
      examples/wave.html
  18. 124
      examples/webgl-basic-pixi.html
  19. BIN
      screenshot/latin-lower.gif
  20. BIN
      screenshot/latin-upper.gif
  21. BIN
      screenshot/latin2.gif
  22. BIN
      screenshot/lower.gif
  23. BIN
      screenshot/lowercase.gif
  24. BIN
      screenshot/number-special.gif
  25. BIN
      screenshot/number.gif
  26. BIN
      screenshot/upper.gif
  27. BIN
      screenshot/uppercase.gif
  28. 17
      src/core/align.js
  29. 46
      src/core/dispatcher.js
  30. 125
      src/core/group.js
  31. 45
      src/core/guide.js
  32. 123
      src/core/length.js
  33. 311
      src/core/model.js
  34. 200
      src/core/paths.js
  35. 21
      src/core/point.js
  36. 214
      src/core/util.js
  37. 101
      src/core/vector.js
  38. 20
      src/draw/canvas/color.js
  39. 93
      src/draw/canvas/colorful.js
  40. 23
      src/draw/canvas/grids.js
  41. 26
      src/draw/canvas/lines.js
  42. 31
      src/draw/canvas/pattern.js
  43. 73
      src/draw/canvas/points.js
  44. 54
      src/draw/canvas/wave.js
  45. 33
      src/draw/pixi/color.js
  46. 51
      src/draw/pixi/lines.js
  47. 23
      src/font/index.js
  48. 884
      src/font/lower.js
  49. 344
      src/font/number.js
  50. 890
      src/font/special.js
  51. 892
      src/font/upper.js
  52. 76
      src/font/util.js
  53. 2
      src/index.js
  54. 521
      src/leonsans.js

4
.gitignore vendored

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
examples/data/.DS_Store
examples/.DS_Store
.DS_Store

21
LICENSE

@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
MIT License
Copyright (c) 2019 Jongmin Kim
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

129
README.md

@ -1,129 +0,0 @@ @@ -1,129 +0,0 @@
# leonsans
Leon Sans is a geometric sans-serif typeface made with code in 2019 by Jongmin Kim. It allows to change font weight dynamically and to create custom animations, effects or shapes in the Canvas element of HTML5. He designed the font to celebrate his newborn baby Leon.
There are live examples at https://leon-kim.com/examples/
And website at https://leon-kim.com/
![uppercase](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/uppercase.gif)
![lowercase](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/lowercase.gif)
![number](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/number.gif)
## What is special?
The font is made with code, it has coordinate values of the drawing points for each type. With the coordinate values, you can create custom shapes, effects or animations.
![Drawing animation](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/drawing.gif)
- [Drawing animation](https://leon-kim.com/examples/#canvas-basic)
![Weight change](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/weight.gif)
- [Weight change](https://leon-kim.com/examples/#canvas-basic)
![Wave](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/wave.gif)
- [Wave](https://leon-kim.com/examples/#wave)
![Metaball](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/metaball.gif)
- [Metaball](https://leon-kim.com/examples/#metaball-pixi)
![Plant](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/plant.gif)
- [Plant](https://leon-kim.com/examples/#plants-pixi)
![Colorful](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/colorful.gif)
- [Colorful](https://leon-kim.com/examples/#colorful)
![Color pattern](https://raw.githubusercontent.com/cmiscm/leonsans/gh-pages/screenshot/colorpattern.gif)
- [Color pattern](https://leon-kim.com/examples/#color-pattern)
## Usage
Download the minified js file in dist folder and include it in your html.
```html
<script src="js/leon.js"></script>
```
Generate LeonSans and draw it in the Canvas element of HTML5.
```javascript
this.canvas = document.createElement('canvas');
document.body.appendChild(this.canvas);
this.ctx = this.canvas.getContext("2d");
this.leon = new LeonSans({
text: 'The quick brown\nfox jumps over\nthe lazy dog',
color: ['#000000'],
size: 160,
weight: 200
});
requestAnimationFrame(animate);
function animate(t) {
requestAnimationFrame(animate);
this.ctx.clearRect(0, 0, document.body.clientWidth, document.body.clientHeight);
const x = (document.body.clientWidth - this.leon.rect.w) / 2;
const y = (document.body.clientHeight - this.leon.rect.h) / 2;
this.leon.position(x, y);
this.leon.draw(this.ctx);
}
```
### Option list
| Name | Type | Description |
| -------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `text` | string | The text that needs to be shown. |
| `size` | integer | The size of the text. |
| `weight` | number | The weight of the font: `1 - 900`. [Default: `1`] |
| `color` | array | The colors of each characters. [Default: `['#000000']`] |
| `colorful` | array | The colors for colorful effect. [Default: `['#c5d73f', '#9d529c', '#49a9db', '#fec330', '#5eb96e', '#fc5356', '#f38f31']`] |
| `tracking` | integer | The spacing between the characters of a block of text. [Default: `0`] |
| `leading` | integer | The distance between each line of text. [Default: `0`] |
| `align` | string | How the text content of the element is horizontally aligned: `left, center, right`. [Default: `left`] |
| `pathGap` | number | The gap between each coordinate of the points on a line of each character: `0 - 1`. [Default: `0.5`] |
| `amplitude` | number | The amplitude of the wave effect: `0 - 1`. [Default: `0.5`] |
| `maxWidth` | number | The width of the text sentence. |
| `breakWord` | boolean | Words break when reaching the end of a line. [Default: `false`] |
| `fps` | number | The FPS for the wave effect. [Default: `30`] |
| `isPath` | boolean | `true` to get the coordinate values of the points on a line of each character. [Default: `false`] |
| `isWave` | boolean | `true` for the wave effect. [Default: `false`] |
### Properties
| Name | Type | Description |
| -------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `lineWidth` | number | The thickness of lines of the character. |
| `scale` | number | The scale of the character. `scale` is `1` when the font size is `500`. |
| `drawing` | array | The drawing object values for each character. `0` is the beginning of the animation, `1` is the end of the animation state. |
| `data` | array | An object of the raw data for the text. |
| `paths` | array | The coordinate values of the points on a line of each character. |
| `drawingPaths` | array | The coordinate values of the points on a line of each character to draw the drawing animation in WebGL. It has 1px distance of each path. |
| `wavePaths` | array | The coordinate values of the points on a line for the wave effect. |
| `rect` | Object | The size of the text and its position: `{x: x position, y: y position, w: width, h: height}`.|
### Methods
| Name | Description |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `on()` | Add `update` event. |
| `off()` | Remove `update` event. |
| `position(x, y)` | Set the position of the text. |
| `updateDrawingPaths()` | Update paths for drawing in WebGL (PIXI.js). It's very expensive, only call when it needs. |
| `drawPixi(graphics)` | Draw text in WebGL with PIXI.js. |
| `draw(ctx)` | Draw text in the Canvas element. |
| `drawColorful(ctx)` | Draw the colorful effect. |
| `wave(ctx, t)` | Draw the wave effect. |
| `pattern(ctx, w, h)` | Draw rectangle shapes at each path point |
| `grid(ctx)` | Draw grid for each type. |
| `point(ctx)` | Draw circles at each drawing point and lines for each type. |
| `box(ctx)` | Draw outline box for the text. |
| `reset()` | Reset all the values. |
| `destroy()` | Destroy. |

1
dist/leon.js vendored

File diff suppressed because one or more lines are too long

111
examples/all.html

@ -1,111 +0,0 @@ @@ -1,111 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>Leon Sans - All</title>
<style>
html, body {
width: 100%;
height: 100%;
overflow: hidden;
outline: 0;
margin: 0;
padding: 0;
background-color: #f0f0f0;
cursor: move;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>
<body>
<script src="../dist/leon.js"></script>
<script src="js/util.js"></script>
<script>
let leon, controll;
function init() {
generateCanvas();
controll = {
align: {},
box: false,
grids: false,
points: false,
drawing: () => {
let i, total = leon.drawing.length;
for (i = 0; i < total; i++) {
TweenMax.killTweensOf(leon.drawing[i]);
TweenMax.fromTo(leon.drawing[i], 2, {
value: 0
}, {
value: 1,
ease: Power3.easeOut
});
}
}
};
leon = new LeonSans({
text: 'abcdefghijklmn\nopqrstuvwxyz\nABCDEFGHIJK\nLMNOPQRST\nUVWXYZ\n0123456789\n?!$^&*(){}[]<>~\n:;,.\'"+=-_@#%',
color: ['#342f2e'],
size: getSize(90),
weight: 200,
tracking: 2,
leading: 1,
align: 'center'
});
const gui = new dat.GUI();
gui.add(leon, 'text');
gui.add(leon, 'size', 20, 1000);
gui.add(leon, 'weight', 1, 900);
gui.add(leon, 'tracking', -3, 10);
gui.add(leon, 'leading', -8, 10);
gui.add(controll, 'drawing');
gui.add(controll, 'box');
gui.add(controll, 'grids');
gui.add(controll, 'points');
requestAnimationFrame(animate);
}
function animate(t) {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, sw, sh);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x + moveX, y + moveY);
ctx.save();
if (controll.grids) leon.grid(ctx);
if (controll.box) leon.box(ctx);
ctx.restore();
ctx.save();
leon.draw(ctx);
ctx.restore();
if (controll.points) {
ctx.save();
leon.point(ctx);
ctx.restore();
}
}
window.onload = () => {
init();
};
</script>
</body>
</html>

120
examples/canvas-basic.html

@ -1,120 +0,0 @@ @@ -1,120 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>Leon Sans - Canvas Basic</title>
<style>
html, body {
width: 100%;
height: 100%;
overflow: hidden;
outline: 0;
margin: 0;
padding: 0;
background-color: #f0f0f0;
cursor: move;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>
<body>
<script src="../dist/leon.js"></script>
<script src="js/util.js"></script>
<script>
let leon, controll;
function init() {
generateCanvas();
controll = {
color: {},
align: {},
drawing: () => {
let i, total = leon.drawing.length;
for (i = 0; i < total; i++) {
TweenMax.killTweensOf(leon.drawing[i]);
TweenMax.fromTo(leon.drawing[i], 1.6, {
value: 0
}, {
delay: i * 0.05,
value: 1,
ease: Power4.easeOut
});
}
}
};
leon = new LeonSans({
text: 'The quick brown\nfox jumps over\nthe lazy dog',
color: ['#342f2e'],
size: getSize(120),
weight: 300
});
const gui = new dat.GUI();
gui.add(leon, 'text');
gui.add(leon, 'size', 20, 1000);
gui.add(leon, 'weight', 1, 900);
gui.add(leon, 'tracking', -3, 10);
gui.add(leon, 'leading', -8, 10);
const alignControll = gui.add(controll, 'align', [ 'left', 'center', 'right'] );
gui.add(leon, 'maxWidth', 0, 2000);
gui.add(leon, 'breakWord');
gui.add(controll, 'drawing');
const colorControll = gui.add(controll, 'color', [ 'black', 'white', 'yellow', 'red - blue', 'mixed'] );
alignControll.onChange((value) => {
leon.align = value;
});
alignControll.setValue('left');
colorControll.onChange((value) => {
if (value == 'black') {
document.body.style.backgroundColor = '#f0f0f0';
leon.color = ['#342f2e'];
} else if (value == 'white') {
document.body.style.backgroundColor = '#000000';
leon.color = ['#ffffff'];
} else if (value == 'yellow') {
document.body.style.backgroundColor = '#57c4e2';
leon.color = ['#ffd93c'];
} else if (value == 'red - blue') {
document.body.style.backgroundColor = '#ffffff';
leon.color = [['#ff94a7', '#1c7dd1']];
} else if (value == 'mixed') {
document.body.style.backgroundColor = '#ffffff';
leon.color = ['#ff5892', '#7bc92f', ['#3eda4e', '#f4bf14', '#fa314c', '#074aee'], '#ffd93c', '#c0008b'];
}
});
colorControll.setValue('black');
requestAnimationFrame(animate);
}
function animate(t) {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, sw, sh);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x + moveX, y + moveY);
leon.draw(ctx);
}
window.onload = () => {
init();
};
</script>
</body>
</html>

144
examples/color-pattern.html

@ -1,144 +0,0 @@ @@ -1,144 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>LeonSans - Color Pattern</title>
<style>
html, body {
width: 100%;
height: 100%;
overflow: hidden;
outline: 0;
margin: 0;
padding: 0;
background-color: #121212;
cursor: move;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>
<body>
<script src="../dist/leon.js"></script>
<script src="js/util.js"></script>
<script>
const speed = 10;
const fps = 1000 / 30;
const PI2 = 2 * Math.PI;
let cValue = 0, mode;
let leon, controll, time;
function init() {
generateCanvas();
controll = {
size: 200,
pathGap: 0,
patternWidth: 2,
visual: {},
drawing: () => {
let i, total = leon.drawing.length;
for (i = 0; i < total; i++) {
TweenMax.killTweensOf(leon.drawing[i]);
TweenMax.fromTo(leon.drawing[i], 2, {
value: 0
}, {
delay: i * 0.1,
value: 1,
ease: Power4.easeOut
});
}
}
};
leon = new LeonSans({
text: 'abcdefg',
size: getSize(200),
weight: 500,
pathGap: -1,
isPath: true
});
const gui = new dat.GUI();
gui.add(leon, 'text');
gui.add(leon, 'size', 10, 1000);
const weightControll = gui.add(controll, 'patternWidth', 1, 100);
gui.add(controll, 'drawing');
const visControll = gui.add(controll, 'pathGap', [ '-1', '0'] );
visControll.onChange((value) => {
mode = value;
if (mode == '-1') {
weightControll.setValue(40);
leon.pathGap = -1;
leon.tracking = 1;
} else if (mode == '0') {
weightControll.setValue(40);
leon.pathGap = 0;
leon.tracking = 1;
}
});
visControll.setValue('-1');
requestAnimationFrame(animate);
}
function update() {
ctx.clearRect(0, 0, sw, sh);
ctx.lineWidth = 0.2;
const w = controll.patternWidth * leon.scale;
const total = leon.data.length;
let i, p, pos, no = 0;
let d, j, j_total;
for (i = 0; i < total; i++) {
d = leon.data[i].paths;
j_total = Math.round(d.length * leon.drawing[i].value);
for (j = 0; j < j_total; j++) {
pos = d[j];
ctx.fillStyle = randomColor(no);
ctx.strokeStyle = randomColor(no);
ctx.beginPath();
ctx.arc(pos.x, pos.y, w, 0, PI2);
ctx.stroke();
no += 1;
}
}
cValue -= speed;
}
function randomColor(no) {
return "hsl(" + (no + cValue) + ',' + '70%,' + '50%)';
}
function animate(t) {
requestAnimationFrame(animate);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x + moveX, y + moveY);
if (t) {
if (!time) time = t;
if (t - time > fps) {
time = t;
update();
}
}
}
window.onload = () => {
init();
};
</script>
</body>
</html>

113
examples/colorful.html

@ -1,113 +0,0 @@ @@ -1,113 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>Leon Sans - Colorful</title>
<style>
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
outline: 0;
margin: 0;
padding: 0;
background-color: #f0f0f0;
cursor: move;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>
<body>
<script src="../dist/leon.js"></script>
<script src="js/util.js"></script>
<script>
let leon, controll;
function init() {
generateCanvas();
controll = {
color: {},
roundCap: true,
multiply: true,
drawing: () => {
let i, total = leon.drawing.length;
for (i = 0; i < total; i++) {
TweenMax.killTweensOf(leon.drawing[i]);
TweenMax.fromTo(leon.drawing[i], 2, {
value: 0
}, {
value: 1,
ease: Cubic.easeOut
});
}
}
};
leon = new LeonSans({
text: 'The quick brown\nfox jumps over\nthe lazy dog',
color: ['#000000'],
size: getSize(120),
weight: 500
});
const gui = new dat.GUI();
gui.add(leon, 'text');
gui.add(leon, 'size', 20, 300);
gui.add(leon, 'weight', 1, 900);
gui.add(leon, 'tracking', -3, 10);
gui.add(leon, 'leading', -8, 10);
gui.add(controll, 'drawing');
const roundCapControll = gui.add(controll, 'roundCap');
const multiplyControll = gui.add(controll, 'multiply');
roundCapControll.onChange((value) => {
if (value) {
ctx.lineCap = "round";
} else {
ctx.lineCap = "butt";
}
});
multiplyControll.onChange((value) => {
if (value) {
ctx.globalCompositeOperation = 'multiply';
} else {
ctx.globalCompositeOperation = 'source-over';
}
});
requestAnimationFrame(animate);
roundCapControll.setValue(true);
multiplyControll.setValue(true);
}
function animate(t) {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, sw, sh);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x + moveX, y + moveY);
leon.drawColorful(ctx);
}
window.onload = () => {
init();
};
</script>
</body>
</html>

109
examples/gradient.html

@ -1,109 +0,0 @@ @@ -1,109 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>Leon Sans - Gradient</title>
<style>
html, body {
width: 100%;
height: 100%;
overflow: hidden;
outline: 0;
margin: 0;
padding: 0;
background-color: #f0f0f0;
cursor: move;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>
<body>
<script src="../dist/leon.js"></script>
<script src="js/util.js"></script>
<script>
let leon, controll;
function init() {
generateCanvas();
controll = {
box: false,
grids: false,
points: false,
drawing: () => {
let i, total = leon.drawing.length;
for (i = 0; i < total; i++) {
TweenMax.killTweensOf(leon.drawing[i]);
TweenMax.fromTo(leon.drawing[i], 2, {
value: 0
}, {
value: 1,
ease: Power4.easeOut
});
}
}
};
leon = new LeonSans({
text: 'mug',
color: [
['#64d3ce', '#2a92ce'],
['#e7c4c4', '#aae898', '#e1ea73', '#ff8974'],
['#fd46aa', '#8ad781']
],
size: getSize(500),
weight: 140
});
const gui = new dat.GUI();
gui.add(leon, 'text');
gui.add(leon, 'size', 20, 1000);
gui.add(leon, 'weight', 1, 900);
gui.add(controll, 'drawing');
gui.add(controll, 'box');
gui.add(controll, 'grids');
gui.add(controll, 'points');
requestAnimationFrame(animate);
}
function animate(t) {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, sw, sh);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x + moveX, y + moveY);
ctx.save();
if (controll.grids) leon.grid(ctx);
if (controll.box) leon.box(ctx);
ctx.restore();
ctx.save();
leon.draw(ctx);
ctx.restore();
if (controll.points) {
ctx.save();
leon.point(ctx);
ctx.restore();
}
}
window.onload = () => {
init();
};
</script>
</body>
</html>

94
examples/grid.html

@ -1,94 +0,0 @@ @@ -1,94 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>Leon Sans - Grids</title>
<style>
html, body {
width: 100%;
height: 100%;
overflow: hidden;
outline: 0;
margin: 0;
padding: 0;
background-color: #f0f0f0;
cursor: move;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>
<body>
<script src="../dist/leon.js"></script>
<script src="js/util.js"></script>
<script>
let leon, controll;
function init() {
generateCanvas();
controll = {
box: true,
grids: true,
points: true,
};
leon = new LeonSans({
text: 'Ttypog',
color: ['#342f2e'],
size: getSize(300),
weight: 400
});
const gui = new dat.GUI();
gui.add(leon, 'text');
gui.add(leon, 'size', 100, 1000);
gui.add(leon, 'weight', 1, 900);
gui.add(leon, 'tracking', -3, 10);
gui.add(leon, 'leading', -8, 10);
gui.add(controll, 'box');
gui.add(controll, 'grids');
gui.add(controll, 'points');
requestAnimationFrame(animate);
}
function animate(t) {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, sw, sh);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x + moveX, y + moveY);
ctx.save();
if (controll.grids) leon.grid(ctx);
if (controll.box) leon.box(ctx);
ctx.restore();
ctx.save();
leon.draw(ctx);
ctx.restore();
if (controll.points) {
ctx.save();
leon.point(ctx);
ctx.restore();
}
}
window.onload = () => {
init();
};
</script>
</body>
</html>

267
examples/index.html

@ -1,267 +0,0 @@ @@ -1,267 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>Leon Sans examples</title>
<style>
html,
body {
outline: 0;
margin: 0;
padding: 0;
height: 100%;
color: #ffffff;
font-size: 14px;
line-height: 30px;
-webkit-text-size-adjust: 100%;
font-family: 'Helvetica', sans-serif;
font-weight: 400;
}
#menu-m {
position: fixed;
z-index: 4;
width: 60px;
height: 56px;
left: 0;
top: 0;
background-color: #222222;
cursor: pointer;
}
#menu-m > p {
display: block;
width: 30px;
height: 2px;
background-color: #ffffff;
position: absolute;
left: 15px;
}
#menu-m > p:nth-child(1) {
top: 5px;
}
#menu-m > p:nth-child(2) {
top: 12px;
}
#menu-m > p:nth-child(3) {
top: 19px;
}
#menu-bg {
position: fixed;
z-index: 2;
width: 100%;
height: 100%;
left: 0;
top: 0;
background-color:rgba(0,0,0,0.3);
display: none;
}
#menu {
position: fixed;
z-index: 6;
left: 0px;
width: 170px;
height: 100%;
overflow-y: auto;
overflow-x: hidden;
background-color: #222222;
}
#menu.show {
transform: translate(170px, 0);
}
#header {
margin: 0;
}
#version {
font-size: 9px;
line-height: 9px;
color: rgba(255,255,255,0.5);
padding: 0 0 0 20px;
}
#list {
margin: -10px 0 20px 0;
}
h2 {
font-size: 18px;
font-weight: 400;
margin: 40px 0 6px 0;
padding: 0 0 0 20px;
}
h2 > a {
font-size: 12px;
}
.item {
padding: 0 0 0 20px;
display: block;
}
.item:hover {
opacity: 1;
background-color: #000;
}
.item.selected {
opacity: 1;
background-color: #000;
}
a {
color: #ffffff;
opacity: 0.6;
text-decoration: none;
}
#iframe {
position: absolute;
border: 0px;
right: 0;
right: 0;
width: calc(100% - 170px);
height: 100%;
overflow: auto;
}
@media (max-width: 600px) {
#iframe {
width: 100%;
}
#menu {
left: -170px;
}
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="../dist/leon.js"></script>
</head>
<body>
<div id="menu-m">
<p></p>
<p></p>
<p></p>
</div>
<div id="menu-bg"></div>
<div id="menu">
<canvas id="header"></canvas>
<div id="version">VERSION 1.5</div>
<div id="list">
<h2>Canvas</h2>
<a class="item" href="all.html" target="iframe">all</a>
<a class="item" href="canvas-basic.html" target="iframe">basic</a>
<a class="item" href="gradient.html" target="iframe">gradient</a>
<a class="item" href="grid.html" target="iframe">grid</a>
<a class="item" href="pattern.html" target="iframe">pattern</a>
<a class="item" href="wave.html" target="iframe">wave</a>
<a class="item" href="colorful.html" target="iframe">colorful</a>
<a class="item" href="color-pattern.html" target="iframe">color pattern</a>
<h2>WebGL <a href="https://www.pixijs.com/" target="_blank">(PIXI.js)</a></h2>
<a class="item" href="webgl-basic-pixi.html" target="iframe">basic</a>
<a class="item" href="metaball-pixi.html" target="iframe">metaball</a>
<a class="item" href="morphing-pixi.html" target="iframe">morphing</a>
<a class="item" href="plants-pixi.html" target="iframe">plants</a>
<a class="item" href="mask-tiling-pixi.html" target="iframe">mask + tiling</a>
</div>
</div>
<iframe id="iframe" name="iframe" allowfullscreen="" allowvr="" onmousewheel=""></iframe>
<script>
window.onload = () => {
let isShow = false;
const menuM = document.getElementById('menu-m');
const menuBg = document.getElementById('menu-bg');
const menu = document.getElementById('menu');
menuM.addEventListener( 'click', (event) => {
onClickMenu();
});
menuBg.addEventListener( 'click', (event) => {
onClickMenu();
});
function onClickMenu() {
isShow = !isShow;
if (isShow) {
menuBg.style.display = 'block';
menu.className = 'show';
} else {
menuBg.style.display = 'none';
menu.className = '';
}
}
const sw = 170;
const sh = 50;
const iframe = document.getElementById('iframe');
const canvas = document.getElementById('header');
const ctx = canvas.getContext("2d");
canvas.width = sw * 2;
canvas.height = sh * 2;
canvas.style.width = sw + 'px'
canvas.style.height = sh + 'px'
ctx.scale(2, 2);
const leon = new LeonSans({
text: 'Leon Sans',
color: ['#ffffff'],
size: 26,
weight: 300
});
leon.on('update', (model) => {
ctx.clearRect(0, 0, sw, sh);
leon.position(20, 20);
leon.draw(ctx);
});
const list = document.getElementById('list');
const arr = list.getElementsByClassName('item');
const total = arr.length;
const links = {};
let cur = null;
let i;
for (i = 0; i < total; i++) {
const vv = arr[i].href.split('/');
const name = vv[vv.length - 1].split('.')[0];
links[name] = arr[i];
arr[i].addEventListener( 'click', (event) => {
const vv = event.target.href.split('/');
const name = vv[vv.length - 1].split('.')[0];
checkMenu(name);
});
}
if (window.location.hash !== '') {
const name = window.location.hash.substring(1);
const url = name + '.html';
iframe.src = url;
checkMenu(name);
} else {
const name = 'all';
iframe.src = name + '.html';
checkMenu(name);
}
function checkMenu(name) {
if (cur) links[cur].classList.remove('selected');
cur = name;
links[cur].classList.add('selected');
window.location.hash = name;
iframe.focus();
};
};
</script>
</body>
</html>

199
examples/mask-tiling-pixi.html

@ -1,199 +0,0 @@ @@ -1,199 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>Leon Sans - MASK + Tiling PIXI</title>
<style>
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
outline: 0;
margin: 0;
padding: 0;
cursor: move;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.4/pixi.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>
<body>
<script src="../dist/leon.js"></script>
<script src="js/util.js"></script>
<script>
let container, loader, textures = [];
let tiling = [], cur = -1;
let leon, controll;
function init() {
generatePixi(0x000000);
container = new PIXI.Container();
stage.addChild(container);
loader = new PIXI.Loader();
loader.add('tile1', 'data/tile1.png')
.add('tile2', 'data/tile2.png')
.add('tile3', 'data/tile3.png')
.add('tile4', 'data/tile4.png')
.add('tile5', 'data/tile5.png')
.add('tile6', 'data/tile6.png');
loader.load((loader, resources) => {
textures.push(resources.tile1.texture);
textures.push(resources.tile2.texture);
textures.push(resources.tile3.texture);
textures.push(resources.tile4.texture);
textures.push(resources.tile5.texture);
textures.push(resources.tile6.texture);
textures = shuffle(textures);
loaded();
});
}
function loaded() {
controll = {
align: {},
};
leon = new LeonSans({
text: '012\n345',
size: getSize(400),
weight: 900,
tracking: 1,
leading: -1,
align: 'center'
});
leon.on('update', (model) => {
update();
});
const gui = new dat.GUI();
gui.add(leon, 'text');
gui.add(leon, 'size', 10, 1000);
gui.add(leon, 'weight', 1, 900);
requestAnimationFrame(animate);
}
function update() {
while(container.children[0]) {
container.removeChild(container.children[0]);
}
const total = leon.data.length;
let i, d, color, line, pos;
let j, j_total, lineW = leon.lineWidth;
let graphics, tilingSprite;
tiling = [];
for (i = 0; i < total; i++) {
d = leon.data[i];
graphics = new PIXI.Graphics();
container.addChild(graphics);
tilingSprite = new PIXI.TilingSprite(
textures[getNum()],
d.rect.w * 2,
d.rect.h * 2
);
tilingSprite.x = d.rect.x - d.rect.w /2;
tilingSprite.y = d.rect.y - d.rect.h / 2;
tilingSprite.tileScale.x = tilingSprite.tileScale.y = leon.scale * 0.5;
container.addChild(tilingSprite);
tilingSprite.mask = graphics;
tiling.push({
item: tilingSprite,
x: (Math.random() * 2 + 1 - 2) * 2,
y: (Math.random() * 2 + 1 - 2) * 2
});
j_total = d.lines.length;
for (j = 0; j < j_total; j++) {
line = d.lines[j];
pos = d.lines[j].pos;
if (pos.type == 'a') {
graphics.lineStyle(0, color, 0);
graphics.beginFill(color);
graphics.drawCircle(pos.x, pos.y, pos.radius);
graphics.endFill();
} else if (pos.type == 'm') {
graphics.lineStyle(lineW, color, 1);
graphics.moveTo(pos.x, pos.y);
} else if (pos.type == 'l') {
graphics.lineTo(pos.x, pos.y);
} else if (pos.type == 'b') {
graphics.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);
}
if (line.closePath) {
graphics.closePath();
}
}
}
}
function animate(t) {
requestAnimationFrame(animate);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x + moveX, y + moveY);
const total = tiling.length;
let i, p;
for (i = 0; i < total; i++) {
p = tiling[i];
p.item.tilePosition.x += p.x * leon.scale;
p.item.tilePosition.y += p.y * leon.scale;
}
renderer.render(stage);
}
function getNum() {
cur += 1;
if (cur == textures.length) {
cur = 0;
}
return cur;
}
function shuffle(oldArray) {
var newArray = oldArray.slice(),
len = newArray.length,
i = len, p, t;
while (i--) {
p = (Math.random()*len) | 0;
t = newArray[i];
newArray[i] = newArray[p];
newArray[p] = t;
}
return newArray;
}
window.onload = () => {
init();
};
</script>
</body>
</html>

230
examples/metaball-pixi.html

@ -1,230 +0,0 @@ @@ -1,230 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>Leon Sans - Metaball PIXI</title>
<style>
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
outline: 0;
margin: 0;
padding: 0;
cursor: move;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.4/pixi.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>
<body>
<script src="../dist/leon.js"></script>
<script src="js/util.js"></script>
<script>
let container, texture, particleCon;
let leon, controll, weightControll;
const particleTotal = 10000;
let particles = [];
function init() {
generatePixi(0x000000);
texture = PIXI.Texture.from('data/drop-alpha.png');
particleCon = new PIXI.ParticleContainer(particleTotal, {
vertices: false,
scale: true,
position: true,
rotation: false,
uvs: false,
alpha: false
});
stage.addChild(particleCon);
let p, i;
for (i = 0; i < particleTotal; i++) {
p = new PIXI.Sprite(texture);
p.x = sw / 2;
p.y = sh / 2;
p.anchor.set(0.5);
p.scale.x = p.scale.y = 0;
particleCon.addChild(p);
particles.push(p);
}
const blurFilter = new PIXI.filters.BlurFilter();
blurFilter.blur = 10;
blurFilter.autoFit = true;
const fragSource = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
'uniform sampler2D uSampler;',
'uniform float threshold;',
'uniform float mr;',
'uniform float mg;',
'uniform float mb;',
'void main(void)',
'{',
' vec4 color = texture2D(uSampler, vTextureCoord);',
' vec3 mcolor = vec3(mr, mg, mb);',
' if (color.a > threshold) {',
' gl_FragColor = vec4(mcolor, 1.0);',
' } else {',
' gl_FragColor = vec4(vec3(0.0), 0.0);',
' }',
'}'
].join('\n');
const uniformsData = {
threshold: 0.5,
mr: 255.0/255.0,
mg: 255.0/255.0,
mb: 255.0/255.0,
};
const thresholdFilter = new PIXI.Filter(null, fragSource, uniformsData);
stage.filters = [blurFilter, thresholdFilter];
stage.filterArea = renderer.screen;
controll = {
weight: 3,
color: {},
outline: true,
drawing: () => {
let i;
for (i = 0; i < particleTotal; i++) {
TweenMax.killTweensOf(particles[i].scale);
TweenMax.set(particles[i].scale, {
x: 0,
y: 0
});
TweenMax.to(particles[i].scale, 3, {
delay: 0.001 * i,
x: particles[i].saveScale,
y: particles[i].saveScale,
ease: Circ.easeOut
});
}
}
};
leon = new LeonSans({
text: 'TOP\n678',
size: getSize(400),
weight: 700,
pathGap: -1,
isPath: true,
tracking: 0
});
leon.on('update', (model) => {
update();
});
const gui = new dat.GUI();
gui.add(leon, 'text');
const sizeControll = gui.add(leon, 'size', 200, 1000);
gui.add(leon, 'tracking', -6, 10);
gui.add(leon, 'leading', -8, 10);
weightControll = gui.add(controll, 'weight', 1, 9);
gui.add(controll, 'drawing');
const colorControll = gui.add(controll, 'color', [ 'white', 'black', 'red'] );
sizeControll.onChange((value) => {
sizeWeight();
});
weightControll.onChange((value) => {
update();
});
colorControll.onChange((value) => {
if (value == 'white') {
renderer.backgroundColor = 0x000000;
uniformsData.mr = 255.0/255.0;
uniformsData.mg = 255.0/255.0;
uniformsData.mb = 255.0/255.0;
} else if (value == 'black') {
renderer.backgroundColor = 0xffffff;
uniformsData.mr = 0.0/255.0;
uniformsData.mg = 0.0/255.0;
uniformsData.mb = 0.0/255.0;
} else if (value == 'red') {
renderer.backgroundColor = 0xe4c143;
uniformsData.mr = 244.0/255.0;
uniformsData.mg = 46.0/255.0;
uniformsData.mb = 33.0/255.0;
}
});
colorControll.setValue('white');
requestAnimationFrame(animate);
sizeWeight();
TweenMax.delayedCall(0.1, () => {
controll.drawing();
});
}
function sizeWeight() {
let w;
if (leon.size > 400) {
w = (1.5 - 3) / (1000 - 400) * (leon.size - 400) + 3;
} else {
w = (3 - 6) / (400 - 200) * (leon.size - 200) + 6;
}
weightControll.setValue(w);
}
function update() {
const total = leon.paths.length;
const sw2 = sw / 2;
const sh2 = sh / 2;
let i, p, pos, scale;
for (i = 0; i < particleTotal; i++) {
p = particles[i];
TweenMax.killTweensOf(p.scale);
if (i < total) {
pos = leon.paths[i];
if (pos.type == 'a') {
scale = controll.weight * 0.025* leon.scale;
} else {
scale = controll.weight * 0.01* leon.scale;
}
p.saveScale = scale;
p.x = pos.x;
p.y = pos.y;
p.scale.x = p.scale.y = scale;
} else {
p.saveScale = 0;
p.x = -1000;
p.y = -1000;
p.scale.x = p.scale.y = 0;
}
}
}
function animate(t) {
requestAnimationFrame(animate);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x + moveX, y + moveY);
renderer.render(stage);
}
window.onload = () => {
init();
};
</script>
</body>
</html>

232
examples/morphing-pixi.html

@ -1,232 +0,0 @@ @@ -1,232 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>Leon Sans - Morphing PIXI</title>
<style>
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
outline: 0;
margin: 0;
padding: 0;
cursor: move;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.4/pixi.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/pixi-filters@latest/dist/pixi-filters.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>
<body>
<script src="../dist/leon.js"></script>
<script src="js/util.js"></script>
<script>
let container, texture, particleCon;
let leon, controll;
const particleTotal = 5000;
let particles = [];
let myText = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789?!$^&*(){}[]<>~:;,.\'"+=-_@#%'.split('');
const textTotal = myText.length;
let curText = -1;
let DELAY_TIME = 0.8;
function init() {
generatePixi(0xfec82e);
myText = shuffle(myText);
texture = PIXI.Texture.from('data/drop-alpha.png');
particleCon = new PIXI.ParticleContainer(particleTotal, {
vertices: false,
scale: true,
position: true,
rotation: false,
uvs: false,
alpha: false
});
stage.addChild(particleCon);
let p, i;
for (i = 0; i < particleTotal; i++) {
p = new PIXI.Sprite(texture);
p.x = sw / 2;
p.y = sh / 2;
p.anchor.set(0.5);
p.scale.x = p.scale.y = 0;
particleCon.addChild(p);
particles.push(p);
}
const blurFilter = new PIXI.filters.BlurFilter();
blurFilter.blur = 10;
blurFilter.autoFit = true;
const fragSource = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
'uniform sampler2D uSampler;',
'uniform float threshold;',
'uniform float mr;',
'uniform float mg;',
'uniform float mb;',
'void main(void)',
'{',
' vec4 color = texture2D(uSampler, vTextureCoord);',
' vec3 mcolor = vec3(mr, mg, mb);',
' if (color.a > threshold) {',
' gl_FragColor = vec4(mcolor, 1.0);',
' } else {',
' gl_FragColor = vec4(vec3(0.0), 0.0);',
' }',
'}'
].join('\n');
const uniformsData = {
threshold: 0.5,
mr: 255.0/255.0,
mg: 255.0/255.0,
mb: 255.0/255.0,
};
const thresholdFilter = new PIXI.Filter(null, fragSource, uniformsData );
const outlineFilterBlue = new PIXI.filters.OutlineFilter(1, 0x000000);
stage.filters = [blurFilter, thresholdFilter, outlineFilterBlue];
stage.filterArea = renderer.screen;
controll = {
weight: 6,
outline: true
};
leon = new LeonSans({
text: '',
size: 600,
weight: 700,
pathGap: -1,
isPath: true
});
leon.on('update', (data) => {
update(data);
});
const gui = new dat.GUI();
gui.add(leon, 'size', 400, 1000);
gui.add(controll, 'weight', 3, 9);
const otControll = gui.add(controll, 'outline');
otControll.onChange((value) => {
if (value) {
stage.filters = [blurFilter, thresholdFilter, outlineFilterBlue];
} else {
stage.filters = [blurFilter, thresholdFilter];
}
});
requestAnimationFrame(animate);
showText();
}
function nextText() {
TweenMax.killDelayedCallsTo(showText);
TweenMax.delayedCall(DELAY_TIME, showText);
}
function showText() {
curText += 1;
if (curText == textTotal) curText = 0;
leon.text = myText[curText];
nextText();
}
function shuffle(oldArray) {
var newArray = oldArray.slice(),
len = newArray.length,
i = len, p, t;
while (i--) {
p = (Math.random()*len) | 0;
t = newArray[i];
newArray[i] = newArray[p];
newArray[p] = t;
}
return newArray;
}
function update(model) {
const total = model.paths.length;
const sw2 = sw / 2;
const sh2 = sh / 2;
let i, p, pos, scale;
for (i = 0; i < particleTotal; i++) {
p = particles[i];
TweenMax.killTweensOf(p);
if (i < total) {
pos = model.paths[i];
if (pos.type == 'a') {
scale = controll.weight * 0.02* leon.scale;
} else {
scale = controll.weight * 0.01* leon.scale;
}
TweenMax.to(p, 0.4, {
x: sw2,
y: sh2,
ease: Sine.easeIn
});
TweenMax.to(p, 0.5, {
delay: 0.3,
x: pos.x,
y: pos.y,
ease: Expo.easeOut
});
TweenMax.to(p.scale, 0.5, {
delay: 0.3,
x: scale,
y: scale,
ease: Expo.easeOut
});
} else {
TweenMax.to(p, 0.3, {
x: sw2,
y: sh2,
ease: Sine.easeIn
});
TweenMax.to(p.scale, 0.3, {
x: 0,
y: 0,
ease: Sine.easeIn
});
}
}
}
function animate(t) {
requestAnimationFrame(animate);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x, y);
renderer.render(stage);
}
window.onload = () => {
init();
};
</script>
</body>
</html>

94
examples/pattern.html

@ -1,94 +0,0 @@ @@ -1,94 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>Leon Sans - Pattern</title>
<style>
html, body {
width: 100%;
height: 100%;
overflow: hidden;
outline: 0;
margin: 0;
padding: 0;
background-color: #502c8d;
cursor: move;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>
<body>
<script src="../dist/leon.js"></script>
<script src="js/util.js"></script>
<script>
let leon, controll;
function init() {
generateCanvas();
controll = {
color: {},
align: {},
patternWidth: 40,
patternHeight: 10,
drawing: () => {
let i, total = leon.drawing.length;
for (i = 0; i < total; i++) {
TweenMax.killTweensOf(leon.drawing[i]);
TweenMax.fromTo(leon.drawing[i], 2, {
value: 0
}, {
delay: i * 0.05,
value: 1,
ease: Power4.easeOut
});
}
}
};
leon = new LeonSans({
text: 'The quick brown\nfox jumps over\nthe lazy dog',
size: getSize(120),
weight: 400,
isPath: true,
pathGap: 0.2
});
const gui = new dat.GUI();
gui.add(leon, 'text');
gui.add(leon, 'size', 20, 300);
gui.add(leon, 'pathGap', 0, 1);
gui.add(controll, 'patternWidth', 1, 200);
gui.add(controll, 'patternHeight', 1, 100);
gui.add(controll, 'drawing');
requestAnimationFrame(animate);
}
function animate(t) {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, sw, sh);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x + moveX, y + moveY);
leon.pattern(ctx, controll.patternWidth, controll.patternHeight);
}
window.onload = () => {
init();
};
</script>
</body>
</html>

227
examples/plants-pixi.html

@ -1,227 +0,0 @@ @@ -1,227 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>Leon Sans - Plants PIXI</title>
<style>
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
outline: 0;
margin: 0;
padding: 0;
cursor: move;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.4/pixi.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>
<body>
<script src="../dist/leon.js"></script>
<script src="js/util.js"></script>
<script>
let container, loader, resource;
let leafs = [], flowers = [];
let leon, controll;
const tintLeaf = [
0xFFFFFF,
0xFFFF00,
0xccff00,
0x00ff1e,
0xffb300,
0xa2ff00
];
const tintFlower = [
0xFFFFFF,
0xffeea1,
0xffa1a1,
0xeca1ff,
0xa1dbff,
0xffa1d6,
0xd2ffa1,
];
function init() {
generatePixi(0xf0f0f0);
container = new PIXI.Container();
stage.addChild(container);
loader = new PIXI.Loader();
loader.add('branch_long', 'data/branch_long.png')
.add('branch_circle', 'data/branch_circle.png')
.add('flower1', 'data/flower1.png')
.add('flower2', 'data/flower2.png')
.add('flower3', 'data/flower3.png')
.add('leaf1', 'data/leaf1.png')
.add('leaf2', 'data/leaf2.png');
loader.load((loader, resources) => {
resource = resources;
flowers.push('flower1');
flowers.push('flower2');
flowers.push('flower3');
leafs.push('leaf1');
leafs.push('leaf1');
leafs.push('leaf2');
loaded();
});
}
function loaded() {
controll = {
color: {},
};
leon = new LeonSans({
text: 'ONE',
size: getSize(500),
weight: 1,
pathGap: -1,
tracking: 0,
isPath: true
});
leon.on('update', (data) => {
update(data);
});
const gui = new dat.GUI();
gui.add(leon, 'text');
gui.add(leon, 'tracking', -3, 10);
window.addEventListener('resize', resize, false);
requestAnimationFrame(animate);
}
function resize() {
sw = document.body.clientWidth;
sh = document.body.clientHeight;
renderer.resize(sw, sh);
}
function update() {
while(container.children[0]) {
TweenMax.killTweensOf(container.children[0]);
container.removeChild(container.children[0]);
}
let points, saveFlowers = [], saveLeafs = [];
let total = leon.model.data.length;
let i, j, j_total, d, pos;
for (i = 0; i < total; i++) {
d = leon.model.data[i];
j_total = d.paths.length;
points = [];
for (j = 0; j < j_total; j++) {
pos = d.paths[j];
if (pos.type == 'a') {
const dot = new PIXI.Sprite(resource.branch_circle.texture);
dot.anchor.set(0.5);
dot.x = pos.x;
dot.y = pos.y;
const scale = 0.15 * leon.scale;
dot.scale.x = dot.scale.y = scale;
container.addChild(dot);
} else if (pos.start == 1) {
if (points.length > 0) {
addBranch(points);
}
points = [];
points.push(new PIXI.Point(pos.x, pos.y));
} else {
points.push(new PIXI.Point(pos.x, pos.y));
}
if (Math.random() > 0.99) {
saveFlowers.push(pos);
}
if (Math.random() > 0.84) {
saveLeafs.push(pos);
}
}
if (points.length > 0) {
addBranch(points);
}
}
function addBranch(points) {
const branch = new PIXI.SimpleRope(resource.branch_long.texture, points);
container.addChild(branch);
}
total = saveLeafs.length;
for (i = 0; i < total; i++) {
pos = saveLeafs[i];
d = leafs[Math.floor(0.5 + (Math.random()*(leafs.length-1)))];
const leaf = new PIXI.Sprite(resource[d].texture);
leaf.anchor.set(0.5, 1);
leaf.x = pos.x;
leaf.y = pos.y;
const scale = 0.1 * (0.2 + Math.random() * (1.2 - 0.2)) * leon.scale;
leaf.scale.x = leaf.scale.y = 0;
leaf.rotation = (pos.rotation + (90 * (Math.PI / 180)) * (Math.random() > 0.5 ? 1 : -1)) + (Math.random() * (Math.PI / 2) - (Math.PI / 4));
container.addChild(leaf);
leaf.tint = tintLeaf[Math.floor(0.5 + (Math.random()*(tintLeaf.length-1)))];
TweenMax.to(leaf.scale, 0.8, {
delay: 0.004 * i,
x: scale,
y: scale,
ease: Power3.easeOut
});
}
total = saveFlowers.length;
for (i = 0; i < total; i++) {
pos = saveFlowers[i];
d = flowers[Math.floor(0.5 + (Math.random()*(flowers.length-1)))];
const flower = new PIXI.Sprite(resource[d].texture);
flower.anchor.set(0.5);
flower.x = pos.x;
flower.y = pos.y;
const scale = 0.04 * (0.6 + Math.random() * (1.2 - 0.6)) * leon.scale;
flower.scale.x = flower.scale.y = 0;
flower.rotation = Math.random() * Math.PI * 2;
container.addChild(flower);
flower.tint = tintFlower[Math.floor(0.5 + (Math.random()*(tintFlower.length-1)))];
TweenMax.to(flower.scale, 0.8, {
delay: 0.05 * i + 0.6,
x: scale,
y: scale,
ease: Power3.easeOut
});
}
}
function animate(t) {
requestAnimationFrame(animate);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x + moveX, y + moveY);
renderer.render(stage);
}
window.onload = () => {
init();
};
</script>
</body>
</html>

82
examples/wave.html

@ -1,82 +0,0 @@ @@ -1,82 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>Leon Sans - Wave</title>
<style>
html, body {
width: 100%;
height: 100%;
overflow: hidden;
outline: 0;
margin: 0;
padding: 0;
background-color: #000000;
cursor: move;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>
<body>
<script src="../dist/leon.js"></script>
<script src="js/util.js"></script>
<script>
let leon, controll;
function init() {
generateCanvas();
const controll = {
color: {},
align: {},
};
leon = new LeonSans({
text: 'The quick brown\nfox jumps over\nthe lazy dog',
color: ['#ffffff'],
size: getSize(120),
weight: 1,
isWave: true,
pathGap: 0.3,
amplitude: 0.5,
fps: 30
});
const gui = new dat.GUI();
gui.add(leon, 'text');
gui.add(leon, 'size', 20, 300);
gui.add(leon, 'weight', 1, 300);
gui.add(leon, 'pathGap', 0, 1);
gui.add(leon, 'amplitude', 0, 1);
gui.add(leon, 'fps', 10, 60);
requestAnimationFrame(animate);
}
function animate(t) {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, sw, sh);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x + moveX, y + moveY);
leon.wave(ctx, t);
}
window.onload = () => {
init();
};
</script>
</body>
</html>

124
examples/webgl-basic-pixi.html

@ -1,124 +0,0 @@ @@ -1,124 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>Leon Sans - WebGL Basic PIXI</title>
<style>
html, body {
width: 100%;
height: 100%;
overflow: hidden;
outline: 0;
margin: 0;
padding: 0;
cursor: move;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.4/pixi.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>
<body>
<script src="../dist/leon.js"></script>
<script src="js/util.js"></script>
<script>
let graphics;
let leon, controll;
function init() {
generatePixi(0x000000);
graphics = new PIXI.Graphics();
stage.addChild(graphics);
controll = {
color: {},
align: {},
drawing: () => {
leon.updateDrawingPaths();
let i, total = leon.drawing.length;
for (i = 0; i < total; i++) {
TweenMax.killTweensOf(leon.drawing[i]);
TweenMax.fromTo(leon.drawing[i], 1.6, {
value: 0
}, {
delay: i * 0.05,
value: 1,
ease: Power4.easeOut
});
}
},
};
leon = new LeonSans({
text: 'The quick brown\nfox jumps over\nthe lazy dog',
color: [0xffffff],
size: getSize(120),
weight: 300
});
const gui = new dat.GUI();
gui.add(leon, 'text');
gui.add(leon, 'size', 10, 2000);
gui.add(leon, 'weight', 1, 900);
gui.add(leon, 'tracking', -3, 10);
gui.add(leon, 'leading', -8, 10);
const alignControll = gui.add(controll, 'align', [ 'left', 'center', 'right'] );
gui.add(leon, 'maxWidth', 0, 2000);
gui.add(leon, 'breakWord');
gui.add(controll, 'drawing');
const colorControll = gui.add(controll, 'color', [ 'black', 'white', 'yellow' , 'mixed'] );
alignControll.onChange((value) => {
leon.align = value;
});
alignControll.setValue('left');
colorControll.onChange((value) => {
if (value == 'black') {
renderer.backgroundColor = 0xf0f0f0;
leon.color = [0x342f2e];
} else if (value == 'white') {
renderer.backgroundColor = 0x000000;
leon.color = [0xffffff];
} else if (value == 'yellow') {
renderer.backgroundColor = 0x57c4e2;
leon.color = [0xffd93c];
} else if (value == 'mixed') {
document.body.style.backgroundColor = '#ffffff';
leon.color = [0xff5892, 0xbc92f, 0xffd93c, 0xc0008b];
}
});
colorControll.setValue('white');
requestAnimationFrame(animate);
}
function animate(t) {
requestAnimationFrame(animate);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x + moveX, y + moveY);
graphics.clear();
leon.drawPixi(graphics);
renderer.render(stage);
}
window.onload = () => {
init();
};
</script>
</body>
</html>

BIN
screenshot/latin-lower.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 962 KiB

BIN
screenshot/latin-upper.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 948 KiB

BIN
screenshot/latin2.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

BIN
screenshot/lower.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 KiB

BIN
screenshot/lowercase.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 KiB

BIN
screenshot/number-special.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 KiB

BIN
screenshot/number.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 651 KiB

BIN
screenshot/upper.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 KiB

BIN
screenshot/uppercase.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 525 KiB

17
src/core/align.js

@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
export function setAlignGapX(sw, tw) {
return {
c: (sw - tw) / 2,
r: sw - tw,
l: 0
};
}
export function getAlignGapX(align, alignGapX) {
if (align == 'center') {
return alignGapX.c;
} else if (align == 'right') {
return alignGapX.r;
} else {
return alignGapX.l;
}
}

46
src/core/dispatcher.js

@ -1,46 +0,0 @@ @@ -1,46 +0,0 @@
export class Dispatcher {
constructor() {
this.handlers_ = {
update: {
listeners: []
}
};
}
on(event, callback) {
if (typeof callback !== 'function') {
console.error(`The listener callback must be a function, the given type is ${typeof callback}`);
return false;
}
if (typeof event !== 'string') {
console.error(`The event name must be a string, the given type is ${typeof event}`);
return false;
}
if (this.handlers_[event] === undefined) {
this.handlers_[event] = {
listeners: []
};
}
this.handlers_[event].listeners.push(callback);
}
off(event, callback) {
if (this.handlers_[event] === undefined) {
console.error(`This event: ${event} does not exist`);
return false;
}
this.handlers_[event].listeners = this.handlers_[event].listeners.filter(listener => {
return listener.toString() !== callback.toString();
});
}
dispatch(event, data) {
this.handlers_[event].listeners.forEach((listener) => {
listener(data);
});
}
}

125
src/core/group.js

@ -1,125 +0,0 @@ @@ -1,125 +0,0 @@
import {
getRect
} from './util.js';
import {
typo
} from '../font/index.js';
export function getTextGroup(text, scale, width, isBreakAll) {
let group;
if (text.indexOf('\n') > 0) {
group = text.split('\n');
} else if (text.indexOf('\\n') > 0) {
group = text.split('\\n');
} else {
group = [text];
}
if (width == 0) return keepAll(group);
else if (isBreakAll) return breakAll(group, scale, width);
else return breakWord(group, scale, width);
}
function keepAll(group) {
const textGroup = [];
const total = group.length;
let i;
for (i = 0; i < total; i++) {
textGroup[i] = group[i].split('');
}
return textGroup;
}
function breakWord(group, scale, width) {
let g2, g3, t, m_rect,
tw = 0,
tw2 = 0,
i, j, k,
total, j_total, k_total,
index = 0;
const tg = [];
total = group.length;
for (i = 0; i < total; i++) {
g2 = group[i].split(' ');
tg[index] = [];
j_total = g2.length;
for (j = 0; j < j_total; j++) {
tw2 = 0;
g3 = g2[j];
k_total = g3.length;
for (k = 0; k < k_total; k++) {
t = typo(g3[k]);
m_rect = getRect(t, scale);
tw2 += m_rect.w;
}
t = typo(' ');
m_rect = getRect(t, scale);
tw2 += m_rect.w;
tw += tw2;
if (tw > width) {
index += 1;
tw = tw2;
tg[index] = [];
}
tg[index].push(g3);
}
index += 1;
tw = 0;
}
total = tg.length;
const textGroup = [];
for (i = 0; i < total; i++) {
t = tg[i].join(' ').split('');
if (t.length > 0) {
textGroup.push(t);
}
}
return textGroup;
}
function breakAll(group, scale, width) {
let t,
i, total,
j, j_total,
m_rect,
g2, g3,
tw = 0,
index = 0,
tx = 0;
const tg = [];
total = group.length;
for (i = 0; i < total; i++) {
g2 = group[i];
tw = 0;
tx = 0;
tg[index] = [];
j_total = g2.length;
for (j = 0; j < j_total; j++) {
g3 = g2[j];
t = typo(g3);
m_rect = getRect(t, scale);
tw += m_rect.w;
tg[index].push(g3);
if (tw >= width) {
index += 1;
tw = m_rect.w;
tg[index] = [];
}
}
index += 1;
}
const textGroup = [];
total = tg.length;
for (i = 0; i < total; i++) {
t = tg[i];
if (t.length > 0) {
if (t[0] == ' ') t.shift();
if (t[t.length - 1] == ' ') t.pop();
if (t.length > 0) textGroup.push(t);
}
}
return textGroup;
}

45
src/core/guide.js

@ -1,45 +0,0 @@ @@ -1,45 +0,0 @@
import {
RECT_RATIO
} from './util.js';
/**
* @name getGuide
* @property {Object} - typo data object from 'font/index.js'
* @property {Number} - scale
* @returns {Object} the guide pos array
* @description get a guide pos
*/
export function getGuide(d, scale) {
let guide = [],
ggap = 10,
i, gvx, gvy;
for (i = 0; i < 6; i++) {
gvx = (ggap * i) + 20;
gvy = (ggap * i) + 90;
guide[i] = {
x1: (gvx * RECT_RATIO) * scale,
x2: ((d.rect.w - (gvx * 2)) * RECT_RATIO) * scale,
y1: (gvy * RECT_RATIO) * scale,
y2: (((d.rect.h - gvy) * RECT_RATIO) * scale) - ((i * ggap * RECT_RATIO) * scale),
};
}
return guide;
}
/**
* @name getGuide
* @property {Object} - typo data object from 'font/index.js'
* @property {Number} - scale
* @returns {Object} the guide pos array
* @description get a guide pos
*/
export function getGrid(d, scale) {
let grid = [],
i, gvy = [98, 340, 815];
for (i = 0; i < 3; i++) {
grid[i] = (gvy[i] * RECT_RATIO) * scale;
}
return grid;
}

123
src/core/length.js

@ -1,123 +0,0 @@ @@ -1,123 +0,0 @@
export function getLengths(item, model) {
const total = item.typo.p.length;
let c, p,
arr = [],
lt = [],
max = 0,
i;
for (i = 0; i < total; i++) {
p = item.typo.p[i];
c = getEachPath(item, p.v, model);
max += c.l;
arr.push(c.v);
lt.push(c.l);
}
return {
max: max,
lines: arr,
lengths: lt
};
}
function getEachPath(item, points, model) {
const total = points.length;
let i, p,
line, cp1, cp2, prev,
lines = [],
length = 0;
for (i = 0; i < total; i++) {
p = points[i];
line = {};
cp2 = p.convert(item, model);
if (i == 0 || p.type == 'a') {
line.x1 = cp2.x;
line.y1 = cp2.y;
line.distance = 0;
line.radius = cp2.radius;
} else {
cp1 = prev.convert(item, model);
if (prev.type == 'b') {
line.x1 = cp1.x3;
line.y1 = cp1.y3;
} else {
line.x1 = cp1.x;
line.y1 = cp1.y;
}
line.x2 = cp2.x;
line.y2 = cp2.y;
if (p.type == 'b') {
line.x3 = cp2.x2;
line.y3 = cp2.y2;
line.x4 = cp2.x3;
line.y4 = cp2.y3;
line.distance = cubicBezierLength(line.x1, line.y1, line.x2, line.y2, line.x3, line.y3, line.x4, line.y4);
} else {
line.distance = distance(line.x1, line.y1, line.x2, line.y2);
}
}
line.type = p.type;
line.rotation = p.ratio.r;
line.pat = p.ratio.p;
line.fix = p.ratio.f;
line.vt = p.ratio.v;
lines.push(line);
length += line.distance;
prev = p;
}
return {
v: lines,
l: length
};
}
export function cubicBezierLength(x1, y1, x2, y2, x3, y3, x4, y4, sampleCount) {
const ptCount = sampleCount || 40;
let totDist = 0;
let lastX = x1;
let lastY = y1;
let dx, dy, i, pt;
for (i = 1; i < ptCount; i++) {
pt = cubicQxy(i / ptCount, x1, y1, x2, y2, x3, y3, x4, y4);
dx = pt.x - lastX;
dy = pt.y - lastY;
totDist += Math.sqrt(dx * dx + dy * dy);
lastX = pt.x;
lastY = pt.y;
}
dx = x4 - lastX;
dy = y4 - lastY;
totDist += Math.sqrt(dx * dx + dy * dy);
return totDist;
}
function cubicQxy(t, x1, y1, x2, y2, x3, y3, x4, y4) {
x1 += (x2 - x1) * t;
x2 += (x3 - x2) * t;
x3 += (x4 - x3) * t;
x1 += (x2 - x1) * t;
x2 += (x3 - x2) * t;
y1 += (y2 - y1) * t;
y2 += (y3 - y2) * t;
y3 += (y4 - y3) * t;
y1 += (y2 - y1) * t;
y2 += (y3 - y2) * t;
return {
x: x1 + (x2 - x1) * t,
y: y1 + (y2 - y1) * t
};
}
export function distance(x1, y1, x2, y2) {
const a = (x2 - x1),
b = (y2 - y1);
return Math.sqrt(a * a + b * b);
}

311
src/core/model.js

@ -1,311 +0,0 @@ @@ -1,311 +0,0 @@
import {
getFontW,
getWeightRatio,
getCircleRound,
getScale,
getTracking,
getLeading,
getFontRatio,
getLineW,
getRect,
getCenter,
getRange,
getLines,
addRectToPaths,
} from './util.js';
import {
getGuide,
getGrid
} from './guide.js';
import {
getTextGroup
} from './group.js';
import {
setAlignGapX,
getAlignGapX
} from './align.js';
import {
typo
} from '../font/index.js';
import {
getLengths
} from './length.js';
import {
getPaths
} from './paths.js';
export class Model {
constructor() {
this.lineWidth_ = 1;
this.drawing_ = [];
this.data_ = null;
this.paths_ = null;
this.lines_ = null;
this.rect_ = {
x: 0,
y: 0,
w: 0,
h: 0
};
this.align_ = 'left';
this.scale_ = 1;
this.fontRatio_ = 1;
}
get data() {
return this.data_;
}
get paths() {
return this.paths_;
}
get lines() {
return this.lines_;
}
set lines(v) {
this.lines_ = v;
}
get lineWidth() {
return this.lineWidth_;
}
get fontRatio() {
return this.fontRatio_;
}
get scale() {
return this.scale_;
}
get rect() {
return this.rect_;
}
get drawing() {
return this.drawing_;
}
set align(v) {
if (this.align_ != v) {
this.align_ = v;
this.setPosition();
}
}
get align() {
return this.align_;
}
position(x, y) {
if (this.rect_.x != x || this.rect_.y != y) {
this.rect_.x = x;
this.rect_.y = y;
this.setPosition();
return true;
} else {
return false;
}
}
setPosition() {
const total = this.data_.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
d.rect.x = d.originPos.x + this.rect_.x + getAlignGapX(this.align_, d.alignGapX);
d.rect.y = d.originPos.y + this.rect_.y;
}
}
updateDrawingPaths() {
const total = this.data_.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
d.drawingPaths = addRectToPaths(getPaths(this, d, -1, false), d);
}
}
updatePatternPaths(pathGap) {
const total = this.data_.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
d.rawPaths = getPaths(this, d, pathGap, true);
}
}
updateWavePaths(pathGap) {
const total = this.data_.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
d.rawWavePaths = getPaths(this, d, pathGap, false);
}
}
updateGuide() {
const total = this.data_.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
d.guide = getGuide(d.typo, this.scale);
d.grid = getGrid(d.typo, this.scale);
}
}
update(text, width, breakWord, weight, size, tracking, leading) {
const fontW = getFontW(weight);
const weightRatio = getWeightRatio(fontW);
const circleRound = getCircleRound(fontW);
const scale = getScale(size);
const m_tracking = getTracking(tracking, scale);
const m_leading = getLeading(leading, scale);
const fontRatio = getFontRatio(weightRatio);
this.fontRatio_ = fontRatio;
this.scale_ = scale;
this.lineWidth_ = getLineW(fontW, scale);
const textGroup = getTextGroup(text, scale, width, breakWord);
let total = textGroup.length;
const total2 = total - 1;
let i, j, j_total, j_total2,
gt,
t, str,
m_rect,
s_pos,
tw = 0,
th = 0,
tx = 0,
ty = 0,
maxW = 0,
maxH = 0,
tmp = [];
for (i = 0; i < total; i++) {
gt = textGroup[i];
j_total = gt.length;
j_total2 = j_total - 1;
tw = 0;
tx = 0;
tmp[i] = {
tw: 0,
arr: []
};
for (j = 0; j < j_total; j++) {
str = gt[j];
t = typo(str);
m_rect = getRect(t, scale);
tw += m_rect.w;
th = m_rect.h;
if (j < j_total2) {
tw += m_tracking;
}
if (i < total2) {
th += m_leading;
}
m_rect.x = tx;
m_rect.y = ty;
s_pos = {
x: tx,
y: ty
};
tmp[i].arr[j] = {
str: str,
typo: t,
rect: m_rect,
originPos: s_pos,
center: getCenter(m_rect.w, m_rect.h, scale),
range: getRange(t, weightRatio, circleRound)
};
tx = tw;
}
ty += th;
tmp[i].tw = tw;
maxW = Math.max(maxW, tw);
maxH += th;
}
this.rect_.w = maxW;
this.rect_.h = maxH;
this.drawing_ = [];
const arr = [];
let aGapX, drawing;
for (const a of tmp) {
aGapX = setAlignGapX(maxW, a.tw);
for (const b of a.arr) {
b.alignGapX = aGapX;
b.pointsLength = getLengths(b, this);
arr.push(b);
drawing = {
value: 1
};
this.drawing_.push(drawing);
b.drawing = drawing;
// add converted Vector
for (const c of b.typo.p) {
c.cv = [];
for (const d of c.v) {
c.cv.push(d.convert(b, this));
}
}
}
}
this.data_ = arr;
this.setPosition();
}
updatePathsForRect() {
const total = this.data_.length;
const paths = [];
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
if (d.rawWavePaths) {
d.wavePaths = addRectToPaths(d.rawWavePaths, d);
}
if (d.rawPaths) {
d.paths = addRectToPaths(d.rawPaths, d);
Array.prototype.push.apply(paths, d.paths);
}
}
this.paths_ = paths;
}
updateLinesForRect() {
const total = this.data_.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
d.lines = getLines(d);
}
}
reset() {
this.lineWidth_ = 1;
this.drawing_ = [];
this.data_ = null;
this.paths_ = null;
this.lines_ = null;
this.rect_ = {
x: 0,
y: 0,
w: 0,
h: 0
};
this.align_ = 'left';
this.scale_ = 1;
this.fontRatio_ = 1;
}
}

200
src/core/paths.js

@ -1,200 +0,0 @@ @@ -1,200 +0,0 @@
import {
getCurrent
} from './util.js';
import {
ROTATE_NONE
} from '../font/util.js';
import {
Point
} from './point.js';
let prevPoint = null;
/**
* @name getPaths
* @property {Model} model - mode.js
* @property {Object} data - data object
* @property {Number} pathGap
* @returns {Array} Returns paths array
* @description get a guide pos
*/
export function getPaths(model, data, pathGap, isPattern) {
const lines = data.pointsLength.lines;
const scale = model.scale;
let total = lines.length,
i, j_total, j,
line, lg, direction,
arr = [],
paths = [],
paths2 = [];
for (i = 0; i < total; i++) {
line = lines[i];
prevPoint = null;
arr.push(getDotPos(line, pathGap, scale));
}
total = arr.length;
for (i = 0; i < total; i++) {
lg = arr[i];
j_total = lg.length;
paths2 = [];
for (j = 0; j < j_total; j++) {
line = lg[j];
if (line.rotation != ROTATE_NONE) {
if (isPattern) {
// If the 'p' value of the font data is 1, it's not included in the pattern paths.
if (!line.pat) {
paths2.push(line);
}
} else {
paths2.push(line);
}
}
}
direction = data.typo.p[i].d;
if (direction == 1) {
paths2.reverse();
}
if (paths2.length > 0) {
paths2[0].start = 1;
Array.prototype.push.apply(paths, paths2);
}
}
return paths;
}
function getDotPos(lines, pathGap, scale) {
const total = lines.length;
let i, j, j_total;
let line;
let curPoint;
let num, pp;
let arr = [];
let isFirst = 1;
let pgap = 1;
if (pathGap > -1) pgap = getCurrent(pathGap, 1, 0, 80, 10) * scale;
for (i = 0; i < total; i++) {
line = lines[i];
if (line.type == 'a') {
arr.push(new Point({
x: line.x1,
y: line.y1,
rotation: 0,
type: 'a',
pat: line.pat,
fix: line.fix,
radius: line.radius
}));
} else if (line.distance == 0) {
// it should be type m
curPoint = new Point({
x: line.x1,
y: line.y1,
rotation: line.rotation,
type: line.type,
pat: line.pat,
fix: line.fix
});
pp = setPointValues(curPoint, prevPoint, line, 1);
if (pp != null) {
if (isFirst) {
pp.type = 'm';
isFirst = 0;
}
arr.push(pp);
}
prevPoint = new Point(curPoint); //Object.assign({}, curPoint)
} else {
j_total = Math.ceil(line.distance / pgap);
if (j_total < 3) j_total = 3;
if (line.vt) j_total = 2;
for (j = 1; j < j_total; j++) {
num = j / (j_total - 1);
if (line.type == 'b') {
curPoint = getCubicBezierXYatT(line, num);
} else {
curPoint = new Point({
x: line.x1 + ((line.x2 - line.x1) * num),
y: line.y1 + ((line.y2 - line.y1) * num),
type: line.type
});
}
if (line.rotation != 0 && num == 1) curPoint.rotation = line.rotation;
if (line.pat && num == 1) curPoint.pat = line.pat;
if (line.fix && num == 1) curPoint.fix = line.fix;
if (j_total > 0) {
pp = setPointValues(curPoint, prevPoint, line, num);
if (pp != null) {
if (isFirst) {
pp.type = 'm';
isFirst = 0;
}
arr.push(pp);
}
}
prevPoint = new Point(curPoint); //Object.assign({}, curPoint)
}
}
}
return arr;
}
function setPointValues(cur, prev, line, num) {
cur.type = line.type;
cur.distance = line.distance;
cur.num = num;
if (!prev || cur.rotation != null) {
cur.rotation = cur.rotation;
} else {
const dx = cur.x - prev.x;
const dy = cur.y - prev.y;
const rad = Math.atan2(dx, dy);
cur.rotation = -rad;
}
if (cur.rotation == ROTATE_NONE) {
return null;
} else {
return cur;
}
}
function getCubicBezierXYatT(line, t) {
const x = CubicN(line.x1, line.x2, line.x3, line.x4, t);
const y = CubicN(line.y1, line.y2, line.y3, line.y4, t);
const tx = bezierTangent(line.x1, line.x2, line.x3, line.x4, t);
const ty = bezierTangent(line.y1, line.y2, line.y3, line.y4, t);
const rotation = -Math.atan2(tx, ty);
return new Point({
x: x,
y: y,
rotation: rotation
});
}
function CubicN(a, b, c, d, t) {
const t2 = t * t;
const t3 = t2 * t;
return a + (-a * 3 + t * (3 * a - a * t)) * t + (3 * b + t * (-6 * b + b * 3 * t)) * t + (c * 3 - c * 3 * t) * t2 + d * t3;
}
//http://qaru.site/questions/10657973/quadratic-curve-with-rope-pattern
//https://stackoverflow.com/questions/32322966/quadratic-curve-with-rope-pattern
export function bezierTangent(a, b, c, d, t) {
return (3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b));
}

21
src/core/point.js

@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
export function Point(mp) {
Object.assign(this, mp);
}
Object.assign(Point.prototype, {
addRect: function (rect) {
const vv = new Point(this);
vv.x = this.x + rect.x;
vv.y = this.y + rect.y;
vv.x2 = this.x2 + rect.x;
vv.y2 = this.y2 + rect.y;
vv.x3 = this.x3 + rect.x;
vv.y3 = this.y3 + rect.y;
vv.rx = this.rx + rect.x;
vv.ry = this.ry + rect.y;
vv.sx = this.sx + rect.x;
vv.sy = this.sy + rect.y;
if (vv.radius < 0.5) vv.radius = 0.5;
return vv;
}
});

214
src/core/util.js

@ -1,214 +0,0 @@ @@ -1,214 +0,0 @@
const DEFAULT_FONT_SIZE = 500;
export const MIN_FONT_WEIGHT = 1;
export const MAX_FONT_WEIGHT = 900;
const MAX_LINE_WIDTH = 70;
const FONT_WEIGHT_LIMIT = 80;
const FR_1 = 1;
const FR_2 = 0.78;
export const RECT_RATIO = 0.49;
const MAX_SHAKE = 120;
export const PI2 = 2 * Math.PI;
export function getAmplitude(amplitude, scale) {
return (MAX_SHAKE * amplitude) * scale;
}
export function getFontW(weight) {
return (MAX_LINE_WIDTH - MIN_FONT_WEIGHT) / (MAX_FONT_WEIGHT - MIN_FONT_WEIGHT) * (weight - MIN_FONT_WEIGHT) + MIN_FONT_WEIGHT;
}
export function getWeightRatio(fontW) {
return (1) / (FONT_WEIGHT_LIMIT - MIN_FONT_WEIGHT) * (fontW - MIN_FONT_WEIGHT);
}
export function getCircleRound(fontW) {
return (58 - 4) / (FONT_WEIGHT_LIMIT - MIN_FONT_WEIGHT) * (fontW - MIN_FONT_WEIGHT) + 4;
}
export function getScale(size) {
return size / DEFAULT_FONT_SIZE;
}
export function getLineW(fontW, scale) {
let lw = fontW * scale;
if (lw < 1) lw = 1;
//if (weight == 1) lw = 1
return lw;
}
export function getTracking(tracking, scale) {
return tracking * 50 * scale;
}
export function getLeading(leading, scale) {
return leading * 50 * scale;
}
export function getFontRatio(weightRatio) {
return (FR_2 - FR_1) * weightRatio + FR_1;
}
export function getRect(d, scale, x = 0, y = 0) {
const w = (d.rect.w * RECT_RATIO) * scale;
const h = ((d.rect.h + 220) * RECT_RATIO) * scale;
return {
x: x,
y: y,
w: w,
h: h
};
}
/**
* @name getGap
* @property {Object} - typo data object from 'font/index.js'
* @property {Number} - weightRatio
* @returns {Object} the gap x and y
* @description get a typo gap from thin to bold weight
*/
/*
export function getGap(d, weightRatio) {
const gx1 = d.ratio.x1
const gx2 = d.ratio.x2
const gy1 = d.ratio.y1
const gy2 = d.ratio.y2
const x = (gx2 - gx1) * weightRatio + gx1
const y = (gy2 - gy1) * weightRatio + gy1
return {
x: x,
y: y
}
}
*/
/**
* @name getCenter
* @property {Number} - typo rect width
* @property {Number} - typo rect height
* @property {Number} - typo scale
* @returns {Object} center position x and y
* @description get a center position of a typo
*/
export function getCenter(w, h, scale) {
const x = w / 2;
const y = (h - ((220 - 90) * RECT_RATIO * scale)) / 2;
return {
x: x,
y: y
};
}
/**
* @name getRange
* @property {Object} - typo data object from 'font/index.js'
* @property {Number} - weightRatio
* @property {Number} - circleRound
* @returns {Object} ratio range
* @description save ratio range to control each line's coordinate
*/
export function getRange(d, weightRatio, circleRound) {
const gx1 = d.ratio.x1;
const gx2 = d.ratio.x2;
const gy1 = d.ratio.y1;
const gy2 = d.ratio.y2;
return {
r: weightRatio,
cr: circleRound,
fr1: FR_1,
fr2: FR_2,
gx1: gx1,
gx2: gx2,
gy1: gy1,
gy2: gy2,
};
}
export function getCurrent(v, vmax, vmin, max, min) {
let value = (max - min) / (vmax - vmin) * (v - vmin) + min;
if (value < min) value = min;
else if (value > max) value = max;
return value;
}
export function getLines(data) {
const total = data.typo.p.length;
const lines = [];
let i, j, k, j_total;
let d2, d3, cp, dir, lt, ltRatio, prevRatio;
for (i = 0; i < total; i++) {
d2 = data.typo.p[i];
j_total = d2.cv.length;
for (j = 0; j < j_total; j++) {
d3 = d2.cv[j];
// add current position to all points
cp = d3.addRect(data.rect);
dir = d2.d;
lt = data.pointsLength.lengths[i];
ltRatio = lt / data.pointsLength.max;
prevRatio = 0;
if (i > 0) {
for (k = 0; k < i; k++) {
prevRatio += (data.pointsLength.lengths[k] / data.pointsLength.max);
}
}
ltRatio += prevRatio;
lines.push({
pos: cp,
drawing: data.drawing,
direction: dir,
lengths: lt,
maxDrawing: ltRatio,
minDrawing: prevRatio,
closePath: d3.ratio.c,
stroke: (ctx, d) => {
let dv = getCurrent(d.drawing.value, d.maxDrawing, d.minDrawing, 1, 0);
//if (d.direction == 1) {
// dv = getCurrent(1 - d.drawing.value, d.minDrawing, d.maxDrawing, 1, 0);
//}
if (dv > 0 && d.pos.type != 'a') {
const frac = d.lengths * dv;
ctx.setLineDash([d.lengths]);
ctx.lineDashOffset = d.direction * (frac + d.lengths);
ctx.stroke();
}
},
});
}
}
return lines;
}
export function addRectToPaths(path, data) {
const total = path.length;
const arr = [];
let i, cp, p;
for (i = 0; i < total; i++) {
p = path[i];
cp = p.addRect(data.rect);
arr.push(cp);
}
return arr;
}
export function randomBrightColor() {
return "hsl(" + 360 * Math.random() + ',' +
'100%,' +
'50%)';
}
export function shuffle(oldArray) {
let newArray = oldArray.slice(),
len = newArray.length,
i = len,
p, t;
while (i--) {
p = (Math.random() * len) | 0;
t = newArray[i];
newArray[i] = newArray[p];
newArray[p] = t;
}
return newArray;
}

101
src/core/vector.js

@ -1,101 +0,0 @@ @@ -1,101 +0,0 @@
import {
Point
} from './point.js';
export function Vector(mp) {
this.type = mp[0];
this.x = mp[1] || 0;
this.y = mp[2] || 0;
if (this.type == 'b') {
this.x2 = mp[3] || 0;
this.y2 = mp[4] || 0;
this.x3 = mp[5] || 0;
this.y3 = mp[6] || 0;
if (mp[7] == null) {
this.ratio = {
x: 1,
y: 1,
r: 0, // rotation : if the rotation is ROTATE_NONE, it will hide in the 'pattern' and 'paths'
p: 0, // 1 is hide the point in the pattern paths
f: 0, // 1 is fixed position for wave paths
c: 0, // 1 is close path for PIXI bug - graphics.closePath()
v: 0 // 1 is vertex, it's only for the vertex shape like V, W, A
};
} else {
this.ratio = {};
this.ratio.x = (mp[7].x == null) ? 1 : mp[7].x;
this.ratio.y = (mp[7].y == null) ? 1 : mp[7].y;
this.ratio.r = mp[7].r || 0;
this.ratio.p = mp[7].p || 0;
this.ratio.f = mp[7].f || 0;
this.ratio.c = mp[7].c || 0;
this.ratio.v = mp[7].v || 0;
}
} else {
if (mp[3] == null) {
this.ratio = {
x: 1,
y: 1,
r: 0,
p: 0,
f: 0,
c: 0,
v: 0
};
} else {
this.ratio = {};
this.ratio.x = (mp[3].x == null) ? 1 : mp[3].x;
this.ratio.y = (mp[3].y == null) ? 1 : mp[3].y;
this.ratio.r = mp[3].r || 0;
this.ratio.p = mp[3].p || 0;
this.ratio.f = mp[3].f || 0;
this.ratio.c = mp[3].c || 0;
this.ratio.v = mp[3].v || 0;
}
}
}
Object.assign(Vector.prototype, {
convert: function (pos, model) {
const x = convertX(this.x, pos, this.ratio, model);
const y = convertY(this.y, pos, this.ratio, model);
const x2 = convertX(this.x2, pos, this.ratio, model);
const y2 = convertY(this.y2, pos, this.ratio, model);
const x3 = convertX(this.x3, pos, this.ratio, model);
const y3 = convertY(this.y3, pos, this.ratio, model);
const rd = convertR(this.type, pos, model);
const vv = new Point(this);
vv.x = x;
vv.y = y;
vv.x2 = x2;
vv.y2 = y2;
vv.x3 = x3;
vv.y3 = y3;
vv.radius = rd;
return vv;
}
});
function convertR(type, pos, model) {
let rd = 0;
if (type == 'a') rd = pos.range.cr * model.scale * model.fontRatio;
return rd;
}
function convertX(x, pos, ratio, model) {
const rr = pos.range.r * ratio.x;
const gx = (pos.range.gx2 - pos.range.gx1) * rr + pos.range.gx1;
const fr = (pos.range.fr2 - pos.range.fr1) * rr + pos.range.fr1;
return pos.center.x + (((x - gx)) * model.scale * fr); // + pos.rect.x
}
function convertY(y, pos, ratio, model) {
const rr = pos.range.r * ratio.y;
const gy = (pos.range.gy2 - pos.range.gy1) * rr + pos.range.gy1;
const fr = (pos.range.fr2 - pos.range.fr1) * rr + pos.range.fr1;
return pos.center.y + (((y - gy)) * model.scale * fr); // + pos.rect.y
}

20
src/draw/canvas/color.js

@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
export function Color(ctx, no, data, color) {
let c_total = color.length;
const cur = (no + (c_total * (Math.abs((no / 10) | 0) + 1))) % c_total;
if (Array.isArray(color[cur])) {
c_total = color[cur].length;
const vv = 1 / (c_total + 1);
const g = ctx.createLinearGradient(data.rect.x, data.rect.y, data.rect.x, data.rect.y + data.rect.h);
let i;
g.addColorStop(vv, color[cur][0]);
for (i = 0; i < c_total; i++) {
g.addColorStop(vv * (i + 1), color[cur][i]);
}
g.addColorStop(vv * (c_total + 1), color[cur][c_total - 1]);
ctx.strokeStyle = g;
ctx.fillStyle = g;
} else {
ctx.strokeStyle = color[cur];
ctx.fillStyle = color[cur];
}
}

93
src/draw/canvas/colorful.js

@ -1,93 +0,0 @@ @@ -1,93 +0,0 @@
import {
PI2,
getCurrent
} from '../../core/util.js';
import {
cubicBezierLength,
distance
} from '../../core/length.js';
let colorArr;
let curColor = -1;
let colorTotal;
const MIN_DISTANCE = 10;
export function Colorful(ctx, model, colors) {
curColor = -1;
colorArr = colors;
colorTotal = colorArr.length;
const total = model.data.length;
let i, d, j, j_total, line, pos, prev;
let max, length, prevRatio;
for (i = 0; i < total; i++) {
d = model.data[i];
max = d.pointsLength.max;
prevRatio = 0;
j_total = d.lines.length;
prev = null;
for (j = 0; j < j_total; j++) {
line = d.lines[j];
pos = line.pos;
if (pos.type == 'a') {
setColor(ctx);
ctx.beginPath();
ctx.arc(pos.x, pos.y, pos.radius * d.drawing.value, 0, PI2);
ctx.fill();
ctx.closePath();
} else if (pos.type == 'm') {
prev = pos;
} else if (pos.type == 'l') {
length = distance(prev.x, prev.y, pos.x, pos.y);
if (length / model.scale > MIN_DISTANCE) {
// ignore short distance paths
setColor(ctx);
ctx.beginPath();
if (prev) ctx.moveTo(prev.x, prev.y);
ctx.lineTo(pos.x, pos.y);
prevRatio += draw(ctx, line, length, max, d, prevRatio);
}
prev = pos;
} else if (pos.type == 'b') {
length = cubicBezierLength(prev.x, prev.y, pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);
if (length / model.scale > MIN_DISTANCE) {
setColor(ctx);
ctx.beginPath();
if (prev) ctx.moveTo(prev.x, prev.y);
ctx.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);
prevRatio += draw(ctx, line, length, max, d, prevRatio);
}
prev = {
x: pos.x3,
y: pos.y3
};
}
}
}
}
function setColor(ctx) {
const color = getColor();
ctx.fillStyle = color;
ctx.strokeStyle = color;
}
function getColor() {
curColor++;
if (curColor == colorTotal) curColor = 0;
return colorArr[curColor];
}
function draw(ctx, line, length, max, d, prevRatio) {
const ltRatio = length / max;
let dv = getCurrent(d.drawing.value, prevRatio + ltRatio, prevRatio, 1, 0);
if (line.direction == 1) {
dv = getCurrent(1 - d.drawing.value, prevRatio, prevRatio + ltRatio, 1, 0);
}
if (dv > 0) {
const frac = length * dv;
ctx.setLineDash([length]);
ctx.lineDashOffset = line.direction * (frac + length);
ctx.stroke();
}
return ltRatio;
}

23
src/draw/canvas/grids.js

@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
export function Grids(ctx, data) {
ctx.save();
ctx.beginPath();
ctx.lineWidth = 1;
ctx.strokeStyle = "#aaaaaa";
let i, total = data.guide.length,
grid;
for (i = 0; i < total; i++) {
grid = data.rect.y + data.grid[i];
ctx.moveTo(data.rect.x, grid);
ctx.lineTo(data.rect.x + data.rect.w, grid);
}
ctx.stroke();
ctx.lineWidth = 1;
ctx.beginPath();
ctx.strokeStyle = "#aaaaaa";
ctx.rect(data.rect.x, data.rect.y, data.rect.w, data.rect.h);
ctx.stroke();
ctx.restore();
}

26
src/draw/canvas/lines.js

@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
import {
PI2
} from '../../core/util.js';
export function Lines(ctx, data) {
const total = data.lines.length;
let i, d, pos;
for (i = 0; i < total; i++) {
d = data.lines[i];
pos = d.pos;
if (pos.type == 'a') {
ctx.beginPath();
ctx.arc(pos.x, pos.y, pos.radius * d.drawing.value, 0, PI2);
ctx.fill();
ctx.closePath();
} else if (pos.type == 'm') {
ctx.beginPath();
ctx.moveTo(pos.x, pos.y);
} else if (pos.type == 'l') {
ctx.lineTo(pos.x, pos.y);
} else if (pos.type == 'b') {
ctx.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);
}
d.stroke(ctx, d);
}
}

31
src/draw/canvas/pattern.js

@ -1,31 +0,0 @@ @@ -1,31 +0,0 @@
import {
PI2
} from '../../core/util.js';
export function Pattern(ctx, data, w, h) {
const total = Math.round(data.paths.length * data.drawing.value);
const w2 = w / 2;
const w3 = w / 3;
const h2 = h / 2;
let i, p;
for (i = 0; i < total; i++) {
p = data.paths[i];
if (p.num == 1) {
ctx.fillStyle = "#ff00c5";
} else {
ctx.fillStyle = "#ff95f8";
}
if (p.type == 'a') {
ctx.beginPath();
ctx.arc(p.x, p.y, w3, 0, PI2);
ctx.fill();
} else {
ctx.beginPath();
ctx.save();
ctx.translate(p.x, p.y);
ctx.rotate(p.rotation);
ctx.fillRect(-w2, -h2, w, h);
ctx.restore();
}
}
}

73
src/draw/canvas/points.js

@ -1,73 +0,0 @@ @@ -1,73 +0,0 @@
import {
PI2
} from '../../core/util.js';
export function Points(ctx, data) {
ctx.save();
ctx.lineWidth = 1;
let total = data.lines.length;
let i;
for (i = 0; i < total; i++) {
eachLine_(ctx, data.lines[i]);
}
ctx.restore();
ctx.save();
ctx.lineWidth = 1;
total = data.typo.p.length;
for (i = 0; i < total; i++) {
eachPoint_(ctx, data.typo.p[i], data);
}
ctx.restore();
}
function eachPoint_(ctx, p, data) {
const total = p.v.length;
let i, mp, cp;
for (i = 0; i < total; i++) {
mp = p.cv[i];
cp = mp.addRect(data.rect);
if (mp.type == 'b') {
ctx.fillStyle = "#ff2a00";
ctx.beginPath();
ctx.arc(cp.x3 + (cp.x3 - cp.x2), cp.y3 + (cp.y3 - cp.y2), 1.5, 0, PI2);
ctx.fill();
ctx.beginPath();
ctx.arc(cp.x2, cp.y2, 1.5, 0, PI2);
ctx.fill();
ctx.beginPath();
ctx.moveTo(cp.x2, cp.y2);
ctx.lineTo(cp.x3, cp.y3);
ctx.lineTo(cp.x3 + (cp.x3 - cp.x2), cp.y3 + (cp.y3 - cp.y2));
ctx.stroke();
ctx.beginPath();
ctx.fillStyle = "#ffffff";
ctx.arc(cp.x3, cp.y3, 2.5, 0, PI2);
ctx.fill();
ctx.stroke();
} else {
ctx.beginPath();
ctx.fillStyle = "#ffffff";
ctx.strokeStyle = "#ff2a00";
ctx.arc(cp.x, cp.y, 2.5, 0, PI2);
ctx.fill();
ctx.stroke();
}
}
}
function eachLine_(ctx, d) {
const pos = d.pos;
if (pos.type != 'a') {
if (pos.type == 'm') {
ctx.strokeStyle = "#ff2a00";
ctx.beginPath();
ctx.moveTo(pos.x, pos.y);
} else if (pos.type == 'l') {
ctx.lineTo(pos.x, pos.y);
} else if (pos.type == 'b') {
ctx.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);
}
ctx.stroke();
}
}

54
src/draw/canvas/wave.js

@ -1,54 +0,0 @@ @@ -1,54 +0,0 @@
import {
PI2,
getAmplitude
} from '../../core/util.js';
const THIN_LIMIT = 110;
const COS = Math.cos;
const SIN = Math.sin;
export function Wave(ctx, data, scale, amplitude, weight, fps) {
const total = data.wavePaths.length;
const m_amplitude = getAmplitude(amplitude, scale);
let i, p, prev, qx, qy, saveDot = [];
ctx.beginPath();
for (i = 0; i < total; i++) {
p = data.wavePaths[i];
if (fps) {
const ranx = (Math.random() * m_amplitude) - (m_amplitude / 2);
const rany = (Math.random() * m_amplitude) - (m_amplitude / 2);
p.rx = p.x + ranx * COS(p.rotation);
p.ry = p.y + ranx * SIN(p.rotation);
p.sx = p.x + ranx;
p.sy = p.y + rany;
}
if (p.type == 'a') {
saveDot.push(p);
} else if (p.start == 1) {
ctx.moveTo(p.x, p.y);
} else if (p.fix) {
ctx.lineTo(p.x, p.y);
} else {
if (weight < THIN_LIMIT) {
prev = data.wavePaths[i - 1];
if (prev) {
qx = prev.x + ((p.x - prev.x) * 0.5);
qy = prev.y + ((p.y - prev.y) * 0.5);
ctx.quadraticCurveTo(qx, qy, p.rx, p.ry);
}
} else {
ctx.lineTo(p.rx, p.ry);
}
}
}
ctx.stroke();
for (i = 0; i < saveDot.length; i++) {
p = saveDot[i];
ctx.beginPath();
ctx.arc(p.x, p.y, p.radius, 0, PI2);
ctx.fill();
}
}

33
src/draw/pixi/color.js

@ -1,33 +0,0 @@ @@ -1,33 +0,0 @@
export function PixiColor(no, data, color) {
let c_total = color.length;
const cur = (no + (c_total * (Math.abs((no / 10) | 0) + 1))) % c_total;
if (Array.isArray(color[cur])) {
/*
c_total = color[cur].length;
const vv = 1 / (c_total - 1);
const g = ctx.createLinearGradient(data.rect.x, data.rect.y, data.rect.x, data.rect.y + data.rect.h);
let i;
for (i = 0; i < c_total; i++) {
g.addColorStop(vv * i, color[cur][i]);
}
ctx.strokeStyle = g;
ctx.fillStyle = g;
*/
/*
c_total = color[cur].length;
const vv = 1 / (c_total - 1);
const c = document.createElement("canvas");
const ctx = c.getContext("2d");
const g = ctx.createLinearGradient(0, 0, data.rect.w, data.rect.h);
let i;
for (i = 0; i < c_total; i++) {
g.addColorStop(vv * i, color[cur][i]);
}
ctx.fillStyle = g;
ctx.fillRect(0, 0, data.rect.w, data.rect.h);
return new PIXI.Texture.from(c);
*/
} else {
return color[cur];
}
}

51
src/draw/pixi/lines.js

@ -1,51 +0,0 @@ @@ -1,51 +0,0 @@
export function PixiLines(graphics, data, lineW, color) {
let total, i;
if (data.drawing.value == 1) {
total = data.lines.length;
for (i = 0; i < total; i++) {
eachLine_(graphics, data.lines[i], lineW, color);
}
} else {
total = data.drawingPaths.length * data.drawing.value;
for (i = 0; i < total; i++) {
eachPath_(graphics, data.drawingPaths[i], lineW, color, data.drawing.value);
}
}
}
function eachLine_(graphics, data, lineW, color) {
const pos = data.pos;
if (pos.type == 'a') {
graphics.lineStyle(0, color, 0);
graphics.beginFill(color);
graphics.drawCircle(pos.x, pos.y, pos.radius);
graphics.endFill();
} else if (pos.type == 'm') {
graphics.lineStyle(lineW, color, 1);
graphics.moveTo(pos.x, pos.y);
} else if (pos.type == 'l') {
graphics.lineTo(pos.x, pos.y);
} else if (pos.type == 'b') {
graphics.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);
}
if (data.closePath) {
graphics.closePath();
}
}
function eachPath_(graphics, pos, lineW, color, dValue) {
if (pos.type == 'a') {
graphics.lineStyle(0, color, 0);
graphics.beginFill(color);
graphics.drawCircle(pos.x, pos.y, pos.radius * dValue);
graphics.endFill();
} else {
if (pos.start == 1) {
graphics.lineStyle(lineW, color, 1);
graphics.moveTo(pos.x, pos.y);
} else {
graphics.lineTo(pos.x, pos.y, 1);
}
}
}

23
src/font/index.js

@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
import {
UPPER
} from './upper.js';
import {
LOWER
} from './lower.js';
import {
NUMBER
} from './number.js';
import {
SPECIAL
} from './special.js';
import {
TOFU
} from './util.js';
const DATA = Object.assign({}, UPPER, LOWER, NUMBER, SPECIAL);
export function typo(v) {
var t = DATA[v] || DATA[TOFU];
t.v = v;
return t;
}

884
src/font/lower.js

@ -1,884 +0,0 @@ @@ -1,884 +0,0 @@
import {
generateFontData,
ROTATE_HORIZONTAL,
ROTATE_VERTICAL,
ROTATE_NONE,
VERTEX_GAP,
VERTEX_GAP2,
getR,
getCurveR
} from './util.js';
export const LOWER = {
'a': generateFontData(
600, 232, 232,
10, 2, -64, -64,
[{
d: -1,
v: [
['m', 232, 8, {
y: -3.4,
r: ROTATE_HORIZONTAL
}],
['l', 232, 116, {
r: ROTATE_NONE
}],
['b', 232, 180.1, 180.1, 232, 116, 232, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 232, 0, 180.1, 0, 116, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 51.9, 51.9, 0, 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 0, 232, 51.9, 232, 116, {
r: ROTATE_HORIZONTAL
}],
['l', 232, 224, {
y: -0.1,
r: ROTATE_HORIZONTAL,
f: 1
}]
]
}, ]
),
'b': generateFontData(
600, 232, 352,
-10, -2, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 116 + 123, {
r: ROTATE_NONE
}],
['b', 0, 180.1 + 123, 51.9, 232 + 123, 116, 232 + 123, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 232 + 123, 232, 180.1 + 123, 232, 116 + 123, {
r: ROTATE_HORIZONTAL
}],
['b', 232, 51.9 + 123, 180.1, 0 + 123, 116, 0 + 123, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 0 + 123, 0, 51.9 + 123, 0, 116 + 123, {
r: ROTATE_HORIZONTAL
}],
['l', 0, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}]
]
}, ]
),
'c': generateFontData(
520, 212.1, 233.1,
2, -10, -64, -64,
[{
d: 1,
v: [
['m', 212.1, 182.9, {
r: getCurveR(212.1, 182.9, 191.1, 213.2, 156.1, 233.1, 116.5, 233.1, 0),
f: 1
}],
['b', 191.1, 213.2, 156.1, 233.1, 116.5, 233.1, {
r: ROTATE_VERTICAL
}],
['b', 52.4, 233.1, 0.5, 181.2, 0.5, 117.1, {
r: ROTATE_HORIZONTAL
}],
['b', 0.5, 53, 52.4, 1.1, 116.5, 1.1, {
r: ROTATE_VERTICAL
}],
['b', 156.1, 1.1, 191.1, 21, 212.1, 51.3],
]
}]
),
'd': generateFontData(
600, 232, 352,
10, 2, 0, 0,
[{
d: -1,
v: [
['m', 232, 0, {
y: 0
}],
['l', 232, 116 + 123, {
r: ROTATE_NONE
}],
['b', 232, 180.1 + 123, 180.1, 232 + 123, 116, 232 + 123, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 232 + 123, 0, 180.1 + 123, 0, 116 + 123, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 51.9 + 123, 51.9, 0 + 123, 116, 0 + 123, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 0 + 123, 232, 51.9 + 123, 232, 116 + 123, {
r: ROTATE_HORIZONTAL
}],
['l', 232, 352, {
y: 0,
f: 1
}],
]
}, ]
),
'e': generateFontData(
570, 225.5, 233.1,
0, 0, -64, -64,
[{
d: 1,
v: [
['m', 211.6, 182.9, {
r: getCurveR(211.6, 182.9, 191.1, 213.2, 156.1, 233.1, 116.5, 233.1, 0),
f: 1
}],
['b', 191.1, 213.2, 156.1, 233.1, 116.5, 233.1, {
r: ROTATE_VERTICAL
}],
['b', 52.4, 233.1, 0.5, 181.2, 0.5, 117.1, {
r: ROTATE_HORIZONTAL
}],
['b', 0.5, 53, 52.4, 1.1, 116.5, 1.1, {
r: ROTATE_VERTICAL
}],
['b', 176.4, 1.1, 224.9, 47.2, 225.5, 106.1, {
r: ROTATE_HORIZONTAL
}],
['l', 0.5, 106.1, {
r: ROTATE_HORIZONTAL,
p: 1
}],
]
}]
),
'f': generateFontData(
356, 232, 352,
-40, -40, 0, 0,
[{
d: -1,
v: [
['m', 166.6, 33, {
x: 0.5,
r: getCurveR(166.6, 33, 159.3, 13.1, 139.2, 0, 116.9, 0, 0)
}],
['b', 159.3, 13.1, 139.2, 0, 116.9, 0, {
r: ROTATE_VERTICAL
}],
['b', 88.2, 0, 65, 23.2, 65, 51.9, {
r: ROTATE_HORIZONTAL
}],
['l', 65, 352, {
y: 0,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 0, 130, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 154, 130, {
x: 0,
f: 1
}],
]
}
]
),
'g': generateFontData(
600, 232, 338,
10, 2, -117, -117,
[{
d: -1,
v: [
['m', 232, 5, {
y: -2.8
}],
['l', 232, 116, {
r: ROTATE_NONE
}],
['b', 232, 180.1, 180.1, 232, 116, 232, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 232, 0, 180.1, 0, 116, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 51.9, 51.9, 0, 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 0, 232, 51.9, 232, 116, {
r: ROTATE_HORIZONTAL
}],
['l', 232, 222],
['b', 234.5, 300.3, 180.2, 338.5, 116, 338, {
y: 0.64,
r: ROTATE_VERTICAL
}],
['b', 76.2, 337.7, 36.6, 320.7, 15.7, 290.1, {
y: 0.64,
f: 1
}],
]
}]
),
'h': generateFontData(
520, 182, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 352, {
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 91 + 123, {
r: ROTATE_NONE
}],
['b', 0, 40.7 + 123, 40.7, 0 + 123, 91, 0 + 123, {
r: ROTATE_VERTICAL
}],
['b', 141.3, 0 + 123, 182, 40.7 + 123, 182, 91 + 123, {
r: ROTATE_HORIZONTAL
}],
['l', 182, 352, {
y: 0,
f: 1
}],
]
}]
),
'i': generateFontData(
200, 0, 352,
0, 0, 0, 0,
[{
d: 1,
v: [
['a', 0, 90, {
y: -3
}],
]
}, {
d: 1,
v: [
['m', 0, 352, {
y: 0,
f: 1
}],
['l', 0, 130, {
y: -3
}],
]
}]
),
'j': generateFontData(
220, 115.9, 352,
-60, -60, 0, 0,
[{
d: 1,
v: [
['a', 0, 90, {
y: -3
}],
]
}, {
d: 1,
v: [
['m', 0 - 115.9, 317 + 127, {
x: 0.4,
y: 0.63,
r: getCurveR(0 - 115.9, 317 + 127, 12.6 - 115.9, 327.4 + 127, 29.6 - 115.9, 333.2 + 127, 45.9 - 115.9, 334.2 + 127, 0),
f: 1
}],
['b', 12.6 - 115.9, 327.4 + 127, 29.6 - 115.9, 333.2 + 127, 45.9 - 115.9, 334.2 + 127, {
x: 0.4,
y: 0.63,
r: ROTATE_VERTICAL
}],
['b', 84.5 - 115.9, 336.5 + 127, 115.9 - 115.9, 308.1 + 127, 115.9 - 115.9, 269.4 + 127, {
x: 0.4,
y: 0.63,
r: ROTATE_HORIZONTAL
}],
['l', 115.9 - 115.9, 0 + 127 + 3, {
y: -3
}],
]
}]
),
'k': generateFontData(
450, 164, 352,
-10, -10, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 352, {
y: 0,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 160, 130, {
x: 0.7,
y: 0,
r: getR(164, 130, 0, 106 + 130 - VERTEX_GAP2),
f: 1
}],
['l', 0, 106 + 130 - VERTEX_GAP2, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 0, 106 + 130 + VERTEX_GAP2, {
r: ROTATE_VERTICAL,
p: 1,
v: 1
}],
['l', 164, 352, {
x: 0.7,
y: 0.7,
f: 1
}],
]
}
]
),
'l': generateFontData(
200, 0, 352,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 0, 352, {
y: 0,
f: 1
}],
['l', 0, 0, {
y: 0
}],
]
}]
),
'm': generateFontData(
740, 150 + 150, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 130, {
y: -3.6
}],
['l', 0, 352, {
y: 0,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 0, 75 + 123, {
y: 0,
r: ROTATE_HORIZONTAL,
p: 1
}],
['b', 0, 33.6 + 123, 33.6, 0 + 123, 75, 0 + 123, {
r: ROTATE_VERTICAL
}],
['b', 116.4, 0 + 123, 150, 33.6 + 123, 150, 75 + 123, {
r: ROTATE_HORIZONTAL
}],
['l', 150, 352, {
y: 0,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 0 + 150, 75 + 123, {
y: 0,
r: ROTATE_HORIZONTAL,
p: 1
}],
['b', 0 + 150, 33.6 + 123, 33.6 + 150, 0 + 123, 75 + 150, 0 + 123, {
r: ROTATE_VERTICAL
}],
['b', 116.4 + 150, 0 + 123, 150 + 150, 33.6 + 123, 150 + 150, 75 + 123, {
r: ROTATE_HORIZONTAL
}],
['l', 150 + 150, 352, {
y: 0,
f: 1
}],
]
}
]
),
'n': generateFontData(
520, 182, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 130, {
y: -3.3
}],
['l', 0, 352, {
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 91 + 123, {
y: 0,
r: ROTATE_HORIZONTAL,
p: 1
}],
['b', 0, 40.7 + 123, 40.7, 0 + 123, 91, 0 + 123, {
r: ROTATE_VERTICAL
}],
['b', 141.3, 0 + 123, 182, 40.7 + 123, 182, 91 + 123, {
r: ROTATE_HORIZONTAL
}],
['l', 182, 352, {
y: 0,
f: 1
}],
]
}
]
),
'o': generateFontData(
580, 232, 232,
0, 0, -64, -64,
[{
d: 1,
v: [
['m', 232, 116, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['b', 232, 180.1, 180.1, 232, 116, 232, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 232, 0, 180.1, 0, 116, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 51.9, 51.9, 0, 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 0, 232, 51.9, 232, 116, {
r: ROTATE_HORIZONTAL,
c: 1
}],
]
}]
),
'p': generateFontData(
600, 232, 338,
-10, -2, -117, -117,
[{
d: -1,
v: [
['m', 0, 5, {
y: -2.8
}],
['l', 0, 116, {
r: ROTATE_NONE
}],
['b', 0, 180.1, 51.9, 232, 116, 232, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 232, 232, 180.1, 232, 116, {
r: ROTATE_HORIZONTAL
}],
['b', 232, 51.9, 180.1, 0, 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 0, 0, 51.9, 0, 116, {
r: ROTATE_HORIZONTAL
}],
['l', 0, 338, {
y: 0,
f: 1
}],
]
}]
),
'q': generateFontData(
600, 232, 338,
10, 2, -117, -117,
[{
d: -1,
v: [
['m', 232, 5, {
y: -2.8
}],
['l', 232, 116, {
r: ROTATE_NONE
}],
['b', 232, 180.1, 180.1, 232, 116, 232, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 232, 0, 180.1, 0, 116, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 51.9, 51.9, 0, 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 0, 232, 51.9, 232, 116, {
r: ROTATE_HORIZONTAL
}],
['l', 232, 338, {
y: 0,
f: 1
}],
]
}]
),
'r': generateFontData(
340, 119.2, 352,
-20, -20, 0, 0,
[{
d: -1,
v: [
['m', 0, 130, {
y: -3.3
}],
['l', 0, 352, {
y: 0,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 0, 57 + 124, {
r: ROTATE_HORIZONTAL,
p: 1,
}],
['b', 0, 57 + 124, 41.9, -22.8 + 124, 119.2, 4.5 + 124, {
x: 0,
y: 2,
r: getCurveR(119.2, 4.5 + 124, 41.9, -22.8 + 124, 0, 57 + 124, 119.2, 4.5 + 124, 0),
f: 1
}],
]
}
]
),
's': generateFontData(
400, 224 * 0.642, 360 * 0.642,
0, 0, -64, -64,
[{
d: 1,
v: [
['m', 0 * 0.642, 295.4 * 0.642, {
r: getCurveR(0 * 0.642, 295.4 * 0.642, 17.6 * 0.642, 332.1 * 0.642, 58.3 * 0.642, 360 * 0.642, 110.3 * 0.642, 360 * 0.642, 0),
f: 1
}],
['b', 17.6 * 0.642, 332.1 * 0.642, 58.3 * 0.642, 360 * 0.642, 110.3 * 0.642, 360 * 0.642],
['b', 173.9 * 0.642, 360 * 0.642, 223.8 * 0.642, 329.6 * 0.642, 224 * 0.642, 271 * 0.642],
['b', 224.2 * 0.642, 214.7 * 0.642, 180.7 * 0.642, 189.6 * 0.642, 112.4 * 0.642, 173.3 * 0.642],
['b', 47.3 * 0.642, 157.7 * 0.642, 10.9 * 0.642, 130.6 * 0.642, 12 * 0.642, 84.4 * 0.642],
['b', 13.3 * 0.642, 29.8 * 0.642, 57.3 * 0.642, 0 * 0.642, 114.8 * 0.642, 0 * 0.642],
['b', 158.4 * 0.642, 0 * 0.642, 196.5 * 0.642, 20.5 * 0.642, 212 * 0.642, 51.3 * 0.642],
]
}]
),
't': generateFontData(
356, 232, 352,
-30, -30, 0, 0,
[{
d: -1,
v: [
['m', 65, 0, {
y: 0
}],
['l', 65, 298.2 + 6],
['b', 65, 326.9 + 6, 88.2, 350.1 + 6, 116.9, 350.1 + 6, {
r: ROTATE_VERTICAL
}],
['b', 139.2, 350.1 + 6, 159.3, 337 + 6, 166.6, 317.1, {
x: 0,
f: 1
}]
]
},
{
d: -1,
v: [
['m', 0, 130, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 154, 130, {
x: 0,
f: 1
}],
]
}
]
),
'u': generateFontData(
520, 182, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 130, {
y: -3
}],
['l', 0, 0 + 265, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 50.3 + 265, 40.7, 91 + 265, 91, 91 + 265, {
r: ROTATE_VERTICAL
}],
['b', 141.3, 91 + 265, 182, 50.3 + 265, 182, 0 + 265, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1,
}],
]
},
{
d: -1,
v: [
['m', 182, 130, {
y: -3
}],
['l', 182, 352, {
y: 0,
f: 1
}],
]
}
]
),
'v': generateFontData(
500, 200, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 130, {
x: 0.6,
y: -3,
r: getR(0, 130, 100 - VERTEX_GAP2, 352)
}],
['l', 100 - VERTEX_GAP2, 352, {
r: getR(0, 130, 100 - VERTEX_GAP2, 352),
f: 1
}],
['l', 100 + VERTEX_GAP2, 352, {
r: getR(100 + VERTEX_GAP2, 352, 200, 130),
f: 1,
v: 1
}],
['l', 200, 130, {
x: 0.6,
y: -3,
f: 1
}],
]
}]
),
'w': generateFontData(
700, 310, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 130, {
x: 0.6,
y: -3,
r: getR(0, 130, 78 - VERTEX_GAP2, 352)
}],
['l', 78 - VERTEX_GAP2, 352, {
r: getR(0, 130, 78 - VERTEX_GAP2, 352),
f: 1
}],
['l', 78 + VERTEX_GAP2, 352, {
r: getR(78 + VERTEX_GAP2, 352, 155 - VERTEX_GAP2, 130),
f: 1,
v: 1
}],
['l', 155 - VERTEX_GAP2, 130, {
y: 1,
r: getR(78 + VERTEX_GAP2, 352, 155 - VERTEX_GAP2, 130),
f: 1
}],
['l', 155 + VERTEX_GAP2, 130, {
y: 1,
r: getR(155 + VERTEX_GAP2, 130, 233 - VERTEX_GAP2, 352),
f: 1,
v: 1
}],
['l', 233 - VERTEX_GAP2, 352, {
r: getR(155 + VERTEX_GAP2, 130, 233 - VERTEX_GAP2, 352),
f: 1
}],
['l', 233 + VERTEX_GAP2, 352, {
r: getR(233 + VERTEX_GAP2, 352, 310, 130),
f: 1,
v: 1
}],
['l', 310, 130, {
x: 0.6,
y: -3,
f: 1
}],
]
}]
),
'x': generateFontData(
490, 210, 352,
0, 0, 0, -7,
[{
d: -1,
v: [
['m', 10, 130, {
x: 0.5,
y: -1,
r: getR(10, 130, 210, 352)
}],
['l', 210, 352, {
x: 0.5,
y: 0.5,
f: 1
}]
]
},
{
d: -1,
v: [
['m', 200, 130, {
x: 0.5,
y: -1,
r: getR(200, 130, 0, 352)
}],
['l', 0, 352, {
x: 0.5,
y: 0.5,
f: 1
}]
]
}
]
),
'y': generateFontData(
500, 225.5, 331.5,
10, 10, -119, -119,
[{
d: -1,
v: [
['m', 225.5, 0, {
y: -3,
r: getR(225.5, 0, 116.3, 248.8)
}],
['l', 116.3, 248.8, {
x: 0.5,
y: 0.64
}],
['b', 71.8, 349.6, 0, 331.5, 0, 331.5, {
x: 0.5,
y: 0.64,
r: getCurveR(0, 331.5, 71.8, 349.6, 116.3, 248.8, 0, 331.5, 0),
f: 1
}],
]
},
{
d: -1,
v: [
['m', 3.2, 0, {
y: -3,
r: getR(3.2, 0, 125.7, 226.6)
}],
['l', 125.7, 226.6, {
p: 1,
f: 1
}],
]
}
]
),
'z': generateFontData( // 232, 224
420, 172, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 6, 130, {
x: -0.5,
y: 1,
r: ROTATE_VERTICAL,
}],
['l', 166, 130, {
x: 1.8,
y: 1,
r: ROTATE_VERTICAL,
f: 1
}],
['l', 166, 130 + VERTEX_GAP, {
x: 1.8,
y: 1,
r: ROTATE_HORIZONTAL,
p: 1,
v: 1
}],
['l', 0, 352 - VERTEX_GAP, {
x: 1.7,
r: ROTATE_HORIZONTAL,
p: 1
}],
['l', 0, 352, {
x: 1.7,
r: ROTATE_VERTICAL,
f: 1,
v: 1
}],
['l', 172, 352, {
x: -0.4,
r: ROTATE_VERTICAL,
f: 1
}]
]
}]
)
};

344
src/font/number.js

@ -1,344 +0,0 @@ @@ -1,344 +0,0 @@
import {
generateFontData,
ROTATE_HORIZONTAL,
ROTATE_VERTICAL,
ROTATE_NONE,
VERTEX_GAP,
getR,
getCurveR
} from './util.js';
export const NUMBER = {
'0': generateFontData(
660, 270, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 270, 180, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['b', 270, 279.4, 209.6, 360, 135, 360, {
r: ROTATE_VERTICAL
}],
['b', 60.4, 360, 0, 279.4, 0, 180, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 80.6, 60.4, 0, 135, 0, {
r: ROTATE_VERTICAL
}],
['b', 209.6, 0, 270, 80.6, 270, 180, {
r: ROTATE_HORIZONTAL,
c: 1
}],
]
}]
),
'1': generateFontData(
380, 76, 352,
15, 15, 0, 0,
[{
d: -1,
v: [
['m', 0, 51, {
x: -2,
y: 2,
r: getR(0, 51, 76 - VERTEX_GAP, 0)
}],
['l', 76 - VERTEX_GAP, 0, {
r: ROTATE_HORIZONTAL,
p: 1
}],
['l', 76, 0, {
r: ROTATE_HORIZONTAL,
f: 1,
v: 1
}],
['l', 76, 352, {
y: 0,
f: 1
}],
]
}]
),
'2': generateFontData(
580, 210, 356,
0, 0, 2, 2,
[{
d: -1,
v: [
['m', 3.9, 68.8, {
x: 1.2,
y: 1.2,
r: getCurveR(3.9, 68.8, 16.7, 29, 54.2, 3.1, 98.2, 0.2, 0)
}],
['b', 16.7, 29, 54.2, 3.1, 98.2, 0.2],
['b', 151.8, -3.3, 208.5, 38.3, 198.9, 100.1],
['b', 197.1, 111.8, 196.4, 142.4, 101.5, 235.2],
['b', 11.4, 323.2, 0, 356 - VERTEX_GAP, 0, 356 - VERTEX_GAP, {
r: ROTATE_NONE
}],
['l', 0, 356 - VERTEX_GAP, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 0, 356, {
r: ROTATE_VERTICAL,
f: 1,
v: 1
}],
['l', 210, 356, {
x: -0.5,
f: 1
}],
]
}]
),
'3': generateFontData(
580, 222.1, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 10.7, 66.3, {
r: getCurveR(10.7, 66.3, 11.2, 64.8, 11.7, 63.3, 12.3, 61.8, 0)
}],
['b', 11.2, 64.8, 11.7, 63.3, 12.3, 61.8, {
r: ROTATE_NONE
}],
['b', 25.8, 25.9, 64.5, 0, 110.1, 0, {
r: ROTATE_VERTICAL
}],
['b', 167, 0, 213.1, 40.3, 213.1, 90, {
r: ROTATE_HORIZONTAL
}],
['b', 213.1, 139.7, 167, 180, 110.1, 179.9, {
r: ROTATE_VERTICAL,
f: 1
}],
['l', 100.1, 179.9, {
x: -5,
y: 1,
r: ROTATE_VERTICAL,
f: 1
}],
['l', 110.1, 180, {
r: ROTATE_VERTICAL,
p: 1
}],
['b', 172, 180, 222.1, 220.3, 222.1, 270, {
r: ROTATE_HORIZONTAL
}],
['b', 222.1, 319.7, 172, 360, 110.1, 360, {
r: ROTATE_VERTICAL
}],
['b', 56.9, 360, 12.4, 330.2, 1, 290.3, {
f: 1
}],
]
}]
),
'4': generateFontData(
596, 236, 352,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 175, 352, {
y: 0,
f: 1
}],
['l', 175, 0, {
f: 1
}],
['l', 175 - VERTEX_GAP, 0, {
r: ROTATE_VERTICAL,
p: 1,
v: 1
}],
['l', 0, 276 - VERTEX_GAP, {
r: ROTATE_HORIZONTAL,
p: 1
}],
['l', 0, 276, {
r: ROTATE_VERTICAL,
f: 1,
v: 1
}],
['l', 236, 276, {
x: -0.5
}],
]
}]
),
'5': generateFontData(
596, 208.5, 356,
0, -5, -2, -2,
[{
d: 1,
v: [
['m', 0, 295.7, {
r: getCurveR(0, 295.7, 15.3, 333.8, 52.2, 356.2, 97.5, 356, 0),
f: 1
}],
['b', 15.3, 333.8, 52.2, 356.2, 97.5, 356, {
r: ROTATE_VERTICAL
}],
['b', 159.1, 355.7, 206.1, 306.9, 208.5, 240.8, {
r: ROTATE_HORIZONTAL
}],
['b', 210.9, 173.9, 162.7, 120.8, 97.5, 125.6, {
r: ROTATE_VERTICAL
}],
['b', 59.4, 128.4, 25.5, 145.8, 5.6, 176.4, {
f: 1
}],
['l', 5.6, 176.4, {
r: ROTATE_NONE
}],
['l', 5.6 - VERTEX_GAP, 176.4, {
r: ROTATE_HORIZONTAL,
p: 1,
v: 1
}],
['l', 11.5, 0, {
r: ROTATE_VERTICAL,
f: 1
}],
['l', 193.5, 0, {
x: -0.5
}],
]
}]
),
'6': generateFontData(
596, 215.8, 360,
0, -2, 0, 0,
[{
d: 1,
v: [
['m', 7.6, 272.3, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['b', 6.4, 265.8, 5.8, 259.1, 5.8, 252.2, {
r: ROTATE_HORIZONTAL
}],
['b', 5.8, 192.6, 52.8, 144.2, 110.8, 144.2, {
r: ROTATE_VERTICAL
}],
['b', 168.7, 144.2, 215.8, 192.6, 215.8, 252.2, {
r: ROTATE_HORIZONTAL
}],
['b', 215.8, 311.9, 168.7, 360, 110.8, 360, {
r: ROTATE_VERTICAL
}],
['b', 59.5, 360, 16.8, 322.4, 7.6, 272.4, {
r: ROTATE_NONE
}],
['b', 7.6, 272.4, -44.1, 8.8, 122.2, 0.2],
['b', 165.5, -2.1, 193.8, 21, 212.1, 56.4],
]
}]
),
'7': generateFontData(
540, 213, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 213, 0, {
r: ROTATE_VERTICAL,
f: 1
}],
['l', 213, 0.1, {
r: ROTATE_NONE
}],
['l', 72.7, 352, {
y: 0.1,
f: 1
}],
]
}]
),
'8': generateFontData(
596, 224, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 112, 180, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['b', 50.1, 180, 0, 220.3, 0, 270, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 319.7, 50.1, 360, 112, 360, {
r: ROTATE_VERTICAL
}],
['b', 173.9, 360, 224, 319.7, 224, 270, {
r: ROTATE_HORIZONTAL
}],
['b', 224, 220.3, 173.9, 180, 112, 180, {
r: ROTATE_VERTICAL
}],
['b', 55.1, 180, 9, 139.7, 9, 90, {
r: ROTATE_HORIZONTAL
}],
['b', 9, 40.3, 55.1, 0, 112, 0, {
r: ROTATE_VERTICAL
}],
['b', 168.9, 0, 215, 40.3, 215, 90, {
r: ROTATE_HORIZONTAL
}],
['b', 215, 139.7, 168.9, 180, 112, 180, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
]
}]
),
'9': generateFontData(
596, 215.8, 360,
0, -2, 0, 0,
[{
d: -1,
v: [
['m', 208.2, 88, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['b', 209.4, 94.5, 210, 101.2, 210, 108, {
r: ROTATE_HORIZONTAL
}],
['b', 210, 167.6, 163, 216, 105, 216, {
r: ROTATE_VERTICAL
}],
['b', 47, 216, -0, 167.6, 0, 108, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 48.4, 47, -0, 105, 0, {
r: ROTATE_VERTICAL
}],
['b', 156.3, 0, 199, 37.8, 208.2, 87.8, {
r: ROTATE_NONE
}],
['b', 208.2, 87.8, 259.8, 351.4, 93.5, 360],
['b', 50.3, 362.3, 21.9, 339.2, 3.6, 303.8, {
f: 1
}],
]
}]
)
};

890
src/font/special.js

@ -1,890 +0,0 @@ @@ -1,890 +0,0 @@
import {
generateFontData,
ROTATE_HORIZONTAL,
ROTATE_VERTICAL,
ROTATE_NONE,
VERTEX_GAP,
getR,
getCurveR,
VERTEX_GAP2
} from './util.js';
export const SPECIAL = {
' ': generateFontData(
336, 0, 0,
0, 0, 0, 0,
[{
d: 1,
v: []
}]
),
'tofu': generateFontData(
672, 232, 352,
0, 0, 0, 0,
[{
//c: 'square',
d: -1,
v: [
['m', 0, 0, {
r: ROTATE_HORIZONTAL
}],
['l', 232, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 232, 352, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 352, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1,
c: 1
}],
]
},
{
d: 1,
v: [
['m', 0, 0, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['l', 232, 352, {
r: ROTATE_NONE
}],
]
}
]
),
'?': generateFontData(
520, 190.348, 360,
0, -5, 0, 0,
[{
d: 1,
v: [
['a', 190.348 / 2 - 4, 360 - 4],
]
}, {
d: -1,
v: [
['m', 0, 87.8, {
r: getCurveR(0, 87.8, 12, -2.3, 99.1, 0, 0, 87.8, 0)
}],
['b', 0, 87.8, 12, -2.3, 99.1, 0, {
r: ROTATE_VERTICAL
}],
['b', 186.2, 2.4, 204.5, 75.2, 180.9, 121.4],
['b', 157.3, 167.6, 119.7, 178.3, 97.4, 223.2],
['b', 90.5, 237.1, 88.1, 249.8, 88, 260.8, {
r: ROTATE_HORIZONTAL,
f: 1
}],
]
}]
),
'!': generateFontData(
465, 8, 355,
0, -5, 0, 0,
[{
d: 1,
v: [
['a', 8 / 2, 355 - 1.5],
]
}, {
d: -1,
v: [
['m', 4, 0, {
y: 0
}],
['l', 4, 260.8, {
f: 1
}],
]
}]
),
'$': generateFontData(
568, 224, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 212, 51.3, {
r: getCurveR(0, 295.4, 17.6, 332.1, 58.3, 360, 110.3, 360, 0),
f: 1
}],
['b', 196.5, 20.5, 158.4, 0, 114.8, 0],
['b', 57.3, 0, 13.3, 29.8, 12, 84.4],
['b', 10.9, 130.6, 47.3, 157.7, 112.4, 173.3],
['b', 180.7, 189.6, 224.2, 214.7, 224, 271],
['b', 223.8, 329.6, 173.9, 360, 110.3, 360],
['b', 58.3, 360, 17.6, 332.1, 0, 295.4, {
f: 1
}],
]
}, {
d: -1,
v: [
['m', 112, 0 - 30, {
y: 0
}],
['l', 112, 360 + 30, {
y: 0,
f: 1
}],
]
}]
),
'@': generateFontData(
820, 343.425, 360,
0, 0, -30, -30,
[{
d: -1,
v: [
['m', 251.9, 92.9, {
r: getR(251.9, 92.9, 238.5, 181.7)
}],
['l', 238.5, 181.7, {
r: ROTATE_NONE
}],
['b', 227.8, 236, 194.7, 267.2, 143.7, 259.2],
['b', 99.1, 252.2, 87.7, 208.5, 90.1, 177.5],
['b', 92.5, 148.4, 118.1, 91, 183.3, 99.1],
['b', 251, 107.5, 238.5, 181.7, 238.5, 181.7, {
r: ROTATE_NONE
}],
['l', 232.5, 221.5],
['b', 232.5, 221.5, 227.2, 257.6, 256, 263.6],
['b', 284.9, 269.7, 309, 241.3, 309, 241.3, {
r: ROTATE_NONE
}],
['b', 309, 241.3, 343.4, 209, 343.4, 146.7],
['b', 343.4, 84.3, 297.4, 3.5, 178.6, 0.1],
['b', 59.7, -3.4, -5.3, 105.2, 0.3, 203.4],
['b', 6.1, 303.7, 93.2, 354.5, 175.5, 359.5],
['b', 175.5, 359.5, 246.5, 364.9, 302.7, 339.8, {
f: 1
}],
]
}]
),
'#': generateFontData(
760, 290 + 24, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 70 + 47, 0, {
y: 0,
r: getR(70 + 47, 0, 0 + 47, 352)
}],
['l', 0 + 47, 352, {
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 70 + 150 + 47, 0, {
y: 0,
r: getR(70 + 150 + 47, 0, 0 + 150 + 47, 352)
}],
['l', 0 + 150 + 47, 352, {
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0 + 24, 117, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 290 + 24, 117, {
x: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 352 - 117, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 290, 352 - 117, {
x: 0,
f: 1
}],
]
}]
),
'%': generateFontData(
920, 352 + 36, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 289.1 + 18, 5.1, {
x: 0,
y: 0,
r: getR(289.1 + 18, 5.1, 62.9 + 18, 354.9)
}],
['l', 62.9 + 18, 354.9, {
x: 0,
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 146, 73, {
r: ROTATE_HORIZONTAL,
p: 1,
}],
['b', 146, 113.3, 113.3, 146, 73, 146, {
r: ROTATE_VERTICAL
}],
['b', 32.7, 146, 0, 113.3, 0, 73, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 32.7, 32.7, 0, 73, 0, {
r: ROTATE_VERTICAL
}],
['b', 113.3, 0, 146, 32.7, 146, 73, {
r: ROTATE_HORIZONTAL,
c: 1,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 352 + 36, 287, {
r: ROTATE_HORIZONTAL,
p: 1,
}],
['b', 352 + 36, 327.3, 319.3 + 36, 360, 279 + 36, 360, {
r: ROTATE_VERTICAL
}],
['b', 238.7 + 36, 360, 206 + 36, 327.3, 206 + 36, 287, {
r: ROTATE_HORIZONTAL
}],
['b', 206 + 36, 246.7, 238.7 + 36, 214, 279 + 36, 214, {
r: ROTATE_VERTICAL
}],
['b', 319.3 + 36, 214, 352 + 36, 246.7, 352 + 36, 287, {
r: ROTATE_HORIZONTAL,
c: 1,
f: 1
}],
]
}]
),
'^': generateFontData(
596, 88 + 88, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 150, {
r: getR(0, 150, 88 - VERTEX_GAP, 0)
}],
['l', 88 - VERTEX_GAP, 0, {
r: getR(0, 150, 88 - VERTEX_GAP, 0),
f: 1
}],
['l', 88 + VERTEX_GAP2, 0, {
r: getR(88 + VERTEX_GAP2, 0, 88 + 88, 150),
f: 1,
v: 1
}],
['l', 88 + 88, 150, {
f: 1
}]
]
}]
),
'&': generateFontData(
660, 259.191, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 257.9, 355, {
x: 0.5,
y: 0.5,
r: getR(257.9, 355, 52.8, 135.3),
f: 1
}],
['l', 52.8, 135.3],
['b', 52.8, 135.3, -2.2, 79.5, 46.6, 26.7],
['b', 46.6, 26.7, 68.1, 0, 101.8, 0, {
r: ROTATE_VERTICAL
}],
['b', 137.2, 0, 174.1, 21.1, 181.2, 65.3],
['b', 188.6, 111.7, 142.6, 142.9, 108.9, 162.9],
['b', 75.2, 182.8, 40.8, 211.4, 40.8, 211.4, {
r: ROTATE_NONE
}],
['b', 35, 217.1, -34.7, 273.7, 22.2, 330.5],
['b', 22.2, 330.5, 48.1, 360, 93.4, 360, {
r: ROTATE_VERTICAL
}],
['b', 138.6, 360, 212.2, 322, 259.2, 200.5],
]
}]
),
'*': generateFontData(
558, 183.597, 212,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 91.8, 0, {
x: 0,
y: 0
}],
['l', 91.8, 212, {
x: 0,
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 53, {
x: 0,
y: 0,
r: getR(0, 53, 183.6, 159)
}],
['l', 183.6, 159, {
x: 0,
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 159, {
x: 0,
y: 0,
r: getR(0, 159, 183.6, 53)
}],
['l', 183.6, 53, {
x: 0,
y: 0,
f: 1
}],
]
}]
),
'+': generateFontData(
712, 250, 250,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 125, 0, {
x: 0,
y: 0,
}],
['l', 125, 250, {
x: 0,
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 125, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['l', 250, 125, {
x: 0,
y: 0,
f: 1
}],
]
}]
),
'=': generateFontData(
712, 216, 86,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['l', 216, 0, {
x: 0,
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 86, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['l', 216, 86, {
x: 0,
y: 0,
f: 1
}],
]
}]
),
'-': generateFontData(
712, 188, 0,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['l', 188, 0, {
x: 0,
y: 0,
f: 1
}],
]
}]
),
'_': generateFontData(
481, 235, 400,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 400, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['l', 235, 400, {
x: 0,
y: 0,
f: 1
}],
]
}]
),
':': generateFontData(
231, 8, 355,
0, 0, 0, 0,
[{
d: 1,
v: [
['a', 8 / 2, 355 - 1.5 - 170],
]
},
{
d: 1,
v: [
['a', 8 / 2, 355 - 1.5],
]
}
]
),
';': generateFontData(
231, 8, 355,
0, 0, 0, 0,
[{
d: 1,
v: [
['a', 8 / 2, 355 - 1.5 - 170],
]
}, {
d: -1,
v: [
['m', 8 / 2, 350, {
x: 0,
y: 2,
r: getR(8 / 2, 350, 8 / 2 - 10, 80 + 350)
}],
['l', 8 / 2 - 10, 80 + 350, {
x: 0,
y: 0.5,
f: 1
}],
]
}]
),
'.': generateFontData(
231, 8, 355,
0, 0, 0, 0,
[{
d: 1,
v: [
['a', 8 / 2, 355 - 1.5],
]
}]
),
',': generateFontData(
231, 10, 355,
10, 10, 0, 0,
[{
d: -1,
v: [
['m', 10, 350, {
x: 0,
y: 2,
r: getR(10, 350, 0, 80 + 350)
}],
['l', 0, 80 + 350, {
x: 0,
y: 0.5,
f: 1
}],
]
}]
),
"'": generateFontData(
173, 0, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0,
y: 0
}],
['l', 0, 80, {
x: 0,
y: 0,
f: 1
}],
]
}]
),
'"': generateFontData(
297, 60, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: -1.5,
y: 0
}],
['l', 0, 80, {
x: -1.5,
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 60, 0, {
x: -1.5,
y: 0
}],
['l', 60, 80, {
x: -1.5,
y: 0,
f: 1
}],
]
}]
),
'~': generateFontData(
731, 199.391, 47.063,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 199.4, 20.7, {
x: 0,
y: 0,
r: getCurveR(199.4, 20.7, 187.6, 36.6, 168.2, 47.1, 148.2, 47.1, 0),
f: 1
}],
['b', 187.6, 36.6, 168.2, 47.1, 148.2, 47.1, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['b', 129.1, 47.1, 112.1, 36.6, 95.3, 25.5, {
x: 0,
y: 0
}],
['b', 76.8, 13.2, 59.1, 0, 39.6, 0, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['b', 22.3, 0, 10.9, 8.9, 0, 20, {
x: 0,
y: 0
}],
]
}]
),
'(': generateFontData(
365, 107.865, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 107.9, 360, {
y: 0.8,
r: getCurveR(107.9, 360, 39.7, 321.1, 0, 259.8, 0, 182.9, 0),
f: 1
}],
['b', 39.7, 321.1, 0, 259.8, 0, 182.9, {
y: 0.8,
r: ROTATE_HORIZONTAL
}],
['b', 0, 100.2, 39.7, 38.9, 107.9, 0, {
y: 0.8
}],
]
}]
),
')': generateFontData(
365, 107.865, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
y: 0.8,
r: getCurveR(0, 0, 68.2, 38.9, 107.9, 100.2, 107.9, 177, 0)
}],
['b', 68.2, 38.9, 107.9, 100.2, 107.9, 177, {
y: 0.8,
r: ROTATE_HORIZONTAL
}],
['b', 107.9, 259.8, 68.2, 321.1, 0, 360, {
y: 0.8,
f: 1
}],
]
}]
),
'{': generateFontData(
385, 107.865, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 94.5, 360, {
x: -0.5,
r: ROTATE_VERTICAL
}],
['l', 77.9, 360, {
x: -0.5
}],
['b', 57.4, 360, 37, 343, 37, 310.7, {
x: -0.5
}],
['l', 37, 233.4, {
x: -0.5
}],
['b', 37, 207.9, 24.3, 183.7, 3.8, 180.7, {
x: -0.5,
r: ROTATE_VERTICAL
}],
['l', 3.8, 179.8, {
x: -0.5,
r: ROTATE_VERTICAL,
p: 1
}],
['b', 24.3, 176.8, 37, 153.1, 37, 126.7, {
x: -0.5
}],
['l', 37, 49.4, {
x: -0.5
}],
['b', 37, 17.1, 57.4, 0.1, 77.9, 0.1, {
x: -0.5
}],
['l', 94.5, 0.1, {
x: -0.5,
}],
]
}]
),
'}': generateFontData(
385, 107.865, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 13.4, 0.1, {
x: -0.5,
r: ROTATE_VERTICAL
}],
['l', 30, 0.1, {
x: -0.5
}],
['b', 50.4, 0.1, 70.8, 17.1, 70.8, 49.4, {
x: -0.5
}],
['l', 70.8, 126.7, {
x: -0.5
}],
['b', 70.8, 153.1, 83.6, 176.8, 104, 179.8, {
x: -0.5,
r: ROTATE_VERTICAL
}],
['l', 104, 180.7, {
x: -0.5,
r: ROTATE_VERTICAL,
p: 1
}],
['b', 83.6, 183.7, 70.8, 207.9, 70.8, 233.4, {
x: -0.5
}],
['l', 70.8, 310.7, {
x: -0.5
}],
['b', 70.8, 343, 50.4, 360, 30, 360, {
x: -0.5
}],
['l', 13.4, 360, {
x: -0.5
}],
]
}]
),
'[': generateFontData(
365, 66, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 66, 0, {
x: -1,
r: ROTATE_VERTICAL
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 352, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 66, 352, {
x: -1,
f: 1
}],
]
}]
),
']': generateFontData(
365, 66, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: -1,
r: ROTATE_VERTICAL
}],
['l', 66, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 66, 352, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 352, {
x: -1,
f: 1
}],
]
}]
),
'<': generateFontData(
423, 90, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 90, 0, {
x: -1,
y: 0.3,
r: getR(90, 0, 0, 176)
}],
['l', 0, 176, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 90, 352, {
x: -1,
y: 0.3,
f: 1
}],
]
}]
),
'>': generateFontData(
423, 90, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: -1,
y: 0.3,
r: getR(0, 0, 90, 176)
}],
['l', 90, 176, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 352, {
x: -1,
y: 0.3,
f: 1
}],
]
}]
),
'/': generateFontData(
433, 130, 352,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 0, 352, {
r: getR(0, 352, 130, 0),
f: 1,
y: 0
}],
['l', 130, 0, {
y: 0
}]
]
}]
)
};

892
src/font/upper.js

@ -1,892 +0,0 @@ @@ -1,892 +0,0 @@
import {
generateFontData,
ROTATE_HORIZONTAL,
ROTATE_VERTICAL,
ROTATE_NONE,
VERTEX_GAP,
VERTEX_GAP2,
getR,
getCurveR
} from './util.js';
export const UPPER = {
'A': generateFontData(
620, 290, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 352, {
x: 0.55,
y: 0.3,
r: getR(0, 352, 145 - VERTEX_GAP2, 0),
}],
['l', 145 - VERTEX_GAP2, 0, {
r: getR(0, 352, 145 - VERTEX_GAP2, 0),
f: 1
}],
['l', 145 + VERTEX_GAP2, 0, {
r: getR(290, 352, 145 + VERTEX_GAP2, 0),
f: 1,
v: 1
}],
['l', 290, 352, {
x: 0.55,
y: 0.3,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 47, 237, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 243, 237, {
r: ROTATE_VERTICAL,
p: 1,
f: 1,
}],
]
}
]
),
'B': generateFontData(
596, 209, 352,
-10, -10, 0, 0,
[{
d: 1,
v: [
['m', 0, 164, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 116, 164, {
r: ROTATE_VERTICAL,
p: 1,
f: 1
}],
['b', 167.4, 164, 209, 205.6, 209, 257, {
r: ROTATE_HORIZONTAL
}],
['b', 209, 308.4, 167.4, 352, 116, 352, {
r: ROTATE_VERTICAL
}],
['l', 0, 352, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 161.3, 0, 198, 36.7, 198, 82, {
r: ROTATE_HORIZONTAL
}],
['b', 198, 127.3, 161.3, 164, 116, 164, {
r: ROTATE_VERTICAL
}]
]
}]
),
'C': generateFontData(
700, 293.1, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 293.1, 320.1, {
r: getCurveR(293.1, 320.1, 262.2, 345, 222.8, 360, 180, 360, 0),
f: 1
}],
['b', 262.2, 345, 222.8, 360, 180, 360],
['b', 80.6, 360, 0, 279.4, 0, 180],
['b', 0, 80.6, 80.6, 0, 180, 0],
['b', 222.8, 0, 262.2, 15, 293.1, 39.9],
]
}]
),
'D': generateFontData(
721, 270, 352,
-10, -10, 0, 0,
[{
//c: 'square',
d: -1,
v: [
['m', 95, 352, {
r: ROTATE_VERTICAL,
f: 1
}],
['b', 191.6, 352, 270, 271.6, 270, 175, {
r: ROTATE_HORIZONTAL
}],
['b', 270, 78.4, 191.6, 0, 95, 0, {
r: ROTATE_VERTICAL
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 352, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 95, 352, {
r: ROTATE_VERTICAL,
f: 1
}],
]
}]
),
'E': generateFontData(
520, 192, 352,
-5, -80, 0, 0,
[{
d: -1,
v: [
['m', 192, 0, {
x: 0,
r: ROTATE_VERTICAL,
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1,
x: 0.5
}],
['l', 0, 352, {
f: 1,
x: 0.5
}],
['l', 192, 352, {
x: 0,
r: ROTATE_VERTICAL,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 0, 164, {
r: ROTATE_VERTICAL,
p: 1,
x: 0.5
}],
['l', 180, 164, {
x: 0,
r: ROTATE_VERTICAL,
f: 1
}],
]
}
]
),
'F': generateFontData(
510, 192, 352,
-5, -80, 0, 0,
[{
d: -1,
v: [
['m', 192, 0, {
x: 0,
r: ROTATE_VERTICAL,
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1,
x: 0.5
}],
['l', 0, 352, {
y: 0,
f: 1,
x: 0.5
}],
]
},
{
d: -1,
v: [
['m', 0, 164, {
r: ROTATE_VERTICAL,
p: 1,
x: 0.5
}],
['l', 180, 164, {
x: 0,
r: ROTATE_VERTICAL,
f: 1
}],
]
}
]
),
'G': generateFontData(
840, 352, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 202, 180, {
r: ROTATE_VERTICAL,
f: 1
}],
['l', 352, 180, {
f: 1
}],
['b', 352, 279.4, 279.4, 360, 180, 360, {
r: ROTATE_VERTICAL
}],
['b', 80.6, 360, 0, 279.4, 0, 180, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 80.6, 80.6, 0, 180, 0, {
r: ROTATE_VERTICAL
}],
['b', 222.8, 0, 262.1, 14.9, 293, 39.9],
]
}]
),
'H': generateFontData(
684, 232, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 232, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 232, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 0, 164, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 232, 164, {
r: ROTATE_VERTICAL,
f: 1,
p: 1
}],
]
},
]
),
'I': generateFontData(
249, 0, 352,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 0, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
]
}, ]
),
'J': generateFontData(
472, 172.5, 355.5,
10, 20, -2, -2,
[{
d: 1,
v: [
['m', 0, 310.5 + 0.5, {
r: getCurveR(0, 310.5 + 0.5, 16.2, 341.1 + 0.5, 49.3, 355.5 + 0.5, 86, 355.5 + 0.5, 0),
f: 1
}],
['b', 16.2, 341.1 + 0.5, 49.3, 355.5 + 0.5, 86, 355.5 + 0.5, {
r: ROTATE_VERTICAL
}],
['b', 133.5, 355.5 + 0.5, 172, 317 + 0.5, 172, 269.5 + 0.5],
['l', 172.5, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
]
}, ]
),
'K': generateFontData(
616, 232, 352,
-10, -20, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 212, 0, {
x: 0.7,
y: 0.7,
r: getR(212, 0, 0, 164 - VERTEX_GAP2),
}],
['l', 0, 164 - VERTEX_GAP2, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 0, 164 + VERTEX_GAP2, {
r: ROTATE_VERTICAL,
p: 1,
v: 1
}],
['l', 232, 352, {
x: 0.7,
y: 0.7,
f: 1
}],
]
}
]
),
'L': generateFontData(
529, 192, 352,
-10, -20, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
y: 0
}],
['l', 0, 352, {
f: 1
}],
['l', 192, 352, {
x: 0,
f: 1
}],
]
}]
),
'M': generateFontData(
885, 330, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 352, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0 + VERTEX_GAP, 0, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1,
v: 1
}],
['l', 165 - VERTEX_GAP2, 330, {
r: getR(165 - VERTEX_GAP2, 330, 165 - VERTEX_GAP2, 330),
f: 1
}],
['l', 165 + VERTEX_GAP2, 330, {
r: getR(165 + VERTEX_GAP2, 330, 330 - VERTEX_GAP, 0),
f: 1,
v: 1
}],
['l', 330 - VERTEX_GAP, 0, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['l', 330, 0, {
r: ROTATE_HORIZONTAL,
f: 1,
v: 1
}],
['l', 330, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
]
}]
),
'N': generateFontData(
721, 250, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 352, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0 + VERTEX_GAP, 0, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1,
v: 1
}],
['l', 250 - VERTEX_GAP, 351, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['l', 250, 351, {
r: ROTATE_HORIZONTAL,
f: 1,
v: 1
}],
['l', 250, 0, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
]
}]
),
'O': generateFontData(
850, 360, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 360, 180, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['b', 360, 279.4, 279.4, 360, 180, 360, {
r: ROTATE_VERTICAL
}],
['b', 80.6, 360, 0, 279.4, 0, 180, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 80.6, 80.6, 0, 180, 0, {
r: ROTATE_VERTICAL
}],
['b', 279.4, 0, 360, 80.6, 360, 180, {
r: ROTATE_HORIZONTAL,
c: 1
}],
]
}]
),
'P': generateFontData(
568, 210, 352,
-10, -10, -0.5, -0.5,
[{
d: 1,
v: [
['m', 0, 352, {
y: 0,
f: 1
}],
['l', 0, 0, {
f: 1
}],
['l', 117, 0, {
r: ROTATE_VERTICAL
}],
['b', 168.4, 0, 210, 41.6, 210, 93, {
r: ROTATE_HORIZONTAL
}],
['b', 210, 144.4, 168.4, 186, 117, 186, {
r: ROTATE_VERTICAL
}],
['l', 0, 186, {
r: ROTATE_VERTICAL,
p: 1
}],
]
}]
),
'Q': generateFontData(
850, 360, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 360, 180, {
r: ROTATE_VERTICAL,
p: 1,
f: 1
}],
['b', 360, 80.6, 279.4, 0, 180, 0, {
r: ROTATE_VERTICAL
}],
['b', 80.6, 0, 0, 80.6, 0, 180, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 279.4, 80.6, 360, 180, 360, {
r: ROTATE_VERTICAL
}],
['b', 279.4, 360, 360, 279.4, 360, 180, {
r: ROTATE_HORIZONTAL,
c: 1,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 222, 222, {
x: 0.5,
y: 0.5,
r: getR(222, 222, 360, 360),
}],
['l', 360, 360, {
x: 0.5,
y: 0.5,
f: 1
}]
]
}
]
),
'R': generateFontData(
634, 232, 352,
-10, -10, -0.5, -0.5,
[{
d: -1,
v: [
['m', 0, 186, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 139, 186, {
r: ROTATE_VERTICAL
}],
['b', 190.4, 186, 232, 144.4, 232, 93, {
r: ROTATE_HORIZONTAL
}],
['b', 232, 41.6, 190.4, 0, 139, 0, {
r: ROTATE_VERTICAL
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 352, {
y: 0,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 139, 186, {
p: 1,
r: getR(139, 186, 232, 352),
}],
['l', 232, 352, {
x: 0.5,
y: 0.39,
f: 1
}],
]
}
]
),
'S': generateFontData(
560, 224, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 0, 295.4, {
r: getCurveR(0, 295.4, 17.6, 332.1, 58.3, 360, 110.3, 360, 0),
f: 1
}],
['b', 17.6, 332.1, 58.3, 360, 110.3, 360],
['b', 173.9, 360, 223.8, 329.6, 224, 271],
['b', 224.2, 214.7, 180.7, 189.6, 112.4, 173.3],
['b', 47.3, 157.7, 10.9, 130.6, 12, 84.4],
['b', 13.3, 29.8, 57.3, 0, 114.8, 0],
['b', 158.4, 0, 196.5, 20.5, 212, 51.3],
]
}]
),
'T': generateFontData(
568, 232, 352,
0, 0, -0.5, -0.5,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 232, 0, {
x: 0,
r: ROTATE_VERTICAL,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 116, 0, {
r: ROTATE_HORIZONTAL,
p: 1
}],
['l', 116, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
]
}
]
),
'U': generateFontData(
712, 250, 355,
0, 0, -0.5, -0.5,
[{
d: 1,
v: [
['m', 250, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 250, 230 + 1, {
r: ROTATE_HORIZONTAL
}],
['b', 250, 299 + 1, 194, 355 + 1, 125, 355 + 1, {
r: ROTATE_VERTICAL
}],
['b', 56, 355 + 1, 0, 299 + 1, 0, 230 + 1, {
r: ROTATE_HORIZONTAL
}],
['l', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
]
}]
),
'V': generateFontData(
650, 270, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0.6,
y: 0.1,
r: getR(0, 0, 135 - VERTEX_GAP2, 352),
}],
['l', 135 - VERTEX_GAP2, 352, {
r: getR(0, 0, 135 - VERTEX_GAP2, 352),
f: 1
}],
['l', 135 + VERTEX_GAP2, 352, {
r: getR(135 + VERTEX_GAP2, 352, 270, 0),
f: 1,
v: 1
}],
['l', 270, 0, {
x: 0.6,
y: 0.1,
f: 1
}],
]
}]
),
'W': generateFontData(
894, 390, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0.6,
y: 0.05,
r: getR(0, 0, 86 - VERTEX_GAP2, 352),
}],
['l', 86 - VERTEX_GAP2, 352, {
r: getR(0, 0, 86 - VERTEX_GAP2, 352),
f: 1
}],
['l', 86 + VERTEX_GAP2, 352, {
r: getR(86 + VERTEX_GAP2, 352, 195 - VERTEX_GAP2, 0),
f: 1,
v: 1
}],
['l', 195 - VERTEX_GAP2, 0, {
r: getR(86 + VERTEX_GAP2, 352, 195 - VERTEX_GAP2, 0),
f: 1
}],
['l', 195 + VERTEX_GAP2, 0, {
r: getR(195 + VERTEX_GAP2, 0, 304 - VERTEX_GAP2, 352),
f: 1,
v: 1
}],
['l', 304 - VERTEX_GAP2, 352, {
r: getR(195 + VERTEX_GAP2, 0, 304 - VERTEX_GAP2, 352),
f: 1
}],
['l', 304 + VERTEX_GAP2, 352, {
r: getR(304 + VERTEX_GAP2, 352, 390, 0),
f: 1,
v: 1
}],
['l', 390, 0, {
x: 0.6,
y: 0.05,
f: 1
}],
]
}]
),
'X': generateFontData(
660, 270, 352,
0, 0, 0, -7,
[{
d: -1,
v: [
['m', 10, 0, {
x: 0.5,
y: 0.3,
r: getR(10, 0, 270, 352),
}],
['l', 270, 352, {
x: 0.5,
y: 0.5,
f: 1
}]
]
},
{
d: -1,
v: [
['m', 260, 0, {
x: 0.5,
y: 0.3,
r: getR(260, 0, 0, 352),
}],
['l', 0, 352, {
x: 0.5,
y: 0.5,
f: 1
}]
]
}
]
),
'Y': generateFontData(
673, 270, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0.6,
y: 0.3,
r: getR(0, 0, 135, 186),
}],
['l', 135, 186, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 270, 0, {
x: 0.6,
y: 0.3,
f: 1
}]
]
},
{
d: -1,
v: [
['m', 135, 186, {
r: ROTATE_HORIZONTAL,
p: 1
}],
['l', 135, 352, {
y: 0,
f: 1
}],
]
}
]
),
'Z': generateFontData(
558, 232, 352,
0, -5, 0, 0,
[{
d: -1,
v: [
['m', 8, 0, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 224, 0, {
r: ROTATE_VERTICAL,
f: 1
}],
['l', 224, 0 + VERTEX_GAP, {
r: ROTATE_HORIZONTAL,
p: 1,
v: 1
}],
['l', 0, 352 - VERTEX_GAP, {
r: ROTATE_HORIZONTAL,
p: 1
}],
['l', 0, 352, {
r: ROTATE_VERTICAL,
f: 1,
v: 1
}],
['l', 232, 352, {
x: 0,
r: ROTATE_VERTICAL,
f: 1
}]
]
}]
)
};

76
src/font/util.js

@ -1,76 +0,0 @@ @@ -1,76 +0,0 @@
import {
Vector
} from '../core/vector.js';
import {
bezierTangent
} from '../core/paths.js';
export const ROTATE_HORIZONTAL = 180 * (Math.PI / 180);
export const ROTATE_VERTICAL = 90 * (Math.PI / 180);
export const ROTATE_NONE = -100;
export const VERTEX_GAP = 3;
export const VERTEX_GAP2 = VERTEX_GAP / 2;
export const TOFU = 'tofu';
const FONT_HEIGHT = 824;
export function generateFontData(w, fw, fh, x1, x2, y1, y2, path) {
const arr = [];
const total = path.length;
let i;
for (i = 0; i < total; i++) {
arr.push({
d: path[i].d,
v: setCenter(path[i].v, fw, fh)
});
}
return {
rect: {
w: w,
h: FONT_HEIGHT,
fw: fw,
fh: fh
},
ratio: {
x1: x1,
x2: x2,
y1: y1,
y2: y2,
},
p: arr
};
}
function setCenter(arr, fw, fh) {
const total = arr.length;
const cx = fw / 2;
const cy = fh / 2;
let mp, i, ct = [];
for (i = 0; i < total; i++) {
mp = arr[i];
mp[1] -= cx;
mp[2] -= cy;
if (mp[0] == 'b') {
mp[3] -= cx;
mp[4] -= cy;
mp[5] -= cx;
mp[6] -= cy;
}
ct.push(new Vector(mp));
}
return ct;
}
export function getR(x1, y1, x2, y2) {
const x = x1 - x2;
const y = y1 - y2;
return -Math.atan2(x, y);
}
export function getCurveR(x1, y1, x2, y2, x3, y3, x4, y4, t) {
const x = bezierTangent(x1, x2, x3, x4, t);
const y = bezierTangent(y1, y2, y3, y4, t);
return -Math.atan2(x, y);
}

2
src/index.js

@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
const LeonSans = require('./LeonSans').default;
module.exports = LeonSans;

521
src/leonsans.js

@ -1,521 +0,0 @@ @@ -1,521 +0,0 @@
import {
Dispatcher
} from './core/dispatcher.js';
import {
MIN_FONT_WEIGHT,
MAX_FONT_WEIGHT,
shuffle
} from './core/util.js';
import {
Lines
} from './draw/canvas/lines.js';
import {
Points
} from './draw/canvas/points.js';
import {
Grids
} from './draw/canvas/grids.js';
import {
Wave
} from './draw/canvas/wave.js';
import {
Pattern
} from './draw/canvas/pattern.js';
import {
Color
} from './draw/canvas/color.js';
import {
Colorful
} from './draw/canvas/colorful.js';
import {
PixiLines
} from './draw/pixi/lines.js';
import {
PixiColor
} from './draw/pixi/color.js';
import {
Model
} from './core/model.js';
export default class LeonSans extends Dispatcher {
constructor({
text = '',
size = 500,
weight = MIN_FONT_WEIGHT,
color = ['#000000'],
colorful = ['#c5d73f', '#9d529c', '#49a9db', '#fec330', '#5eb96e', '#fc5356', '#f38f31'],
tracking = 0,
leading = 0,
align = 'left',
pathGap = 0.5,
amplitude = 0.5,
width = 0,
breakWord = false,
fps = 30,
isPath = false,
isWave = false,
} = {}) {
super();
this.size_ = size;
this.weight_ = weight;
this.color_ = color;
this.colorful_ = shuffle(colorful);
this.tracking_ = tracking;
this.leading_ = leading;
this.pathGap_ = pathGap;
this.amplitude_ = amplitude;
this.width_ = width;
this.breakWord_ = breakWord;
this.fps_ = fps;
this.fpsTime_ = 1000 / this.fps_;
this.isPath_ = isPath;
this.isWave_ = isWave;
this.model = new Model();
this.str_ = null;
this.time_ = null;
this.isFps_ = false;
this.isForceRander_ = false;
this.updateID_ = 0;
this.dPathsID_ = null;
this.pPathsID_ = null;
this.wPathsID_ = null;
this.guideID_ = null;
this.text = text;
this.model.align = align;
}
on(event, callback) {
super.on(event, callback);
this.update();
}
off(event, callback) {
super.off(event, callback);
}
get text() {
return this.str_;
}
set text(str) {
if (this.str_ == str) return;
this.str_ = str;
this.update();
}
get size() {
return this.size_;
}
set size(v) {
if (this.size_ == v) return;
this.size_ = v;
this.update();
this.isForceRander_ = true;
}
get weight() {
return this.weight_;
}
set weight(v) {
if (v < MIN_FONT_WEIGHT) {
v = MIN_FONT_WEIGHT;
} else if (v > MAX_FONT_WEIGHT) {
v = MAX_FONT_WEIGHT;
}
if (this.weight_ == v) return;
this.weight_ = v;
this.update();
this.isForceRander_ = true;
}
get color() {
return this.color_;
}
set color(v) {
if (this.color_ == v) return;
this.color_ = v;
}
get tracking() {
return this.tracking_;
}
set tracking(v) {
if (this.tracking_ == v) return;
this.tracking_ = v;
this.update();
this.isForceRander_ = true;
}
get leading() {
return this.leading_;
}
set leading(v) {
if (this.leading_ == v) return;
this.leading_ = v;
this.update();
this.isForceRander_ = true;
}
get align() {
return this.model.align;
}
set align(v) {
if (this.model.align != v) {
this.model.align = v;
this.updateID_++;
this.updateSignal();
}
}
get pathGap() {
return this.pathGap_;
}
set pathGap(v) {
if (this.pathGap_ != v) {
this.pathGap_ = v;
this.updatePatternPaths(true);
this.updateWavePaths(true);
this.isForceRander_ = true;
}
}
get amplitude() {
return this.amplitude_;
}
set amplitude(v) {
this.amplitude_ = v;
}
get rect() {
return this.model.rect;
}
set maxWidth(v) {
if (this.width_ == v) return;
this.width_ = v;
this.update();
}
get maxWidth() {
return this.width_;
}
set breakWord(v) {
if (this.breakWord_ == v) return;
this.breakWord_ = v;
this.update();
}
get breakWord() {
return this.breakWord_;
}
get isPath() {
return this.isPath_;
}
set isPath(v) {
this.isPath_ = v;
this.updatePatternPaths(true);
}
get isWave() {
return this.isWave_;
}
set isWave(v) {
this.isWave_ = v;
this.updateWavePaths(true);
}
get fps() {
return this.fps_;
}
set fps(v) {
this.fps_ = v;
this.fpsTime_ = 1000 / this.fps_;
}
get lineWidth() {
return this.model.lineWidth;
}
get scale() {
return this.model.scale;
}
get drawing() {
return this.model.drawing;
}
get data() {
return this.model.data;
}
get paths() {
return this.model.paths;
}
get drawingPaths() {
return this.model.drawingPaths;
}
get wavePaths() {
return this.model.wavePaths;
}
position(x = 0, y = 0) {
if (this.model.position(x, y)) {
this.updateID_++;
this.updateSignal();
}
}
update() {
this.updateID_++;
this.model.update(
this.str_,
this.width_,
this.breakWord_,
this.weight_,
this.size_,
this.tracking_,
this.leading_
);
if (this.isPath_ || this.isWave_) {
this.updatePatternPaths();
this.updateWavePaths();
} else {
this.updateSignal();
}
}
updateGuide() {
if (this.guideID_ != this.updateID_) {
this.guideID_ = this.updateID_;
this.model.updateGuide();
}
}
/**
* Update paths for drawing in WebGL (PIXI.js). It's very expensive, only call when it needs.
*/
updateDrawingPaths() {
if (this.dPathsID_ != this.updateID_) {
this.dPathsID_ = this.updateID_;
this.model.updateDrawingPaths();
}
}
/**
* Update paths for pattern
* @param {boolean} force - Force execution
*/
updatePatternPaths(force) {
if (this.isPath_ && (force || this.pPathsID_ != this.updateID_)) {
this.pPathsID_ = this.updateID_;
this.model.updatePatternPaths(this.pathGap_);
this.isForceRander_ = true;
this.updateSignal();
}
}
/**
* Update paths for wave effect
* @param {boolean} force - Force execution
*/
updateWavePaths(force) {
if (this.isWave_ && (force || this.wPathsID_ != this.updateID_)) {
this.wPathsID_ = this.updateID_;
this.model.updateWavePaths(this.pathGap_);
this.isForceRander_ = true;
this.updateSignal();
}
}
updateSignal() {
this.model.updateLinesForRect();
this.model.updatePathsForRect();
this.dispatch('update', this.model);
}
reset() {
this.size_ = 500;
this.weight_ = MIN_FONT_WEIGHT;
this.color_ = ['#000000'];
this.tracking_ = 0;
this.leading_ = 0;
this.pathGap_ = 0.5;
this.amplitude_ = 0.5;
this.width_ = 0;
this.breakWord_ = false;
this.fps_ = 30;
this.fpsTime_ = 1000 / this.fps_;
this.isPath_ = false;
this.isWave_ = false;
this.str_ = null;
this.time_ = null;
this.isFps_ = false;
this.isForceRander_ = false;
this.updateID_ = 0;
this.dPathsID_ = null;
this.pPathsID_ = null;
this.wPathsID_ = null;
this.guideID_ = null;
this.model.reset();
}
dispose() {
this.reset();
this.model = null;
}
/**
* Draw text in WebGL with PIXI.js
* @param {PIXI.Graphics} graphics
*/
drawPixi(graphics) {
const total = this.model.data.length;
let i, d, color;
for (i = 0; i < total; i++) {
d = this.model.data[i];
color = PixiColor(i, d, this.color_);
PixiLines(graphics, d, this.lineWidth, color);
}
}
/**
* Draw text in the Canvas element.
* @param {CanvasRenderingContext2D} ctx
*/
draw(ctx) {
ctx.lineWidth = this.lineWidth;
const total = this.model.data.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.model.data[i];
Color(ctx, i, d, this.color_);
Lines(ctx, d);
}
}
/**
* Draw the colorful effect.
* @param {CanvasRenderingContext2D} ctx
*/
drawColorful(ctx) {
ctx.lineWidth = this.lineWidth;
Colorful(ctx, this.model, this.colorful_);
}
/**
* Draw the wave effect.
* @param {CanvasRenderingContext2D} ctx
* @param {DOMHighResTimeStamp} t time stemp from requestAnimationFrame()
*/
wave(ctx, t) {
ctx.lineWidth = this.lineWidth;
if (t) {
if (!this.time_) this.time_ = t;
const p = t - this.time_;
if (p > this.fpsTime_ || this.isForceRander_) {
this.time_ = t;
this.isFps_ = true;
} else {
this.isFps_ = false;
}
}
this.isForceRander_ = false;
const total = this.model.data.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.model.data[i];
Color(ctx, i, d, this.color_);
Wave(ctx, d, this.model.scale, this.amplitude_, this.weight_, this.isFps_);
}
}
/**
* Draw rectangle shapes at each path point.
* @param {CanvasRenderingContext2D} ctx
* @param {number} w pattern width
* @param {number} h pattern height
*/
pattern(ctx, w, h) {
const tw = w * this.model.scale;
const th = h * this.model.scale;
const total = this.model.data.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.model.data[i];
Pattern(ctx, d, tw, th);
}
}
/**
* Draw grid for each type.
* @param {CanvasRenderingContext2D} ctx
*/
grid(ctx) {
this.updateGuide();
const total = this.model.data.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.model.data[i];
Grids(ctx, d);
}
}
/**
* Draw circles at each drawing point and lines for each type.
* @param {CanvasRenderingContext2D} ctx
*/
point(ctx) {
const total = this.model.data.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.model.data[i];
Points(ctx, d);
}
}
/**
* Draw outline box for the text.
* @param {CanvasRenderingContext2D} ctx
* @private
*/
box(ctx) {
ctx.lineWidth = 1;
ctx.beginPath();
ctx.strokeStyle = "#0b90dc";
ctx.rect(this.model.rect.x, this.model.rect.y, this.model.rect.w, this.model.rect.h);
ctx.stroke();
}
}
Loading…
Cancel
Save