Skip to content

Commit 337d460

Browse files
committed
🐛 fix: Fix line-gradient parse
1 parent 6d92cfe commit 337d460

File tree

3 files changed

+112
-34
lines changed

3 files changed

+112
-34
lines changed

src/model/type.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ import SymbolMaster from './Layer/SymbolMaster';
1515
*/
1616
export interface FrameInitParams extends Partial<FrameType> {}
1717

18+
/**
19+
* 节点的背景颜色类型
20+
*/
21+
export type BackgroundImageType = {
22+
type: 'Image' | 'LinearGradient';
23+
value: any;
24+
};
25+
1826
/**
1927
* 定界框类型
2028
*/

src/utils/__tests__/background.spec.ts

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { getActualImageSize } from '../background';
1+
import { BackgroundImageType } from 'html2sketch';
2+
import {
3+
getActualImageSize,
4+
parseBackgroundImage,
5+
parseLinearGradient,
6+
} from '../background';
27

38
describe('getActualImageSize', () => {
49
test('background-size: contain', () => {
@@ -153,3 +158,57 @@ describe('getActualImageSize', () => {
153158
});
154159
});
155160
});
161+
162+
describe('parseBackgroundImage', () => {
163+
describe('渐变', () => {
164+
it('解析三种颜色', () => {
165+
const str = 'linear-gradient(red, yellow, blue)';
166+
const result = parseBackgroundImage(str) as BackgroundImageType;
167+
expect(result.type).toStrictEqual('LinearGradient');
168+
});
169+
});
170+
});
171+
172+
describe('parseLinearGradient', () => {
173+
it('解析两种颜色', () => {
174+
const str = 'red, yellow';
175+
const result = parseLinearGradient(str);
176+
expect(result).toStrictEqual({
177+
stops: ['red', 'yellow'],
178+
angle: '180deg',
179+
});
180+
});
181+
it('解析 to 类型的方向', () => {
182+
const str = 'to right, rgba(255,0,0,0), rgba(255,0,0,1)';
183+
const result = parseLinearGradient(str);
184+
expect(result).toStrictEqual({
185+
stops: ['rgba(255,0,0,0)', 'rgba(255,0,0,1)'],
186+
angle: 'to right',
187+
});
188+
});
189+
it('解析deg 类型的方向', () => {
190+
const str = '90deg, red, blue';
191+
const result = parseLinearGradient(str);
192+
expect(result).toStrictEqual({
193+
stops: ['red', 'blue'],
194+
angle: '90deg',
195+
});
196+
});
197+
it('解析三种颜色', () => {
198+
const str = 'red, yellow, blue';
199+
const result = parseLinearGradient(str);
200+
expect(result).toStrictEqual({
201+
stops: ['red', 'yellow', 'blue'],
202+
angle: '180deg',
203+
});
204+
});
205+
206+
it('解析多种颜色', () => {
207+
const str = 'to left,red, yellow, blue,green';
208+
const result = parseLinearGradient(str);
209+
expect(result).toStrictEqual({
210+
stops: ['red', 'yellow', 'blue', 'green'],
211+
angle: 'to left',
212+
});
213+
});
214+
});

src/utils/background.ts

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
1-
// Parser for a linear gradient:
2-
// ---
3-
// <linear-gradient> = linear-gradient(
4-
// [ [ <angle> | to <side-or-corner> ] ,]?
5-
// <color-stop>[, <color-stop>]+
6-
// )
7-
//
8-
// <side-or-corner> = [left | right] || [top | bottom]
9-
// ---
10-
// Source: https://www.w3.org/TR/css3-images/#linear-gradients
11-
// ---
12-
// Example: "to top, rgba(67, 90, 111, 0.04), white"
13-
const parseLinearGradient = (value: string) => {
1+
import { BackgroundImageType } from '../type';
2+
3+
/**
4+
* 解析线性渐变
5+
*
6+
* ---
7+
* <linear-gradient> = linear-gradient(
8+
* [ [ <angle> | to <side-or-corner> ] ,]?
9+
* <color-stop>[, <color-stop>]+
10+
* )
11+
*
12+
* <side-or-corner> = [left | right] || [top | bottom]
13+
*
14+
* ---
15+
* * Example: "to top, rgba(67, 90, 111, 0.04), white"
16+
*
17+
* @param value
18+
* @see https://www.w3.org/TR/css3-images/#linear-gradients
19+
*/
20+
export const parseLinearGradient = (value: string) => {
1421
const parts = [];
1522
let currentPart = [];
1623
let i = 0;
@@ -47,6 +54,12 @@ const parseLinearGradient = (value: string) => {
4754
};
4855
}
4956
if (parts.length > 2) {
57+
// 如果 parts 的第一个对象 不包含 deg 和 to
58+
// 那就意味着全部都是 stops
59+
if (!parts[0].includes('deg') && !parts[0].includes('to')) {
60+
return { angle: '180deg', stops: parts };
61+
}
62+
5063
// angle + n stops
5164
const [angle, ...stops] = parts;
5265

@@ -60,23 +73,23 @@ const parseLinearGradient = (value: string) => {
6073
return null;
6174
};
6275

63-
type BackgroundImageType = {
64-
type: 'Image' | 'LinearGradient';
65-
value: any;
66-
};
67-
68-
// Parses the background-image. The structure is as follows:
69-
// (Supports images and gradients)
70-
// ---
71-
// <background-image> = <bg-image> [ , <bg-image> ]*
72-
// <bg-image> = <image> | none
73-
// <image> = <url> | <image-list> | <element-reference> | <image-combination> | <gradient>
74-
// ---
75-
// Source: https://www.w3.org/TR/css-backgrounds-3/#the-background-image
76-
// ---
77-
// These functions should be pure to make it easy
78-
// to write test cases in the future.
79-
const parseBackgroundImage = (value: string): BackgroundImageType | void => {
76+
/**
77+
* 解析背景图片
78+
* The structure is as follows:
79+
* (Supports images and gradients)
80+
*
81+
* ---
82+
* <background-image> = <bg-image> [ , <bg-image> ]*
83+
* <bg-image> = <image> | none
84+
* <image> = <url> | <image-list> | <element-reference> | <image-combination> | <gradient>
85+
* ---
86+
* @param value
87+
* @see: https://www.w3.org/TR/css-backgrounds-3/#the-background-image
88+
* ---
89+
*/
90+
export const parseBackgroundImage = (
91+
value: string,
92+
): BackgroundImageType | void => {
8093
if (value === 'none') {
8194
return;
8295
}
@@ -112,7 +125,7 @@ const parseBackgroundImage = (value: string): BackgroundImageType | void => {
112125
* @param {{width: number, height: number}} containerSize size of the container
113126
* @return {{width: number, height: number}} actual image size
114127
*/
115-
const getActualImageSize = (
128+
export const getActualImageSize = (
116129
backgroundSize: string,
117130
imageSize: { width: number; height: number },
118131
containerSize: { width: any; height: any },
@@ -197,5 +210,3 @@ const getActualImageSize = (
197210
height,
198211
};
199212
};
200-
201-
export { parseBackgroundImage, getActualImageSize };

0 commit comments

Comments
 (0)