steal fizzyText
This commit is contained in:
parent
f53853e2ac
commit
494676b78a
@ -1,8 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<script src="./index.js"></script>
|
|
||||||
<section class="hero is-info is-large">
|
<section class="hero is-info is-large">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@ -58,6 +57,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id='fizzytext'></div>
|
||||||
|
|
||||||
<div class="hero-foot">
|
<div class="hero-foot">
|
||||||
<nav class="tabs is-boxed is-fullwidth">
|
<nav class="tabs is-boxed is-fullwidth">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@ -84,6 +85,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="./index.js"></script>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
const { toast } = require('bulma-toast');
|
const { toast } = require('bulma-toast');
|
||||||
|
|
||||||
|
const fizzyText = require('./src/fizzy-text');
|
||||||
|
|
||||||
|
fizzyText('cryps');
|
||||||
|
|
||||||
const cbor = require('borc');
|
const cbor = require('borc');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
// Create WebSocket connection.
|
// Create WebSocket connection.
|
||||||
@ -72,4 +76,5 @@ ws.addEventListener('error', function (event) {
|
|||||||
ws.addEventListener('close', function (event) {
|
ws.addEventListener('close', function (event) {
|
||||||
console.error('WebSocket closed', event);
|
console.error('WebSocket closed', event);
|
||||||
account = null;
|
account = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -12,11 +12,11 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"borc": "^2.0.3",
|
"borc": "^2.0.3",
|
||||||
"bulma-toast": "^1.2.0",
|
"bulma-toast": "^1.2.0",
|
||||||
"parcel": "^1.9.7",
|
|
||||||
"docco": "^0.7.0",
|
"docco": "^0.7.0",
|
||||||
"eslint": "^3.18.0",
|
"eslint": "^3.18.0",
|
||||||
"eslint-config-airbnb-base": "^11.1.1",
|
"eslint-config-airbnb-base": "^11.1.1",
|
||||||
"eslint-plugin-import": "^2.2.0",
|
"eslint-plugin-import": "^2.2.0",
|
||||||
"jest": "^18.0.0"
|
"jest": "^18.0.0",
|
||||||
|
"parcel": "^1.9.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
181
client/src/fizzy-noise.js
Normal file
181
client/src/fizzy-noise.js
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
// http://mrl.nyu.edu/~perlin/noise/
|
||||||
|
|
||||||
|
var ImprovedNoise = function () {
|
||||||
|
|
||||||
|
var p = [151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,
|
||||||
|
23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,
|
||||||
|
174,20,125,136,171,168,68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,
|
||||||
|
133,230,220,105,92,41,55,46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,
|
||||||
|
89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,250,124,123,5,
|
||||||
|
202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,
|
||||||
|
248,152,2,44,154,163,70,221,153,101,155,167,43,172,9,129,22,39,253,19,98,108,110,79,113,224,232,
|
||||||
|
178,185,112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,
|
||||||
|
14,239,107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,150,254,138,236,205,
|
||||||
|
93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180];
|
||||||
|
|
||||||
|
for ( var i = 0; i < 256 ; i++ ) {
|
||||||
|
|
||||||
|
p[ 256 + i ] = p[ i ];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function fade( t ) {
|
||||||
|
|
||||||
|
return t * t * t * ( t * ( t * 6 - 15 ) + 10 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function lerp( t, a, b ) {
|
||||||
|
|
||||||
|
return a + t * ( b - a );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function grad( hash, x, y, z ) {
|
||||||
|
|
||||||
|
var h = hash & 15;
|
||||||
|
var u = h < 8 ? x : y, v = h < 4 ? y : h == 12 || h == 14 ? x : z;
|
||||||
|
return ( ( h & 1 ) == 0 ? u : -u ) + ( ( h & 2 ) == 0 ? v : -v );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
noise: function ( x, y, z ) {
|
||||||
|
|
||||||
|
var floorX = Math.floor( x ), floorY = Math.floor( y ), floorZ = Math.floor( z );
|
||||||
|
|
||||||
|
var X = floorX & 255, Y = floorY & 255, Z = floorZ & 255;
|
||||||
|
|
||||||
|
x -= floorX;
|
||||||
|
y -= floorY;
|
||||||
|
z -= floorZ;
|
||||||
|
|
||||||
|
var xMinus1 = x -1, yMinus1 = y - 1, zMinus1 = z - 1;
|
||||||
|
|
||||||
|
var u = fade( x ), v = fade( y ), w = fade( z );
|
||||||
|
|
||||||
|
var A = p[ X ] + Y, AA = p[ A ] + Z, AB = p[ A + 1 ] + Z, B = p[ X + 1 ] + Y, BA = p[ B ] + Z, BB = p[ B + 1 ] + Z;
|
||||||
|
|
||||||
|
return lerp( w, lerp( v, lerp( u, grad( p[ AA ], x, y, z ),
|
||||||
|
grad( p[ BA ], xMinus1, y, z ) ),
|
||||||
|
lerp( u, grad( p[ AB ], x, yMinus1, z ),
|
||||||
|
grad( p[ BB ], xMinus1, yMinus1, z ) ) ),
|
||||||
|
lerp( v, lerp( u, grad( p[ AA + 1 ], x, y, zMinus1 ),
|
||||||
|
grad( p[ BA + 1 ], xMinus1, y, z - 1 ) ),
|
||||||
|
lerp( u, grad( p[ AB + 1 ], x, yMinus1, zMinus1 ),
|
||||||
|
grad( p[ BB + 1 ], xMinus1, yMinus1, zMinus1 ) ) ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentRandom = Math.random;
|
||||||
|
|
||||||
|
// Pseudo-random generator
|
||||||
|
function Marsaglia(i1, i2) {
|
||||||
|
// from http://www.math.uni-bielefeld.de/~sillke/ALGORITHMS/random/marsaglia-c
|
||||||
|
var z=i1 || 362436069, w= i2 || 521288629;
|
||||||
|
var nextInt = function() {
|
||||||
|
z=(36969*(z&65535)+(z>>>16)) & 0xFFFFFFFF;
|
||||||
|
w=(18000*(w&65535)+(w>>>16)) & 0xFFFFFFFF;
|
||||||
|
return (((z&0xFFFF)<<16) | (w&0xFFFF)) & 0xFFFFFFFF;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.nextDouble = function() {
|
||||||
|
var i = nextInt() / 4294967296;
|
||||||
|
return i < 0 ? 1 + i : i;
|
||||||
|
};
|
||||||
|
this.nextInt = nextInt;
|
||||||
|
}
|
||||||
|
Marsaglia.createRandomized = function() {
|
||||||
|
var now = new Date();
|
||||||
|
return new Marsaglia((now / 60000) & 0xFFFFFFFF, now & 0xFFFFFFFF);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Noise functions and helpers
|
||||||
|
function PerlinNoise(seed) {
|
||||||
|
var rnd = seed !== undefined ? new Marsaglia(seed) : Marsaglia.createRandomized();
|
||||||
|
var i, j;
|
||||||
|
// http://www.noisemachine.com/talk1/17b.html
|
||||||
|
// http://mrl.nyu.edu/~perlin/noise/
|
||||||
|
// generate permutation
|
||||||
|
var p = new Array(512);
|
||||||
|
for(i=0;i<256;++i) { p[i] = i; }
|
||||||
|
for(i=0;i<256;++i) { var t = p[j = rnd.nextInt() & 0xFF]; p[j] = p[i]; p[i] = t; }
|
||||||
|
// copy to avoid taking mod in p[0];
|
||||||
|
for(i=0;i<256;++i) { p[i + 256] = p[i]; }
|
||||||
|
|
||||||
|
function grad3d(i,x,y,z) {
|
||||||
|
var h = i & 15; // convert into 12 gradient directions
|
||||||
|
var u = h<8 ? x : y,
|
||||||
|
v = h<4 ? y : h===12||h===14 ? x : z;
|
||||||
|
return ((h&1) === 0 ? u : -u) + ((h&2) === 0 ? v : -v);
|
||||||
|
}
|
||||||
|
|
||||||
|
function grad2d(i,x,y) {
|
||||||
|
var v = (i & 1) === 0 ? x : y;
|
||||||
|
return (i&2) === 0 ? -v : v;
|
||||||
|
}
|
||||||
|
|
||||||
|
function grad1d(i,x) {
|
||||||
|
return (i&1) === 0 ? -x : x;
|
||||||
|
}
|
||||||
|
|
||||||
|
function lerp(t,a,b) { return a + t * (b - a); }
|
||||||
|
|
||||||
|
this.noise3d = function(x, y, z) {
|
||||||
|
var X = Math.floor(x)&255, Y = Math.floor(y)&255, Z = Math.floor(z)&255;
|
||||||
|
x -= Math.floor(x); y -= Math.floor(y); z -= Math.floor(z);
|
||||||
|
var fx = (3-2*x)*x*x, fy = (3-2*y)*y*y, fz = (3-2*z)*z*z;
|
||||||
|
var p0 = p[X]+Y, p00 = p[p0] + Z, p01 = p[p0 + 1] + Z, p1 = p[X + 1] + Y, p10 = p[p1] + Z, p11 = p[p1 + 1] + Z;
|
||||||
|
return lerp(fz,
|
||||||
|
lerp(fy, lerp(fx, grad3d(p[p00], x, y, z), grad3d(p[p10], x-1, y, z)),
|
||||||
|
lerp(fx, grad3d(p[p01], x, y-1, z), grad3d(p[p11], x-1, y-1,z))),
|
||||||
|
lerp(fy, lerp(fx, grad3d(p[p00 + 1], x, y, z-1), grad3d(p[p10 + 1], x-1, y, z-1)),
|
||||||
|
lerp(fx, grad3d(p[p01 + 1], x, y-1, z-1), grad3d(p[p11 + 1], x-1, y-1,z-1))));
|
||||||
|
};
|
||||||
|
|
||||||
|
this.noise2d = function(x, y) {
|
||||||
|
var X = Math.floor(x)&255, Y = Math.floor(y)&255;
|
||||||
|
x -= Math.floor(x); y -= Math.floor(y);
|
||||||
|
var fx = (3-2*x)*x*x, fy = (3-2*y)*y*y;
|
||||||
|
var p0 = p[X]+Y, p1 = p[X + 1] + Y;
|
||||||
|
return lerp(fy,
|
||||||
|
lerp(fx, grad2d(p[p0], x, y), grad2d(p[p1], x-1, y)),
|
||||||
|
lerp(fx, grad2d(p[p0 + 1], x, y-1), grad2d(p[p1 + 1], x-1, y-1)));
|
||||||
|
};
|
||||||
|
|
||||||
|
this.noise1d = function(x) {
|
||||||
|
var X = Math.floor(x)&255;
|
||||||
|
x -= Math.floor(x);
|
||||||
|
var fx = (3-2*x)*x*x;
|
||||||
|
return lerp(fx, grad1d(p[X], x), grad1d(p[X+1], x-1));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// these are lifted from Processing.js
|
||||||
|
// processing defaults
|
||||||
|
var noiseProfile = { generator: undefined, octaves: 4, fallout: 0.5, seed: undefined};
|
||||||
|
|
||||||
|
module.exports = function noise(x, y, z) {
|
||||||
|
if(noiseProfile.generator === undefined) {
|
||||||
|
// caching
|
||||||
|
noiseProfile.generator = new PerlinNoise(noiseProfile.seed);
|
||||||
|
}
|
||||||
|
var generator = noiseProfile.generator;
|
||||||
|
var effect = 1, k = 1, sum = 0;
|
||||||
|
for(var i=0; i<noiseProfile.octaves; ++i) {
|
||||||
|
effect *= noiseProfile.fallout;
|
||||||
|
switch (arguments.length) {
|
||||||
|
case 1:
|
||||||
|
sum += effect * (1 + generator.noise1d(k*x))/2; break;
|
||||||
|
case 2:
|
||||||
|
sum += effect * (1 + generator.noise2d(k*x, k*y))/2; break;
|
||||||
|
case 3:
|
||||||
|
sum += effect * (1 + generator.noise3d(k*x, k*y, k*z))/2; break;
|
||||||
|
}
|
||||||
|
k *= 2;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
};
|
||||||
229
client/src/fizzy-text.js
Normal file
229
client/src/fizzy-text.js
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
const noise = require('./fizzy-noise');
|
||||||
|
|
||||||
|
function fizzyText(message) {
|
||||||
|
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
// These are the variables that we manipulate with gui-dat.
|
||||||
|
// Notice they're all defined with "this". That makes them public.
|
||||||
|
// Otherwise, gui-dat can't see them.
|
||||||
|
|
||||||
|
this.growthSpeed = 0.2; // how fast do particles change size?
|
||||||
|
this.minSize = 1;
|
||||||
|
this.maxSize = 5.59; // how big can they get?
|
||||||
|
this.noiseStrength = 10; // how turbulent is the flow?
|
||||||
|
this.speed = 0.8; // how fast do particles move?
|
||||||
|
this.displayOutline = false; // should we draw the message as a stroke?
|
||||||
|
this.framesRendered = 0;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
var width = 550;
|
||||||
|
var height = 200;
|
||||||
|
var textAscent = 101;
|
||||||
|
var textOffsetLeft = 80;
|
||||||
|
var noiseScale = 300;
|
||||||
|
var frameTime = 30;
|
||||||
|
|
||||||
|
var colors = ["#00aeff", "#0fa954", "#54396e", "#e61d5f"];
|
||||||
|
|
||||||
|
// This is the context we use to get a bitmap of text using
|
||||||
|
// the getImageData function.
|
||||||
|
var r = document.createElement('canvas');
|
||||||
|
var s = r.getContext('2d');
|
||||||
|
|
||||||
|
// This is the context we actually use to draw.
|
||||||
|
var c = document.createElement('canvas');
|
||||||
|
var g = c.getContext('2d');
|
||||||
|
|
||||||
|
r.setAttribute('width', width);
|
||||||
|
c.setAttribute('width', width);
|
||||||
|
r.setAttribute('height', height);
|
||||||
|
c.setAttribute('height', height);
|
||||||
|
|
||||||
|
// Add our demo to the HTML
|
||||||
|
document.getElementById('fizzytext').appendChild(c);
|
||||||
|
|
||||||
|
// Stores bitmap image
|
||||||
|
var pixels = [];
|
||||||
|
|
||||||
|
// Stores a list of particles
|
||||||
|
var particles = [];
|
||||||
|
|
||||||
|
// Set g.font to the same font as the bitmap canvas, incase we
|
||||||
|
// want to draw some outlines.
|
||||||
|
s.font = g.font = "800 82px helvetica, arial, sans-serif";
|
||||||
|
|
||||||
|
// Instantiate some particles
|
||||||
|
for (var i = 0; i < 1000; i++) {
|
||||||
|
particles.push(new Particle(Math.random() * width, Math.random() * height));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function creates a bitmap of pixels based on your message
|
||||||
|
// It's called every time we change the message property.
|
||||||
|
var createBitmap = function (msg) {
|
||||||
|
|
||||||
|
s.fillStyle = "#fff";
|
||||||
|
s.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
|
s.fillStyle = "#222";
|
||||||
|
s.fillText(msg, textOffsetLeft, textAscent);
|
||||||
|
|
||||||
|
// Pull reference
|
||||||
|
var imageData = s.getImageData(0, 0, width, height);
|
||||||
|
pixels = imageData.data;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Called once per frame, updates the animation.
|
||||||
|
var render = function () {
|
||||||
|
|
||||||
|
that.framesRendered ++;
|
||||||
|
|
||||||
|
g.clearRect(0, 0, width, height);
|
||||||
|
|
||||||
|
// if (_this.displayOutline) {
|
||||||
|
// g.globalCompositeOperation = "source-over";
|
||||||
|
// g.strokeStyle = "#000";
|
||||||
|
// g.lineWidth = .5;
|
||||||
|
// g.strokeText(message, textOffsetLeft, textAscent);
|
||||||
|
// }
|
||||||
|
|
||||||
|
g.globalCompositeOperation = "darker";
|
||||||
|
|
||||||
|
for (var i = 0; i < particles.length; i++) {
|
||||||
|
g.fillStyle = colors[i % colors.length];
|
||||||
|
particles[i].render();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns x, y coordinates for a given index in the pixel array.
|
||||||
|
var getPosition = function (i) {
|
||||||
|
return {
|
||||||
|
x: (i - (width * 4) * Math.floor(i / (width * 4))) / 4,
|
||||||
|
y: Math.floor(i / (width * 4))
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns a color for a given pixel in the pixel array.
|
||||||
|
var getColor = function (x, y) {
|
||||||
|
var base = (Math.floor(y) * width + Math.floor(x)) * 4;
|
||||||
|
var c = {
|
||||||
|
r: pixels[base + 0],
|
||||||
|
g: pixels[base + 1],
|
||||||
|
b: pixels[base + 2],
|
||||||
|
a: pixels[base + 3]
|
||||||
|
};
|
||||||
|
|
||||||
|
return "rgb(" + c.r + "," + c.g + "," + c.b + ")";
|
||||||
|
};
|
||||||
|
|
||||||
|
this.message = message;
|
||||||
|
createBitmap(message);
|
||||||
|
|
||||||
|
var loop = function() {
|
||||||
|
requestAnimationFrame(loop);
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This calls the render function every 30 milliseconds.
|
||||||
|
loop();
|
||||||
|
|
||||||
|
// This class is responsible for drawing and moving those little
|
||||||
|
// colored dots.
|
||||||
|
function Particle(x, y, c) {
|
||||||
|
|
||||||
|
// Position
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
|
||||||
|
// Size of particle
|
||||||
|
this.r = 1;
|
||||||
|
|
||||||
|
// This velocity is used by the explode function.
|
||||||
|
this.vx = 0;
|
||||||
|
this.vy = 0;
|
||||||
|
|
||||||
|
this.constrain = function (v, o1, o2) {
|
||||||
|
if (v < o1) v = o1;
|
||||||
|
else if (v > o2) v = o2;
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Called every frame
|
||||||
|
this.render = function () {
|
||||||
|
|
||||||
|
// What color is the pixel we're sitting on top of?
|
||||||
|
var c = getColor(this.x, this.y);
|
||||||
|
|
||||||
|
// Where should we move?
|
||||||
|
var angle = noise(this.x / noiseScale, this.y / noiseScale) * _this.noiseStrength;
|
||||||
|
// var angle = -Math.PI/2;
|
||||||
|
|
||||||
|
// Are we within the boundaries of the image?
|
||||||
|
var onScreen = this.x > 0 && this.x < width &&
|
||||||
|
this.y > 0 && this.y < height;
|
||||||
|
|
||||||
|
var isBlack = c != "rgb(255,255,255)" && onScreen;
|
||||||
|
|
||||||
|
// If we're on top of a black pixel, grow.
|
||||||
|
// If not, shrink.
|
||||||
|
if (isBlack) {
|
||||||
|
this.r += _this.growthSpeed;
|
||||||
|
} else {
|
||||||
|
this.r -= _this.growthSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This velocity is used by the explode function.
|
||||||
|
this.vx *= 0.5;
|
||||||
|
this.vy *= 0.5;
|
||||||
|
|
||||||
|
// Change our position based on the flow field and our
|
||||||
|
// explode velocity.
|
||||||
|
this.x += Math.cos(angle) * _this.speed + this.vx;
|
||||||
|
this.y += -Math.sin(angle) * _this.speed + this.vy;
|
||||||
|
|
||||||
|
if (this.r > _this.maxSize) {
|
||||||
|
this.r = _this.maxSize;
|
||||||
|
} else if (this.r < 0) {
|
||||||
|
this.r = 0;
|
||||||
|
this.x = Math.random() * width;
|
||||||
|
this.y = Math.random() * height;
|
||||||
|
// this.y = height + (Math.random() * 2 - 1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this.r = 3;
|
||||||
|
// debugger
|
||||||
|
// console.log(DAT.GUI.constrain(this.r, 0, _this.maxSize));
|
||||||
|
// this.r = this.constrain(this.r, _this.minSize, _this.maxSize);
|
||||||
|
|
||||||
|
// If we're tiny, keep moving around until we find a black
|
||||||
|
// pixel.
|
||||||
|
if (this.r <= 0) {
|
||||||
|
this.x = Math.random() * width;
|
||||||
|
this.y = Math.random() * height;
|
||||||
|
return; // Don't draw!
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're off the screen, go over to other side
|
||||||
|
if(this.x < 0) this.x = width;
|
||||||
|
if(this.x > width) this.x = 0;
|
||||||
|
if(this.y < 0) this.y = height;
|
||||||
|
if(this.y > height) this.y = 0;
|
||||||
|
|
||||||
|
// Draw the circle.
|
||||||
|
g.beginPath();
|
||||||
|
g.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
|
||||||
|
g.fill();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = fizzyText;
|
||||||
Loading…
x
Reference in New Issue
Block a user