Repository: chanind/hanzi-writer (ts)

Issue:
Rounding drawnPath's data
For both, the current level of decimals precision is certainly not needed, and rather unnecessary noise.
Reminder : `drawingWidth` default is **4px**.
See :
![screenshot from 2018-02-26 11-44-04](https://user-images.githubusercontent.com/1420189/36666324-7e04201e-1aea-11e8-9433-a3cb3b9701f3.png)


Pull request description:
Rounded path strings
This PR rounds the `points` and `pathString` returned in `drawnPath` to 1 decimal place.

fixes #66 

Patch:
diff --git a/src/Quiz.js b/src/Quiz.js
index db826e51..f68c3a35 100644
--- a/src/Quiz.js
+++ b/src/Quiz.js
@@ -3,12 +3,13 @@ const UserStroke = require('./models/UserStroke');
 const {callIfExists, counter} = require('./utils');
 const quizActions = require('./quizActions');
 const svg = require('./svg');
+const geometry = require('./geometry');
 const characterActions = require('./characterActions');
 
 
 const getDrawnPath = (userStroke) => ({
   pathString: svg.getPathString(userStroke.externalPoints),
-  points: userStroke.points,
+  points: userStroke.points.map(point => geometry.round(point)),
 });
 
 
diff --git a/src/geometry.js b/src/geometry.js
index fa4981db..59ee9b9f 100644
--- a/src/geometry.js
+++ b/src/geometry.js
@@ -2,6 +2,13 @@ const subtract = (p1, p2) => ({x: p1.x - p2.x, y: p1.y - p2.y});
 const magnitude = (point) => Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2));
 const distance = (point1, point2) => magnitude(subtract(point1, point2));
 const equals = (point1, point2) => point1.x === point2.x && point1.y === point2.y;
+const round = (point, precision = 1) => {
+  const multiplier = precision * 10;
+  return {
+    x: Math.round(multiplier * point.x) / multiplier,
+    y: Math.round(multiplier * point.y) / multiplier,
+  };
+};
 
 const cosineSimilarity = (point1, point2) => {
   const rawDotProduct = point1.x * point2.x + point1.y * point2.y;
@@ -37,6 +44,7 @@ const filterParallelPoints = (points) => {
 };
 
 module.exports = {
+  round,
   equals,
   distance,
   subtract,
diff --git a/src/svg.js b/src/svg.js
index dc298adb..c5d1deee 100644
--- a/src/svg.js
+++ b/src/svg.js
@@ -1,3 +1,6 @@
+const { round } = require('./geometry');
+
+
 function createElm(elmType) {
   return global.document.createElementNS('http://www.w3.org/2000/svg', elmType);
 }
@@ -11,11 +14,12 @@ function attrs(elm, attrsMap) {
 }
 
 function getPathString(points, close = false) {
-  const start = points[0];
+  const start = round(points[0]);
   const remainingPoints = points.slice(1);
   let pathString = `M ${start.x} ${start.y}`;
   remainingPoints.forEach(point => {
-    pathString += ` L ${point.x} ${point.y}`;
+    const roundedPoint = round(point);
+    pathString += ` L ${roundedPoint.x} ${roundedPoint.y}`;
   });
   if (close) pathString += 'Z';
   return pathString;


Test patch:
diff --git a/src/__tests__/Quiz-test.js b/src/__tests__/Quiz-test.js
index f9de5211..533fedf5 100644
--- a/src/__tests__/Quiz-test.js
+++ b/src/__tests__/Quiz-test.js
@@ -428,5 +428,33 @@ describe('Quiz', () => {
       await resolvePromises();
       expect(renderState.state.character.highlight.opacity).toBe(0);
     });
+
+    it('rounds drawn path data', async () => {
+      strokeMatches.mockImplementation(() => true);
+
+      const renderState = createRenderState();
+      const quiz = new Quiz(char, renderState, new Positioner());
+      const onCorrectStroke = jest.fn();
+      quiz.startQuiz(Object.assign({}, opts, { onCorrectStroke }));
+      clock.tick(1000);
+      await resolvePromises();
+
+      quiz.startUserStroke({x: 10.93234, y: 20.4567978});
+      quiz.endUserStroke();
+
+      await resolvePromises();
+      expect(onCorrectStroke).toHaveBeenCalledTimes(1);
+      expect(onCorrectStroke).toHaveBeenLastCalledWith({
+        character: '人',
+        mistakesOnStroke: 0,
+        strokeNum: 0,
+        strokesRemaining: 1,
+        totalMistakes: 0,
+        drawnPath: {
+          pathString: 'M 10.9 20.5',
+          points: [{x: 15.9, y: 25.5}],
+        },
+      });
+    });
   });
 });
diff --git a/src/__tests__/svg-test.js b/src/__tests__/svg-test.js
index 8f4fd89a..c8c8110e 100644
--- a/src/__tests__/svg-test.js
+++ b/src/__tests__/svg-test.js
@@ -19,5 +19,14 @@ describe('svg', () => {
       ];
       expect(svg.getPathString(points, true)).toEqual('M 0 0 L 5 0 L 5 2Z');
     });
+
+    it('rounds points to 1 decimal point', () => {
+      const points = [
+        {x: 0.11113, y: 0.991212},
+        {x: 5.4565, y: 0.923},
+        {x: 5.4456, y: 2},
+      ];
+      expect(svg.getPathString(points, true)).toEqual('M 0.1 1 L 5.5 0.9 L 5.4 2Z');
+    });
   });
 });