mumuki-puzzle-runner 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0524959e5526b6f764f91b27d939eaf1869fc21a6aa4682d052d216dea0807f2'
4
- data.tar.gz: 41cd6df65522b8039cfb933c785f392f1c44f23e40b49b06ff8d1b2859506fe8
3
+ metadata.gz: 5da4e03efe5edbeb4e6eadfaf79f5d37e4f5bea50127a26e91c5f6d2cedb2438
4
+ data.tar.gz: f0eeb8f873165d98ecfcc04854aa4fb781d4753fc4350bcfed90fd24c184744b
5
5
  SHA512:
6
- metadata.gz: 6ec608fc1f4162f6664e14b3f3b623602d400a366ffb7f6e66d40df9d9719a65853063692bff98a300c7d9485d297f524d7b0b8a42c7a3a33e3528f02cac3fe4
7
- data.tar.gz: fd403eb6301bdc0dd39f53b4b9fd315b654608cd575076d702f23074e3efde98785202765c879d72be76125f060d2410db619ca7fa7cebc0c71c530878adb88e
6
+ metadata.gz: c98b0e5f9fe633c8fb0587b3c948ce0a6d6d79b80619befc28bc4c583578be596b1d8d2d9f61fddbb3241a320424b602af417fca96827c632a9537342d2a62e9
7
+ data.tar.gz: f40b2c76b102651f25ca76eda5b82d24f6cb037e92efcbd68299d634ec8a4f8a22477f4639893b780f6e8f44e790761189c43c12a925a5421f8e33416b3273af
@@ -1,4 +1,13 @@
1
1
  .mu-kids-state-image img {
2
- width: 90%;
2
+ height: 100%;
3
+ width: auto;
3
4
  padding: 30px;
4
5
  }
6
+
7
+ .mu-kids-state.mu-state-initial {
8
+ width: 100%;
9
+ }
10
+
11
+ .mu-kids-exercise-workspace.muzzle-simple .mu-kids-submit-button {
12
+ display: none;
13
+ }
@@ -1,5 +1,13 @@
1
1
  // @ts-nocheck
