Skip to content

Commit 2e7c654

Browse files
author
Divyanshi Vashist
committed
Added support for %
1 parent 0ea59bc commit 2e7c654

File tree

3 files changed

+154
-26
lines changed

3 files changed

+154
-26
lines changed

src/offsetPath.js

Lines changed: 119 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22
'use strict';
33

44
(function () {
5-
function basicShapePolygonParse (input, element) {
5+
var isNumeric = internalScope.isNumeric;
6+
7+
function roundToHundredth (number) {
8+
return Math.round(number * 100) / 100;
9+
}
10+
11+
function basicShapePolygonParse (input) {
612
// TODO: Support the fill-rule option and %
713
var argumentList = input.split(',');
814
var coordinate = null;
@@ -34,37 +40,127 @@
3440
return {type: 'path', path: path};
3541
}
3642

37-
function basicShapeCircleParse (input, element) {
38-
// TODO: Need element as an argument to this function
39-
var radius;
40-
var position = /at (.*?)$/.exec(input);
43+
function getCirclePathPosition (parentProperties, position) {
44+
var analysedPosition = [];
45+
46+
if (position !== null) {
47+
var positionList = position[1].split(/\s+/);
48+
49+
// If only one value is specified, the second value is assumed to be 'center'
50+
// https://drafts.csswg.org/css-backgrounds-3/#position
51+
for (var index in positionList) {
52+
var aPosition = positionList[index];
53+
54+
var aPositionUnit = /(%|px)$/.exec(aPosition)[1];
55+
if (aPositionUnit === null) {
56+
return null;
57+
}
58+
59+
var aPositionValueString = aPosition.substring(0, aPosition.length - aPositionUnit.length);
60+
if (!isNumeric(aPositionValueString) || aPositionValueString === '') {
61+
return null;
62+
}
63+
64+
var aPositionValue = Number(aPositionValueString);
65+
if (aPositionUnit === '%') {
66+
if (Number(index) === 0) {
67+
if (!parentProperties || !parentProperties.width) {
68+
return null;
69+
}
70+
aPositionValue *= (parentProperties.width / 100);
71+
}
72+
if (Number(index) === 1) {
73+
if (!parentProperties || !parentProperties.height) {
74+
return null;
75+
}
76+
aPositionValue *= (parentProperties.height / 100);
77+
}
78+
}
79+
analysedPosition[index] = aPositionValue;
80+
}
81+
}
82+
83+
if (analysedPosition.length < 2) {
84+
for (var i = analysedPosition.length; i < 2; i++) {
85+
if (Number(i) === 0) {
86+
if (!parentProperties || !parentProperties.width) {
87+
return null;
88+
}
89+
analysedPosition[i] = parentProperties.width / 2;
90+
} else if (Number(i) === 1) {
91+
if (!parentProperties || !parentProperties.height) {
92+
return null;
93+
}
94+
analysedPosition[i] = parentProperties.height / 2;
95+
}
96+
}
97+
}
98+
99+
return analysedPosition;
100+
}
41101

42-
// TODO: Need to support other positions as currently this only supports positions in which both x and y are specified and are in px
102+
function getCirclePathRadius (parentProperties, position, input) {
103+
var radiusString;
43104
if (position === null) {
44-
// TODO: Set default position to the center of the reference box
45-
position = '0px 0px';
46105
if (input !== '') {
47-
radius = input;
106+
radiusString = input;
48107
}
49108
} else {
50-
position = position[1].split(/\s+/);
51-
radius = (/^(.*?) at/.exec(input));
52-
if (radius === null) {
53-
radius = 'closest-side';
109+
radiusString = (/^(.*?) at/.exec(input));
110+
// TODO: Add support for when a radius had not been specified
111+
if (radiusString === null) {
112+
radiusString = 'closest-side';
54113
} else {
55-
radius = radius[1];
114+
radiusString = radiusString[1];
115+
}
116+
}
117+
118+
var radiusUnit = /(%|px)$/.exec(radiusString);
119+
if (radiusUnit === null) {
120+
return null;
121+
}
122+
123+
var radiusValueString = radiusString.substring(0, radiusString.length - radiusUnit[1].length);
124+
if (!isNumeric(radiusValueString)) {
125+
return null;
126+
}
127+
var radiusValue = Number(radiusValueString);
128+
129+
if (radiusUnit[1] === '%') {
130+
var height = parentProperties.height;
131+
var width = parentProperties.width;
132+
if (!height || !width) {
133+
return null;
56134
}
135+
136+
return roundToHundredth((Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)) / Math.sqrt(2)) * radiusValue / 100);
137+
}
138+
139+
return Number(radiusValueString);
140+
}
141+
142+
function basicShapeCircleParse (input, element) {
143+
var parentProperties = null;
144+
if (element) {
145+
parentProperties = element.offsetParent ? element.offsetParent.getBoundingClientRect() : null;
57146
}
58147

59-
radius = Number(radius.substring(0, radius.length - 2));
148+
var position = /at (.*?)$/.exec(input);
149+
150+
var radiusValue = getCirclePathRadius(parentProperties, position, input);
151+
if (!radiusValue) {
152+
return undefined;
153+
}
60154

61-
var positionX = Number(position[0].substring(0, position[0].length - 2));
62-
var positionY = Number(position[1].substring(0, position[1].length - 2));
155+
var analysedPosition = getCirclePathPosition(parentProperties, position);
156+
if (!analysedPosition) {
157+
return undefined;
158+
}
63159

64-
var pathString = 'M ' + positionX + ' ' + positionY +
65-
' m 0,' + (-radius) +
66-
' a ' + radius + ',' + radius + ' 0 0,1 ' + radius + ',' + radius +
67-
' a ' + radius + ',' + radius + ' 0 1,1 ' + (-radius) + ',' + (-radius) + ' z';
160+
var pathString = 'M ' + analysedPosition[0] + ' ' + analysedPosition[1] +
161+
' m 0,' + (-radiusValue) +
162+
' a ' + radiusValue + ',' + radiusValue + ' 0 0,1 ' + radiusValue + ',' + radiusValue +
163+
' a ' + radiusValue + ',' + radiusValue + ' 0 1,1 ' + (-radiusValue) + ',' + (-radiusValue) + ' z';
68164

69165
return {type: 'path', path: pathString};
70166
}
@@ -150,6 +246,7 @@
150246
return undefined;
151247
}
152248
var toParse = [basicShapePolygonParse, basicShapeCircleParse, basicShapeInsetParse, basicShapeEllipseParse];
249+
// var toParse = [basicShapeCircleParse];
153250
for (var i = 0; i < toParse.length; i++) {
154251
var result = toParse[i](shapeArguments[1], element);
155252
if (result) {
@@ -212,4 +309,5 @@
212309

213310
internalScope.offsetPathParse = offsetPathParse;
214311
internalScope.offsetPathMerge = offsetPathMerge;
312+
internalScope.roundToHundredth = roundToHundredth;
215313
})();

src/toTransform.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
'use strict';
33

44
(function () {
5+
var roundToHundredth = internalScope.roundToHundredth;
6+
57
function convertTranslate (input) {
68
var valuesArray = internalScope.translateParse(input);
79

@@ -88,10 +90,6 @@
8890
return offsetDistanceLength;
8991
}
9092

91-
function roundToHundredth (number) {
92-
return Math.round(number * 100) / 100;
93-
}
94-
9593
function convertPathString (properties) {
9694
var offsetPath = internalScope.offsetPathParse(properties['offsetPath']);
9795
var closedLoop = isClosedLoop(offsetPath);

test/pathBasicShapeCircleTest.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,41 @@
1-
/* global suite test internalScope */
1+
/* global assert suite test internalScope */
22

33
(function () {
44
suite('offsetPath', function () {
55
test('basicShapeCircle', function () {
66
var assertTransformInterpolation = internalScope.assertTransformInterpolation;
7+
var offsetPathParse = internalScope.offsetPathParse;
8+
9+
var containerStyle = {
10+
position: 'absolute',
11+
height: '100px',
12+
width: '200px'
13+
};
14+
15+
var container = document.createElement('div');
16+
17+
for (var property in containerStyle) {
18+
container.style[property] = containerStyle[property];
19+
}
20+
21+
var target = document.createElement('div');
22+
container.appendChild(target);
23+
document.body.appendChild(container);
24+
25+
var circlePathString = offsetPathParse('circle(50%)', target).path;
26+
assert.equal(circlePathString, 'M 100 50 m 0,-79.06 a 79.06,79.06 0 0,1 79.06,79.06 a 79.06,79.06 0 1,1 -79.06,-79.06 z');
27+
28+
circlePathString = offsetPathParse('circle(10px)', target).path;
29+
assert.equal(circlePathString, 'M 100 50 m 0,-10 a 10,10 0 0,1 10,10 a 10,10 0 1,1 -10,-10 z');
30+
31+
circlePathString = offsetPathParse('circle(10px at 50%)', target).path;
32+
assert.equal(circlePathString, 'M 100 50 m 0,-10 a 10,10 0 0,1 10,10 a 10,10 0 1,1 -10,-10 z');
33+
34+
circlePathString = offsetPathParse('circle(50% at 100px 200px)', target).path;
35+
assert.equal(circlePathString, 'M 100 200 m 0,-79.06 a 79.06,79.06 0 0,1 79.06,79.06 a 79.06,79.06 0 1,1 -79.06,-79.06 z');
36+
37+
circlePathString = offsetPathParse('circle(10px at 50% 50%)', target).path;
38+
assert.equal(circlePathString, 'M 100 50 m 0,-10 a 10,10 0 0,1 10,10 a 10,10 0 1,1 -10,-10 z');
739

840
assertTransformInterpolation([
941
{'offsetPath': 'circle(10px at 0px 0px)', 'offsetDistance': '0%'},

0 commit comments

Comments
 (0)