-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpatternBrush.js
113 lines (96 loc) · 2.63 KB
/
patternBrush.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Logic to place and warp the texture along the curve
let isTextureEnabled = true;
function toggleTexture(){
if(isTextureEnabled && currentFabricSvg){
canvas.remove(currentFabricSvg);
}
isTextureEnabled = !isTextureEnabled;
if(isTextureEnabled){
warpToCurve();
}
}
let isWarping = false;
function warpIfNotAlready() {
if (isTextureEnabled && !isWarping) {
warpToCurve();
}
}
let currentFabricSvg;
async function warpToCurve() {
if(!isTextureEnabled){
return;
}
isWarping = true;
const {width, height, svg} = await selectedSVG;
const scaleX = scale || +scaleElement.value || 1;
const scaleY = scale || +scaleElement.value || 1;
const newWidth = width * scaleX;
const startCurve = curve;
const count = Math.ceil(startCurve.length / newWidth);
const svgs = [];
for (let i = 0; i < count; i++) {
const newSvg = svg.cloneNode(true);
const warp = new Warp(newSvg);
warp.interpolate(4);
warp.transform(([x, y]) => {
// Flipping it around for it to be on the correct side, thanks to fabric.js
// Subtracting height / 2 to center it, instead of making it on / on top of the item
y = height / 2 - y;
let t = ((x * scaleX) + i * newWidth) / startCurve.length;
if (t < 0) t = 0;
if (t > 1) t = 1;
const curveX = startCurve.mx(t);
const curveY = startCurve.my(t);
const normal = startCurve.mNormal(t);
const offsetX = (normal.x * y * scaleX);
const offsetY = (normal.y * y * scaleY);
const newX = curveX + offsetX;
const newY = curveY + offsetY;
return [newX, newY];
});
svgs.push(newSvg);
}
const elements = await Promise.all(svgs.map(element => {
return new Promise(resolve => {
const container = document.createElement('div');
container.appendChild(element);
fabric.loadSVGFromString(
container.innerHTML,
(elements) => {
resolve(elements);
}
);
})
}));
const group = new fabric.Group([...elements.map(element => {
return fabric.util.groupSVGElements(element);
})]);
group.selectable = false;
if (currentFabricSvg) {
canvas.remove(currentFabricSvg);
}
currentFabricSvg = group;
if(isTextureEnabled){
canvas.insertAt(group, 0);
if (curve !== startCurve) {
warpToCurve();
} else {
isWarping = false;
}
} else {
isWarping = false;
}
if(normals.length){
redrawNormals();
}
}
warpIfNotAlready();
// let scale = 0.5;
// let direction = 0.01;
// setInterval(()=>{
// scale += direction;
// if(scale >= 2 || scale <= 0.5){
// direction *= -1;
// }
// warpIfNotAlready();
// }, 50)