├── README.md
├── Barrio-Regular.ttf
├── randomTexts.js
├── style.css
├── index.html
├── CanvasRecorder.js
├── generator.js
└── Finger.js
/README.md:
--------------------------------------------------------------------------------
1 | I am angry, exhausted and disappointed. So I made art.
2 |
--------------------------------------------------------------------------------
/Barrio-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bleeptrack/funkyfingers/HEAD/Barrio-Regular.ttf
--------------------------------------------------------------------------------
/randomTexts.js:
--------------------------------------------------------------------------------
1 | var randomText = [
2 | 'WTF',
3 | 'OMG WTF',
4 | 'FUCK NFTs',
5 | 'CORONA SUCKS',
6 | 'FUCK UPLOAD FILTERS',
7 | 'FUCK 2020',
8 | 'WHY ?',
9 | 'THIS SUCKS',
10 | 'FUCK CRYPTO COINS',
11 | 'FUCK CAPITALISM',
12 | 'FUCK FRONTEX'
13 | ];
14 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | canvas[resize] {
2 | position:absolute;
3 | top:0;
4 | left:0;
5 | width:100%;
6 | height:100%;
7 | z-index:-1;
8 | }
9 |
10 | body{
11 |
12 | }
13 |
14 | input[type="color"] {
15 | -webkit-appearance: none;
16 | border: none;
17 | width: 64px;
18 | height: 32px;
19 | background-color: none;
20 | height: 37px;
21 | margin: 0;
22 | padding: 0;
23 | margin-bottom: 1em;
24 | }
25 | input[type="color"]::-webkit-color-swatch-wrapper {
26 | padding: 0;
27 | }
28 | input[type="color"]::-webkit-color-swatch {
29 | border: none;
30 | }
31 |
32 | #settingswrap{
33 | display: flex;
34 | flex-direction: row;
35 | flex-wrap: wrap;
36 | }
37 |
38 | button{
39 | height: 40px;
40 | text-decoration: none;
41 | color: #FF00AA;
42 | border: 2px solid #FF00AA;
43 | letter-spacing: 2px;
44 | text-align: center;
45 | position: relative;
46 | transition: all .35s;
47 | padding-left: 1.5em;
48 | padding-right: 1.5em;
49 | background-color: transparent;
50 | margin-right: 1em;
51 | margin-bottom: 1em;
52 | }
53 |
54 | input{
55 | height: 34px;
56 | width: 5em;
57 | text-decoration: none;
58 | color: #FF00AA;
59 | border: 2px solid #FF00AA;
60 | letter-spacing: 2px;
61 | text-align: center;
62 | position: relative;
63 | transition: all .35s;
64 | padding-left: 1.5em;
65 | padding-right: 1.5em;
66 | background-color: transparent;
67 | margin-right: 1em;
68 | margin-bottom: 1em;
69 | -webkit-appearance: none;
70 | margin: 0;
71 | -moz-appearance: textfield;
72 | }
73 |
74 | button:hover{
75 | color: 'white';
76 | border: 2px solid #AA00FF;
77 | background-color: #AA00FF
78 | }
79 |
80 |
81 | .spacer{
82 | width: 2em;
83 | }
84 |
85 | .seg{
86 | margin-right: 2em;
87 | }
88 |
89 | .info{
90 | position: fixed;
91 | bottom: 0;
92 | right: 0;
93 | margin: 0.5em;
94 | text-decoration: none;
95 | letter-spacing: 2px;
96 | }
97 |
98 | span{
99 | margin: 0 0.5em;
100 | text-decoration: none;
101 | letter-spacing: 2px;
102 | color: #AA00FF;
103 | }
104 |
105 | a{
106 | color: #AA00FF;
107 | }
108 |
109 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Some F*s to give
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
78 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/CanvasRecorder.js:
--------------------------------------------------------------------------------
1 | // CanvasRecorder.js - smusamashah
2 | // To record canvas effitiently using MediaRecorder
3 | // https://webrtc.github.io/samples/src/content/capture/canvas-record/
4 |
5 | function CanvasRecorder(canvas, video_bits_per_sec) {
6 | this.start = startRecording;
7 | this.stop = stopRecording;
8 | this.save = download;
9 |
10 | var recordedBlobs = [];
11 | var supportedType = null;
12 | var mediaRecorder = null;
13 |
14 | var stream = canvas.captureStream();
15 | if (typeof stream == undefined || !stream) {
16 | return;
17 | }
18 |
19 | const video = document.createElement('video');
20 | video.style.display = 'none';
21 |
22 | function startRecording() {
23 | let types = [
24 | "video/webm",
25 | 'video/webm,codecs=vp9',
26 | 'video/vp8',
27 | "video/webm\;codecs=vp8",
28 | "video/webm\;codecs=daala",
29 | "video/webm\;codecs=h264",
30 | "video/mpeg"
31 | ];
32 |
33 | for (let i in types) {
34 | if (MediaRecorder.isTypeSupported(types[i])) {
35 | supportedType = types[i];
36 | break;
37 | }
38 | }
39 | if (supportedType == null) {
40 | console.log("No supported type found for MediaRecorder");
41 | }
42 | let options = {
43 | mimeType: supportedType,
44 | videoBitsPerSecond: video_bits_per_sec || 2500000 // 2.5Mbps
45 | };
46 |
47 | recordedBlobs = [];
48 | try {
49 | mediaRecorder = new MediaRecorder(stream, options);
50 | } catch (e) {
51 | alert('MediaRecorder is not supported by this browser.');
52 | console.error('Exception while creating MediaRecorder:', e);
53 | return;
54 | }
55 |
56 | console.log('Created MediaRecorder', mediaRecorder, 'with options', options);
57 | mediaRecorder.onstop = handleStop;
58 | mediaRecorder.ondataavailable = handleDataAvailable;
59 | mediaRecorder.start(100); // collect 100ms of data blobs
60 | console.log('MediaRecorder started', mediaRecorder);
61 | }
62 |
63 | function handleDataAvailable(event) {
64 | if (event.data && event.data.size > 0) {
65 | recordedBlobs.push(event.data);
66 | }
67 | }
68 |
69 | function handleStop(event) {
70 | console.log('Recorder stopped: ', event);
71 | const superBuffer = new Blob(recordedBlobs, { type: supportedType });
72 | video.src = window.URL.createObjectURL(superBuffer);
73 | }
74 |
75 | function stopRecording() {
76 | mediaRecorder.stop();
77 | console.log('Recorded Blobs: ', recordedBlobs);
78 | video.controls = true;
79 | }
80 |
81 | function download(file_name) {
82 | const name = file_name || 'recording.webm';
83 | const blob = new Blob(recordedBlobs, { type: supportedType });
84 | const url = window.URL.createObjectURL(blob);
85 | const a = document.createElement('a');
86 | a.style.display = 'none';
87 | a.href = url;
88 | a.download = name;
89 | document.body.appendChild(a);
90 | a.click();
91 | setTimeout(() => {
92 | document.body.removeChild(a);
93 | window.URL.revokeObjectURL(url);
94 | }, 100);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/generator.js:
--------------------------------------------------------------------------------
1 |
2 | let fingers;
3 | let handColors = [
4 | '#FFAA00',
5 | '#FF00AA',
6 | '#AA00FF',
7 | '#00AAFF'
8 | ];
9 | let boxColor = '#AAFF00';
10 | let tinyFingers = true;
11 | let sizex = 420;
12 | let sizey = 420;
13 | let imgcount = 0;
14 | let recording = false;
15 | paper.install(window);
16 | window.onload = async function() {
17 |
18 |
19 | paper.setup('myCanvas');
20 |
21 |
22 | let canvas = document.getElementById('myCanvas');
23 | const recorder = new CanvasRecorder(canvas, 4500000);
24 | var downloadLink = document.createElement("a");
25 | document.body.appendChild(downloadLink);
26 |
27 | shuffle();
28 | generate();
29 |
30 | //genGrid();
31 | //genStickers();
32 |
33 | if(recording){
34 | recorder.start();
35 | }
36 | //genAnimation();
37 |
38 |
39 | if(recording){
40 | view.onClick = function(){
41 | recorder.stop();
42 | recorder.save('finger_motion.webm');
43 | }
44 | }
45 | }
46 |
47 | function genAnimation(){
48 | fingers = new Finger([sizex, sizey], view.bounds.center.add([-900,-400]), handColors.concat([boxColor]), false, 'animation');
49 | let fingers1 = new Finger([sizex, sizey], view.bounds.center.add([-900,400]), handColors.concat([boxColor]), false, 'animation');
50 | let fingers2 = new Finger([sizex, sizey], view.bounds.center.add([0,-400]), handColors.concat([boxColor]), false, 'animation');
51 | let fingers3 = new Finger([sizex, sizey], view.bounds.center.add([0,400]), handColors.concat([boxColor]), false, 'animation');
52 | let fingers4 = new Finger([sizex, sizey], view.bounds.center.add([900,-400]), handColors.concat([boxColor]), false, 'animation');
53 | let fingers5 = new Finger([sizex, sizey], view.bounds.center.add([900,400]), handColors.concat([boxColor]), false, 'animation');
54 |
55 | //fingers = new Finger([sizex, sizey], view.bounds.center, handColors.concat([boxColor]), false, 'animation');
56 | }
57 |
58 | function genStickers(){
59 | fingers = new Finger([sizex, sizey], view.bounds.center, handColors.concat([boxColor]), false, 'sticker');
60 | }
61 |
62 | function genGrid(){
63 | let s = 350;
64 | let d = 150;
65 |
66 | fingers = new Finger([s*2+d, s*2+d], [300+s+d/2, 300+s+d/2], handColors.concat([boxColor]), false);
67 |
68 | let oldColors = [boxColor].concat(handColors);
69 | let colors = _.shuffle(oldColors);
70 | boxColor = colors.pop();
71 | handColors = colors;
72 | fingers = new Finger([s, s*3+d*2], [300+s*2.5+d*2, 300+s*1.5+d], handColors.concat([boxColor]), false);
73 |
74 | oldColors = [boxColor].concat(handColors);
75 | //colors = _.shuffle(oldColors);
76 | boxColor = colors.pop();
77 | handColors = colors;
78 | fingers = new Finger([s, s], [300+s*0.5, 300+s*2.5+d*2], handColors.concat([boxColor]), false);
79 |
80 | oldColors = [boxColor].concat(handColors);
81 | //colors = _.shuffle(oldColors);
82 | boxColor = colors.pop();
83 | handColors = colors;
84 | fingers = new Finger([s, s], [300+s*1.5+d, 300+s*2.5+d*2], handColors.concat([boxColor]), false);
85 | }
86 |
87 | function generate(text){
88 | project.activeLayer.removeChildren();
89 | let val = document.getElementById("textinput").value
90 | fingers = new Finger([sizex, sizey], view.bounds.center, handColors.concat([boxColor]), false, 'none', val);
91 |
92 | if(!tinyFingers){
93 | fingers.removeTinyFingers();
94 | }
95 |
96 |
97 | }
98 |
99 | function shuffle(){
100 | let oldColors = handColors.concat([boxColor]);
101 | let colors = _.shuffle(oldColors);
102 |
103 | boxC = colors.pop();
104 | handC = colors;
105 |
106 | if(fingers){
107 |
108 | changeColor('boxcolor', Color.random());
109 | changeColor('fillcolor1', Color.random());
110 | changeColor('fillcolor2', Color.random());
111 | changeColor('fillcolor3', Color.random());
112 | changeColor('fillcolor4', Color.random());
113 |
114 | changeColor('boxcolor', boxC);
115 | changeColor('fillcolor1', handC[0]);
116 | changeColor('fillcolor2', handC[1]);
117 | changeColor('fillcolor3', handC[2]);
118 | changeColor('fillcolor4', handC[3]);
119 |
120 | }
121 |
122 | handColors = handC;
123 | boxColor = boxC;
124 | document.getElementById('boxcolor').value = boxColor;
125 | document.getElementById('fillcolor1').value = handColors[0];
126 | document.getElementById('fillcolor2').value = handColors[1];
127 | document.getElementById('fillcolor3').value = handColors[2];
128 | document.getElementById('fillcolor4').value = handColors[3];
129 |
130 |
131 |
132 | }
133 |
134 | function toggleFingers(){
135 | if(tinyFingers){
136 | fingers.removeTinyFingers();
137 | }else{
138 | fingers.insertTinyFingers();
139 | }
140 | tinyFingers = !tinyFingers;
141 | }
142 |
143 | var changeText = _.debounce(function (text) {
144 | generate(text);
145 | }, 500);
146 |
147 | function changeSize(name, value){
148 | if(name == 'sizex'){
149 | sizex = value;
150 | }
151 | if(name == 'sizey'){
152 | sizey = value;
153 | }
154 |
155 | }
156 |
157 | function changeStyle(val){
158 | if(val == 'fill'){
159 | fingers.makeColored();
160 | }
161 | if(val == 'nofill'){
162 | fingers.makeLineArt();
163 | }
164 | }
165 |
166 | function changeColor(colorname, value){
167 | if(colorname == 'fillcolor1'){
168 | fingers.changeColor(handColors[0], value);
169 | handColors[0] = value;
170 | }
171 | if(colorname == 'fillcolor2'){
172 | fingers.changeColor(handColors[1], value);
173 | handColors[1] = value;
174 | }
175 | if(colorname == 'fillcolor3'){
176 | fingers.changeColor(handColors[2], value);
177 | handColors[2] = value;
178 | }
179 | if(colorname == 'fillcolor4'){
180 | fingers.changeColor(handColors[3], value);
181 | handColors[3] = value;
182 | }
183 | if(colorname == 'boxcolor'){
184 | fingers.changeColor(boxColor, value);
185 | boxColor = value;
186 | }
187 | }
188 |
189 | function downloadSVG(){
190 | var svg = project.exportSVG({ asString: true });
191 | var svgBlob = new Blob([svg], {type:"image/svg+xml;charset=utf-8"});
192 | var svgUrl = URL.createObjectURL(svgBlob);
193 | var downloadLink = document.createElement("a");
194 | downloadLink.href = svgUrl;
195 | downloadLink.download = "funkyfingers.svg";
196 | document.body.appendChild(downloadLink);
197 | downloadLink.click();
198 | document.body.removeChild(downloadLink);
199 | }
200 |
201 | function downloadPNG(){
202 | var canvas = document.getElementById("myCanvas");
203 | var downloadLink = document.createElement("a");
204 | downloadLink.href = canvas.toDataURL("image/png;base64");
205 | downloadLink.download = 'funkyfingers.png'
206 | document.body.appendChild(downloadLink);
207 | downloadLink.click();
208 | document.body.removeChild(downloadLink);
209 | }
210 |
211 |
212 |
213 |
--------------------------------------------------------------------------------
/Finger.js:
--------------------------------------------------------------------------------
1 | class Finger{
2 |
3 |
4 |
5 |
6 | constructor(boxsize, pos, colors, offset, mode, text){
7 |
8 |
9 | this.colors = colors;
10 | this.center = paper.view.center;
11 | this.coloredObjs = [];
12 | this.tinyFingers = [];
13 | this.bigFingerBG = [];
14 | this.bigFingerLines = [];
15 | this.offset = offset;
16 | this.animation = mode == 'animation' ? true : false;
17 | this.sticker = mode == 'sticker' ? true : false;
18 | if(text){
19 | this.text = text;
20 | }else{
21 | this.text = _.sample(randomText);
22 | }
23 |
24 |
25 | paper.view.scaling = 1;
26 |
27 | this.generate(boxsize, pos);
28 |
29 | if(this.offset){
30 | this.offsetColors();
31 | }
32 | if(this.animation){
33 | this.removeTinyFingers();
34 | }
35 |
36 | this.bigHandOffset = [_.random(4,8)*_.sample([-1,1]),_.random(4,8)*_.sample([-1,1])];
37 |
38 | }
39 |
40 | async generate(boxsize, pos){
41 | this.font = await opentype.load("Barrio-Regular.ttf");
42 |
43 | if(this.sticker){
44 | for(let y = 1; y<=4; y++){
45 | for(let x = 1; x<= 5; x++){
46 | let h1 = this.drawhand();
47 | h1.strokeWidth *= 2.1;
48 | h1.rotate(180);
49 |
50 | h1.position = [x*380, y*750-300];
51 | this.decoHand(h1);
52 | }
53 | if(y<4){
54 | for(let x = 1; x<= 4; x++){
55 | let h1 = this.drawhand();
56 | h1.strokeWidth *= 2.1;
57 |
58 | h1.position = [190+x*380, y*750];
59 | this.decoHand(h1);
60 | }
61 | }
62 | }
63 |
64 | } else if(this.animation){
65 | let boxcolor = this.colors.pop();
66 | let animFingers = this.generateAnimationFingers(9, pos);
67 |
68 | animFingers[0].dashArray = [animFingers[0].length, animFingers[0].length];
69 | await animFingers[0].tweenFrom({dashOffset: animFingers[0].length}, {duration: 2500, easing: 'linear'});
70 | animFingers[0].remove();
71 |
72 | let fin = new Path();
73 | fin.strokeColor = 'black';
74 | fin.strokeWidth = animFingers[0].strokeWidth;
75 |
76 | for(let i = 0; i p.tweenTo({opacity: 0}, {duration: 300, easing: 'easeInOutCubic'}));
148 | handleIns.forEach(p => p.tweenTo({opacity: 0}, {duration: 300, easing: 'easeInOutCubic'}));
149 | handleOuts.forEach(p => p.tweenTo({opacity: 0}, {duration: 300, easing: 'easeInOutCubic'}));
150 |
151 | deco.children[1].applyMatrix = false;
152 | deco.scaling = 1;
153 | await deco.children[1].tweenFrom({scaling: 0.01}, {duration: 1000, easing: 'easeInOutCubic'});
154 |
155 | await l.tweenTo({dashOffset: 0}, {duration: 2500, easing: 'easeInOutCubic'});
156 |
157 | this.box = new Path.Rectangle([0,0], [650, 650]);
158 | this.box.sendToBack();
159 | this.box.position = pos;
160 | this.box.fillColor = boxcolor;
161 | this.box.applyMatrix = false;
162 | this.box.rotation = _.random(-5,5);
163 | await this.box.tweenFrom({scaling: 0.01, rotation: 0}, {duration: 500, easing: 'easeInOutCubic'});
164 |
165 | let bigHand = new Group(deco, fin);
166 | bigHand.applyMatrix = false;
167 | bigHand.rotation = 0;
168 | let newpos = [this.box.bounds.topLeft.x+_.random(0,this.box.bounds.width), this.box.bounds.topLeft.y+_.random(0,this.box.bounds.height)];
169 | await bigHand.tweenTo({rotation: _.random(0, 360), position: newpos}, {duration: 1000, easing: 'easeInOutCubic'});
170 |
171 |
172 | bigHand.applyMatrix = true;
173 | this.fingers = [fin];
174 | let lasttween;
175 | for(let i = 0; i<200; i++){
176 | //if(i%100==0)
177 | //console.log(i);
178 | let h1 = this.drawhand();
179 | h1.strokeWidth *= 1.7
180 | h1.fillColor = this.getRandomColor();
181 | h1.scale(_.random(5,20)/70);
182 | h1.rotate(_.random(0, 360));
183 | if(_.random(0,1)==0){
184 | h1.scale(-1,1);
185 | }
186 | h1.position = [this.box.bounds.topLeft.x+_.random(0,this.box.bounds.width), this.box.bounds.topLeft.y+_.random(0,this.box.bounds.height)];
187 | if(!this.collides(h1, false)){
188 | this.fingers.push(h1);
189 | lasttween = h1.tweenFrom({opacity: 0}, {duration: _.random(300,1200), easing: 'easeInOutCubic'})
190 | //tween
191 | }else{
192 | h1.remove();
193 | }
194 | }
195 | await lasttween.start();
196 |
197 | }else{
198 | this.fingers = [];
199 |
200 |
201 | await this.addText();
202 |
203 | this.box = new Path.Rectangle([0,0], [this.textpath.bounds.width+250, this.textpath.bounds.height+250]);
204 | this.box.position = pos;
205 | this.box.fillColor = this.colors.pop();
206 |
207 | this.box = new CompoundPath({ children: [this.box], fillColor: this.box.fillColor, fillRule: 'evenodd' });
208 | this.box.sendToBack();
209 | this.coloredObjs.push(this.box);
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 | for(let i = 0; i 7 ){
225 | h1.scale(_.random(5,20)/100);
226 | handOffset = 0;
227 | }
228 | h1.rotate(_.random(0, 360));
229 | if(_.random(0,1)==0){
230 | h1.scale(-1,1);
231 | }
232 | h1.position = [this.box.bounds.topLeft.x+_.random(-handOffset,this.box.bounds.width+handOffset), this.box.bounds.topLeft.y+_.random(-handOffset,this.box.bounds.height+handOffset)];
233 | if(!this.collides(h1, false)){
234 | this.fingers.push(h1);
235 | if( i <= 7){
236 | this.decoHand(h1);
237 | h1.strokeWidth *= 1.5;
238 | h1.bringToFront();
239 |
240 | if(h1.intersects(paper.view.bounds)){
241 | console.log('error');
242 | }
243 | }else{
244 | let h2 = h1.clone();
245 | h1.strokeColor = undefined;
246 | h1.fillColor = this.getRandomColor();
247 | this.tinyFingers.push(h1);
248 | this.tinyFingers.push(h2);
249 | this.coloredObjs.push(h1);
250 | }
251 | paper.view.update();
252 | }else{
253 | h1.remove();
254 | }
255 | }
256 |
257 | if(paper.project.activeLayer.bounds.height > paper.view.bounds.height){
258 | paper.view.scale( paper.view.bounds.height*0.8 / paper.project.activeLayer.bounds.height );
259 | }
260 | if(paper.project.activeLayer.bounds.width > paper.view.bounds.width){
261 | paper.view.scale( paper.view.bounds.width*0.8 / paper.project.activeLayer.bounds.width );
262 | }
263 |
264 | //this.box.rotate(_.random(-3,3,true));
265 | //
266 | for(let letter of this.textpath.children){
267 | await this.box.tweenTo({}, 200);
268 | this.box.addChild(letter.clone());
269 | for(let i = 0; i<5; i++){ //iterate crumbles
270 | let crumble = new Path.Rectangle([0,0], [20,20]);
271 | crumble.fillColor = this.box.fillColor;
272 | //crumble.strokeColor = 'black';
273 | crumble.rotate(_.random(0,360));
274 | crumble.position = letter.getPointAt(_.random(0, letter.length));
275 | crumble.applyMatrix = false;
276 | if(i==4){
277 | this.shake(5);
278 | crumble.tweenTo({position: crumble.position.add([0,700]), opacity: 0, rotation: crumble.rotation + _.random(300, 1000)}, 800);
279 | }else{
280 | crumble.tweenTo({position: crumble.position.add([0,700]), opacity: 0, rotation: crumble.rotation + _.random(300, 1000)}, 800);
281 | }
282 | }
283 | }
284 |
285 |
286 | }
287 | }
288 |
289 |
290 |
291 | shake(times){
292 | paper.view.shakeOffset = times;
293 | paper.view.oldCenter = paper.view.center;
294 | paper.view.onFrame = this.shakeRender;
295 |
296 | }
297 |
298 | shakeRender(){
299 | paper.view.center = paper.view.oldCenter.add([_.random(-paper.view.shakeOffset, paper.view.shakeOffset), _.random(-paper.view.shakeOffset, paper.view.shakeOffset)]);
300 | paper.view.rotation = _.random(-paper.view.shakeOffset/2, paper.view.shakeOffset/2);
301 | paper.view.shakeOffset--;
302 | console.log(paper.view.shakeOffset);
303 | if(paper.view.shakeOffset <= 0){
304 | paper.view.onFrame = undefined;
305 | paper.view.rotation = 0;
306 | }
307 | }
308 |
309 | async addText(){
310 |
311 | //background.fillColor = colors[0];
312 | let txts = this.text.split(" ");
313 | this.textpath = new CompoundPath();
314 |
315 | txts.forEach( (txt, idx, arr) => {
316 | let fontpath = this.font.getPath(txt,0,idx*300, 300, {kerning: true});
317 | let p = paper.project.importSVG(fontpath.toSVG());
318 | this.textpath.addChildren(p.children);
319 | });
320 |
321 | this.textpath.position = view.center;
322 | this.fingers.push(this.textpath.clone());
323 |
324 |
325 |
326 | //console.log(this.box);
327 | //this.box.fillColor = 'red';
328 |
329 |
330 | }
331 |
332 |
333 | generateAnimationFingers(num, pos){
334 | let animFingers = [];
335 | for(let i = 0; i {
475 | let offset = [_.random(-4,4), _.random(-4,4)];
476 | let colObjs = this.getObjsByColor(new Color(col));
477 | colObjs.forEach(c => {
478 | c.translate(offset);
479 | c.myOffset = offset;
480 | });
481 | })
482 |
483 | }
484 |
485 | changeColor(fromC, toC){
486 | let colObjs = this.getObjsByColor(new Color(fromC));
487 | colObjs.forEach(c => {
488 | if(c.fillColor){
489 | c.fillColor = toC;
490 | }
491 | if(c.strokeColor){
492 | c.strokeColor = toC;
493 | }
494 | });
495 | }
496 |
497 | makeLineArt(){
498 | this.coloredObjs.forEach(o => o.remove());
499 | }
500 |
501 | makeColored(){
502 | project.activeLayer.insertChildren(0,this.coloredObjs);
503 | }
504 |
505 | removeTinyFingers(){
506 | this.tinyFingers.forEach(o => o.remove());
507 | }
508 |
509 | insertTinyFingers(){
510 | project.activeLayer.insertChildren(1,this.tinyFingers);
511 | }
512 |
513 | getBoxColor(){
514 | return this.box.fillColor.toCSS(true);
515 | }
516 |
517 | getHandColors(){
518 | return this.colors;
519 | }
520 |
521 | }
522 |
--------------------------------------------------------------------------------