2
2
  $(() => {
3
+ function register(event, callback) {
4
+ const _event = Muzzle[event];
5
+ Muzzle[event] = (...args) => {
6
+ callback(...args);
7
+ _event(...args);
8
+ }
9
+ }
10
+
3
11
  // ================
4
12
  // Muzzle rendering
5
13
  // ================
@@ -29,39 +37,44 @@ $(() => {
29
37
 
30
38
  // Requiered to actually bind Muzzle's submit to
31
39
  // mumuki's solution processing
32
- const _onSubmit = Muzzle.onSubmit;
33
- Muzzle.onSubmit = (submission) => {
40
+ register('onSubmit', (submission) => {
34
41
  mumuki.submission.processSolution(submission);
35
- _onSubmit(submission);
36
- }
42
+ });
37
43
 
38
44
  // ===========
39
45
  // Kids config
40
46
  // ===========
41
47
 
42
- // Required to make scaler work
43
48
  mumuki.kids.registerStateScaler(($state, fullMargin, preferredWidth, preferredHeight) => {
44
- // nothing
45
- // no state scaling needed
49
+ // no manul image scalling. Leave it to css
46
50
  });
51
+
47
52
  mumuki.kids.registerBlocksAreaScaler(($blocks) => {
48
- const maxSize = $('.mu-kids-exercise').height() - $('.mu-kids-exercise-description').height();
49
- Muzzle.scale($blocks.width(), Math.min($blocks.height(), maxSize));
53
+ const maxHeight = $('.mu-kids-exercise').height() - $('.mu-kids-exercise-description').height();
54
+ Muzzle.scale($blocks.width(), Math.min($blocks.height(), maxHeight));
50
55
  });
51
56
 
52
57
  Muzzle.manualScale = true;
53
58
 
59
+ // ====================
60
+ // Submit button hiding
61
+ // ====================
62
+
63
+ register('onReady', () => {
64
+ if (Muzzle.simple) {
65
+ $('.mu-kids-exercise-workspace').addClass('muzzle-simple');
66
+ }
67
+ });
68
+
54
69
  // ==============
55
70
  // Assets loading
56
71
  // ==============
57
72
 
58
- const _onReady = Muzzle.onReady;
59
- Muzzle.onReady = () => {
73
+ register('onReady', () => {
60
74
  mumuki.assetsLoadedFor('editor');
61
75
  // although layout assets
62
76
  // are actually loaded before this script, puzzle runner is not aimed
63
77
  // to be used without a custom editor
64
78
  mumuki.assetsLoadedFor('layout');
65
- _onReady();
66
- };
79
+ });
67
80
  });
@@ -136,7 +136,17 @@ class MuzzleCanvas {
136
136
  *
137
137
  * @type {string}
138
138
  */
139
- this.previousSolutionContent = null
139
+ this.previousSolutionContent = null;
140
+
141
+ /**
142
+ * Whether the current puzzle can be solved in very few tries.
143
+ *
144
+ * Set null for automatic configuration of this property. Basic puzzles will be considered
145
+ * basic and match puzzles will be considered non-basic.
146
+ *
147
+ * @type {boolean}
148
+ */
149
+ this.simple = null;
140
150
 
141
151
  /**
142
152
  * Callback to be executed when submitting puzzle.
@@ -167,7 +177,7 @@ class MuzzleCanvas {
167
177
  width: this.canvasWidth,
168
178
  height: this.canvasHeight,
169
179
  pieceSize: pieceSize,
170
- proximity: pieceSize.x / 5,
180
+ proximity: Math.min(pieceSize.x, pieceSize.y) / 5,
171
181
  borderFill: this.borderFill === null ? headbreaker.Vector.divide(pieceSize, 10) : this.borderFill,
172
182
  strokeWidth: this.strokeWidth,
173
183
  lineSoftness: 0.18
@@ -228,6 +238,10 @@ class MuzzleCanvas {
228
238
  this.aspectRatio = x / y;
229
239
  }
230
240
 
241
+ if (this.simple === null) {
242
+ this.simple = true;
243
+ }
244
+
231
245
  /**
232
246
  * @todo take all container size
233
247
  **/
@@ -389,11 +403,11 @@ class MuzzleCanvas {
389
403
  this._canvas.onValid(() => {
390
404
  setTimeout(() => this.onValid(), 0);
391
405
  });
392
- this._setupScaler();
406
+ this._setUpScaler();
393
407
  this.ready();
394
408
  }
395
409
 
396
- _setupScaler() {
410
+ _setUpScaler() {
397
411
  if (this.manualScale) return;
398
412
 
399
413
  ['resize', 'load'].forEach((event) => {
@@ -405,10 +419,39 @@ class MuzzleCanvas {
405
419
  }
406
420
 
407
421
  scale(width, height) {
408
- if (this.fixedDimensions) return;
422
+ if (this.fixedDimensions || !this.canvas) return;
423
+ const factor = this.optimalScaleFactor(width, height);
409
424
  this.canvas.resize(width, height);
410
- this.canvas.scale(this.optimalScaleFactor(width, height));
425
+ this.canvas.scale(factor);
411
426
  this.canvas.redraw();
427
+ this.focus();
428
+ }
429
+
430
+ focus() {
431
+ const stage = this.canvas['__konvaLayer__'].getStage();
432
+
433
+ const area = headbreaker.Vector.divide(headbreaker.vector(stage.width(), stage.height()), stage.scaleX());
434
+ const realDiameter = (() => {
435
+ const [xs, ys] = this.coordinates;
436
+
437
+ const minX = Math.min(...xs);
438
+ const minY = Math.min(...ys);
439
+
440
+ const maxX = Math.max(...xs);
441
+ const maxY = Math.max(...ys);
442
+
443
+ return headbreaker.Vector.plus(headbreaker.vector(maxX - minX, maxY - minY), this.canvas.puzzle.pieceDiameter);
444
+ })();
445
+ const diff = headbreaker.Vector.minus(area, realDiameter);
446
+ const semi = headbreaker.Vector.divide(diff, -2);
447
+
448
+ stage.setOffset(semi);
449
+ stage.draw();
450
+ }
451
+
452
+ get coordinates() {
453
+ const points = this.canvas.puzzle.points;
454
+ return [points.map(([x, _y]) => x), points.map(([_x, y]) => y)];
412
455
  }
413
456
 
414
457
  optimalScaleFactor(width, height) {
@@ -422,6 +465,7 @@ class MuzzleCanvas {
422
465
  */
423
466
  ready() {
424
467
  this.loadPreviousSolution();
468
+ this.resetCoordinates();
425
469
  this.draw();
426
470
  this.onReady();
427
471
  }
@@ -447,6 +491,7 @@ class MuzzleCanvas {
447
491
  */
448
492
  loadSolution(solution) {
449
493
  this.canvas.puzzle.relocateTo(solution.positions);
494
+ this.canvas.puzzle.autoconnect();
450
495
  }
451
496
 
452
497
  /**
@@ -463,6 +508,13 @@ class MuzzleCanvas {
463
508
  }
464
509
  }
465
510
 
511
+ resetCoordinates() {
512
+ const [xs, ys] = this.coordinates;
513
+ const minX = Math.min(...xs);
514
+ const minY = Math.min(...ys);
515
+ this.canvas.puzzle.translate(-minX, -minY);
516
+ }
517
+
466
518
  // ==========
467
519
  // Submitting
468
520
  // ==========
@@ -1,3 +1,3 @@
1
1
  module PuzzleVersionHook
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mumuki-puzzle-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Franco Leonardo Bulgarelli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-01 00:00:00.000000000 Z
11
+ date: 2020-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mumukit