js-draw 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/bundle.js +1 -1
- package/dist/src/EditorImage.d.ts +1 -1
- package/dist/src/EditorImage.js +3 -3
- package/dist/src/components/builders/FreehandLineBuilder.js +1 -1
- package/dist/src/geometry/Rect2.js +19 -8
- package/dist/src/rendering/Display.js +4 -3
- package/dist/src/rendering/caching/CacheRecord.js +2 -1
- package/dist/src/rendering/caching/CacheRecordManager.js +2 -10
- package/dist/src/rendering/caching/RenderingCache.js +10 -4
- package/dist/src/rendering/caching/RenderingCacheNode.js +10 -3
- package/dist/src/rendering/caching/testUtils.js +1 -1
- package/dist/src/rendering/caching/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/EditorImage.ts +3 -3
- package/src/components/builders/FreehandLineBuilder.ts +1 -1
- package/src/geometry/Rect2.test.ts +9 -0
- package/src/geometry/Rect2.ts +25 -8
- package/src/rendering/Display.ts +4 -3
- package/src/rendering/caching/CacheRecord.ts +2 -1
- package/src/rendering/caching/CacheRecordManager.ts +2 -12
- package/src/rendering/caching/RenderingCache.test.ts +1 -1
- package/src/rendering/caching/RenderingCache.ts +11 -4
- package/src/rendering/caching/RenderingCacheNode.ts +16 -3
- package/src/rendering/caching/testUtils.ts +1 -0
- package/src/rendering/caching/types.ts +4 -0
@@ -40,7 +40,7 @@ export declare class ImageNode {
|
|
40
40
|
onContentChange(): void;
|
41
41
|
getContent(): AbstractComponent | null;
|
42
42
|
getParent(): ImageNode | null;
|
43
|
-
|
43
|
+
private getChildrenIntersectingRegion;
|
44
44
|
getChildrenOrSelfIntersectingRegion(region: Rect2): ImageNode[];
|
45
45
|
getLeavesIntersectingRegion(region: Rect2, isTooSmall?: TooSmallToRenderCheck): ImageNode[];
|
46
46
|
getLeaves(): ImageNode[];
|
package/dist/src/EditorImage.js
CHANGED
@@ -107,7 +107,7 @@ export class ImageNode {
|
|
107
107
|
getParent() {
|
108
108
|
return this.parent;
|
109
109
|
}
|
110
|
-
|
110
|
+
getChildrenIntersectingRegion(region) {
|
111
111
|
return this.children.filter(child => {
|
112
112
|
return child.getBBox().intersects(region);
|
113
113
|
});
|
@@ -116,7 +116,7 @@ export class ImageNode {
|
|
116
116
|
if (this.content) {
|
117
117
|
return [this];
|
118
118
|
}
|
119
|
-
return this.
|
119
|
+
return this.getChildrenIntersectingRegion(region);
|
120
120
|
}
|
121
121
|
// Returns a list of `ImageNode`s with content (and thus no children).
|
122
122
|
getLeavesIntersectingRegion(region, isTooSmall) {
|
@@ -128,7 +128,7 @@ export class ImageNode {
|
|
128
128
|
if (this.content !== null && this.getBBox().intersects(region)) {
|
129
129
|
result.push(this);
|
130
130
|
}
|
131
|
-
const children = this.
|
131
|
+
const children = this.getChildrenIntersectingRegion(region);
|
132
132
|
for (const child of children) {
|
133
133
|
result.push(...child.getLeavesIntersectingRegion(region, isTooSmall));
|
134
134
|
}
|
@@ -160,7 +160,7 @@ export default class FreehandLineBuilder {
|
|
160
160
|
const upperBoundary = computeBoundaryCurve(1, halfVec);
|
161
161
|
const lowerBoundary = computeBoundaryCurve(-1, halfVec);
|
162
162
|
// If the boundaries have two intersections, increasing the half vector's length could fix this.
|
163
|
-
if (upperBoundary.intersects(lowerBoundary).length
|
163
|
+
if (upperBoundary.intersects(lowerBoundary).length > 0) {
|
164
164
|
halfVec = halfVec.times(2);
|
165
165
|
}
|
166
166
|
const pathCommands = [
|
@@ -38,20 +38,31 @@ export default class Rect2 {
|
|
38
38
|
&& this.bottomRight.y >= other.bottomRight.y;
|
39
39
|
}
|
40
40
|
intersects(other) {
|
41
|
-
|
41
|
+
// Project along x/y axes.
|
42
|
+
const thisMinX = this.x;
|
43
|
+
const thisMaxX = thisMinX + this.w;
|
44
|
+
const otherMinX = other.x;
|
45
|
+
const otherMaxX = other.x + other.w;
|
46
|
+
if (thisMaxX < otherMinX || thisMinX > otherMaxX) {
|
47
|
+
return false;
|
48
|
+
}
|
49
|
+
const thisMinY = this.y;
|
50
|
+
const thisMaxY = thisMinY + this.h;
|
51
|
+
const otherMinY = other.y;
|
52
|
+
const otherMaxY = other.y + other.h;
|
53
|
+
if (thisMaxY < otherMinY || thisMinY > otherMaxY) {
|
54
|
+
return false;
|
55
|
+
}
|
56
|
+
return true;
|
42
57
|
}
|
43
58
|
// Returns the overlap of this and [other], or null, if no such
|
44
59
|
// overlap exists
|
45
60
|
intersection(other) {
|
46
|
-
|
47
|
-
const bottomRight = this.bottomRight.zip(other.bottomRight, Math.min);
|
48
|
-
// The intersection can't be outside of this rectangle
|
49
|
-
if (!this.containsPoint(topLeft) || !this.containsPoint(bottomRight)) {
|
50
|
-
return null;
|
51
|
-
}
|
52
|
-
else if (!other.containsPoint(topLeft) || !other.containsPoint(bottomRight)) {
|
61
|
+
if (!this.intersects(other)) {
|
53
62
|
return null;
|
54
63
|
}
|
64
|
+
const topLeft = this.topLeft.zip(other.topLeft, Math.max);
|
65
|
+
const bottomRight = this.bottomRight.zip(other.bottomRight, Math.min);
|
55
66
|
return Rect2.fromCorners(topLeft, bottomRight);
|
56
67
|
}
|
57
68
|
// Returns a new rectangle containing both [this] and [other].
|
@@ -23,7 +23,7 @@ export default class Display {
|
|
23
23
|
else {
|
24
24
|
throw new Error(`Unknown rendering mode, ${mode}!`);
|
25
25
|
}
|
26
|
-
const cacheBlockResolution = Vec2.of(
|
26
|
+
const cacheBlockResolution = Vec2.of(600, 600);
|
27
27
|
this.cache = new RenderingCache({
|
28
28
|
createRenderer: () => {
|
29
29
|
if (mode === RenderingMode.DummyRenderer) {
|
@@ -45,8 +45,9 @@ export default class Display {
|
|
45
45
|
},
|
46
46
|
blockResolution: cacheBlockResolution,
|
47
47
|
cacheSize: 500 * 500 * 4 * 200,
|
48
|
-
maxScale: 1.
|
49
|
-
minComponentsPerCache:
|
48
|
+
maxScale: 1.5,
|
49
|
+
minComponentsPerCache: 50,
|
50
|
+
minComponentsToUseCache: 120,
|
50
51
|
});
|
51
52
|
this.editor.notifier.on(EditorEventType.DisplayResized, event => {
|
52
53
|
var _a;
|
@@ -11,7 +11,7 @@ export default class CacheRecord {
|
|
11
11
|
this.allocd = true;
|
12
12
|
}
|
13
13
|
startRender() {
|
14
|
-
this.lastUsedCycle = this.cacheState.currentRenderingCycle
|
14
|
+
this.lastUsedCycle = this.cacheState.currentRenderingCycle;
|
15
15
|
if (!this.allocd) {
|
16
16
|
throw new Error('Only alloc\'d canvases can be rendered to');
|
17
17
|
}
|
@@ -33,6 +33,7 @@ export default class CacheRecord {
|
|
33
33
|
}
|
34
34
|
this.allocd = true;
|
35
35
|
this.onBeforeDeallocCallback = newDeallocCallback;
|
36
|
+
this.lastUsedCycle = this.cacheState.currentRenderingCycle;
|
36
37
|
}
|
37
38
|
getLastUsedCycle() {
|
38
39
|
return this.lastUsedCycle;
|
@@ -25,15 +25,7 @@ export class CacheRecordManager {
|
|
25
25
|
}
|
26
26
|
// Returns null if there are no cache records. Returns an unalloc'd record if one exists.
|
27
27
|
getLeastRecentlyUsedRecord() {
|
28
|
-
|
29
|
-
|
30
|
-
if (!rec.isAllocd()) {
|
31
|
-
return rec;
|
32
|
-
}
|
33
|
-
if (!lruSoFar || rec.getLastUsedCycle() < lruSoFar.getLastUsedCycle()) {
|
34
|
-
lruSoFar = rec;
|
35
|
-
}
|
36
|
-
}
|
37
|
-
return lruSoFar;
|
28
|
+
this.cacheRecords.sort((a, b) => a.getLastUsedCycle() - b.getLastUsedCycle());
|
29
|
+
return this.cacheRecords[0];
|
38
30
|
}
|
39
31
|
}
|
@@ -22,15 +22,21 @@ export default class RenderingCache {
|
|
22
22
|
return;
|
23
23
|
}
|
24
24
|
if (!this.rootNode) {
|
25
|
-
//
|
26
|
-
const
|
25
|
+
// Adjust the node so that it has the correct aspect ratio
|
26
|
+
const res = this.partialSharedState.props.blockResolution;
|
27
27
|
const topLeft = visibleRect.topLeft;
|
28
|
-
this.rootNode = new RenderingCacheNode(new Rect2(topLeft.x, topLeft.y,
|
28
|
+
this.rootNode = new RenderingCacheNode(new Rect2(topLeft.x, topLeft.y, res.x, res.y), this.getSharedState());
|
29
29
|
}
|
30
30
|
while (!this.rootNode.region.containsRect(visibleRect)) {
|
31
31
|
this.rootNode = this.rootNode.generateParent();
|
32
32
|
}
|
33
33
|
this.rootNode = (_a = this.rootNode.smallestChildContaining(visibleRect)) !== null && _a !== void 0 ? _a : this.rootNode;
|
34
|
-
|
34
|
+
const visibleLeaves = image.getLeavesIntersectingRegion(viewport.visibleRect, rect => screenRenderer.isTooSmallToRender(rect));
|
35
|
+
if (visibleLeaves.length > this.partialSharedState.props.minComponentsToUseCache) {
|
36
|
+
this.rootNode.renderItems(screenRenderer, [image], viewport);
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
image.render(screenRenderer, visibleRect);
|
40
|
+
}
|
35
41
|
}
|
36
42
|
}
|
@@ -133,7 +133,11 @@ export default class RenderingCacheNode {
|
|
133
133
|
const newItems = [];
|
134
134
|
// Divide [items] until nodes are leaves or smaller than this
|
135
135
|
for (const item of items) {
|
136
|
-
|
136
|
+
const bbox = item.getBBox();
|
137
|
+
if (!bbox.intersects(this.region)) {
|
138
|
+
continue;
|
139
|
+
}
|
140
|
+
if (bbox.maxDimension >= this.region.maxDimension) {
|
137
141
|
newItems.push(...item.getChildrenOrSelfIntersectingRegion(this.region));
|
138
142
|
}
|
139
143
|
else {
|
@@ -146,6 +150,9 @@ export default class RenderingCacheNode {
|
|
146
150
|
items.forEach(item => item.render(screenRenderer, viewport.visibleRect));
|
147
151
|
return;
|
148
152
|
}
|
153
|
+
if (debugMode) {
|
154
|
+
screenRenderer.drawRect(this.region, 0.5 * viewport.getSizeOfPixelOnCanvas(), { fill: Color4.yellow });
|
155
|
+
}
|
149
156
|
// Could we render direclty from [this] or do we need to recurse?
|
150
157
|
const couldRender = this.renderingWouldBeHighEnoughResolution(viewport);
|
151
158
|
if (!couldRender) {
|
@@ -159,7 +166,7 @@ export default class RenderingCacheNode {
|
|
159
166
|
// Determine whether we already have rendered the items
|
160
167
|
const leaves = [];
|
161
168
|
for (const item of items) {
|
162
|
-
leaves.push(...item.getLeavesIntersectingRegion(this.region));
|
169
|
+
leaves.push(...item.getLeavesIntersectingRegion(this.region, rect => rect.w / this.region.w < 2 / this.cacheState.props.blockResolution.x));
|
163
170
|
}
|
164
171
|
sortLeavesByZIndex(leaves);
|
165
172
|
const leavesByIds = this.computeSortedByLeafIds(leaves);
|
@@ -213,7 +220,7 @@ export default class RenderingCacheNode {
|
|
213
220
|
}
|
214
221
|
}
|
215
222
|
if (debugMode) {
|
216
|
-
screenRenderer.drawRect(this.region, viewport.getSizeOfPixelOnCanvas(), { fill: Color4.
|
223
|
+
screenRenderer.drawRect(this.region, viewport.getSizeOfPixelOnCanvas(), { fill: Color4.clay });
|
217
224
|
}
|
218
225
|
}
|
219
226
|
}
|
@@ -12,7 +12,7 @@ export const createCache = (onRenderAlloc, cacheOptions) => {
|
|
12
12
|
},
|
13
13
|
isOfCorrectType(renderer) {
|
14
14
|
return renderer instanceof DummyRenderer;
|
15
|
-
}, blockResolution: Vec2.of(500, 500), cacheSize: 500 * 10 * 4, maxScale: 2, minComponentsPerCache: 0 }, cacheOptions));
|
15
|
+
}, blockResolution: Vec2.of(500, 500), cacheSize: 500 * 10 * 4, maxScale: 2, minComponentsPerCache: 0, minComponentsToUseCache: 0 }, cacheOptions));
|
16
16
|
return {
|
17
17
|
cache,
|
18
18
|
editor
|
package/package.json
CHANGED
package/src/EditorImage.ts
CHANGED
@@ -137,7 +137,7 @@ export class ImageNode {
|
|
137
137
|
return this.parent;
|
138
138
|
}
|
139
139
|
|
140
|
-
|
140
|
+
private getChildrenIntersectingRegion(region: Rect2): ImageNode[] {
|
141
141
|
return this.children.filter(child => {
|
142
142
|
return child.getBBox().intersects(region);
|
143
143
|
});
|
@@ -147,7 +147,7 @@ export class ImageNode {
|
|
147
147
|
if (this.content) {
|
148
148
|
return [this];
|
149
149
|
}
|
150
|
-
return this.
|
150
|
+
return this.getChildrenIntersectingRegion(region);
|
151
151
|
}
|
152
152
|
|
153
153
|
// Returns a list of `ImageNode`s with content (and thus no children).
|
@@ -163,7 +163,7 @@ export class ImageNode {
|
|
163
163
|
result.push(this);
|
164
164
|
}
|
165
165
|
|
166
|
-
const children = this.
|
166
|
+
const children = this.getChildrenIntersectingRegion(region);
|
167
167
|
for (const child of children) {
|
168
168
|
result.push(...child.getLeavesIntersectingRegion(region, isTooSmall));
|
169
169
|
}
|
@@ -212,7 +212,7 @@ export default class FreehandLineBuilder implements ComponentBuilder {
|
|
212
212
|
const lowerBoundary = computeBoundaryCurve(-1, halfVec);
|
213
213
|
|
214
214
|
// If the boundaries have two intersections, increasing the half vector's length could fix this.
|
215
|
-
if (upperBoundary.intersects(lowerBoundary).length
|
215
|
+
if (upperBoundary.intersects(lowerBoundary).length > 0) {
|
216
216
|
halfVec = halfVec.times(2);
|
217
217
|
}
|
218
218
|
|
@@ -148,4 +148,13 @@ describe('Rect2', () => {
|
|
148
148
|
expect(Rect2.empty.divideIntoGrid(1000, 10000).length).toBe(1);
|
149
149
|
});
|
150
150
|
});
|
151
|
+
|
152
|
+
it('division of rectangle', () => {
|
153
|
+
expect(new Rect2(0, 0, 2, 1).divideIntoGrid(2, 2)).toMatchObject(
|
154
|
+
[
|
155
|
+
new Rect2(0, 0, 1, 0.5), new Rect2(1, 0, 1, 0.5),
|
156
|
+
new Rect2(0, 0.5, 1, 0.5), new Rect2(1, 0.5, 1, 0.5),
|
157
|
+
]
|
158
|
+
);
|
159
|
+
});
|
151
160
|
});
|
package/src/geometry/Rect2.ts
CHANGED
@@ -67,22 +67,39 @@ export default class Rect2 {
|
|
67
67
|
}
|
68
68
|
|
69
69
|
public intersects(other: Rect2): boolean {
|
70
|
-
|
70
|
+
// Project along x/y axes.
|
71
|
+
const thisMinX = this.x;
|
72
|
+
const thisMaxX = thisMinX + this.w;
|
73
|
+
const otherMinX = other.x;
|
74
|
+
const otherMaxX = other.x + other.w;
|
75
|
+
|
76
|
+
if (thisMaxX < otherMinX || thisMinX > otherMaxX) {
|
77
|
+
return false;
|
78
|
+
}
|
79
|
+
|
80
|
+
|
81
|
+
const thisMinY = this.y;
|
82
|
+
const thisMaxY = thisMinY + this.h;
|
83
|
+
const otherMinY = other.y;
|
84
|
+
const otherMaxY = other.y + other.h;
|
85
|
+
|
86
|
+
if (thisMaxY < otherMinY || thisMinY > otherMaxY) {
|
87
|
+
return false;
|
88
|
+
}
|
89
|
+
|
90
|
+
return true;
|
71
91
|
}
|
72
92
|
|
73
93
|
// Returns the overlap of this and [other], or null, if no such
|
74
94
|
// overlap exists
|
75
95
|
public intersection(other: Rect2): Rect2|null {
|
76
|
-
|
77
|
-
const bottomRight = this.bottomRight.zip(other.bottomRight, Math.min);
|
78
|
-
|
79
|
-
// The intersection can't be outside of this rectangle
|
80
|
-
if (!this.containsPoint(topLeft) || !this.containsPoint(bottomRight)) {
|
81
|
-
return null;
|
82
|
-
} else if (!other.containsPoint(topLeft) || !other.containsPoint(bottomRight)) {
|
96
|
+
if (!this.intersects(other)) {
|
83
97
|
return null;
|
84
98
|
}
|
85
99
|
|
100
|
+
const topLeft = this.topLeft.zip(other.topLeft, Math.max);
|
101
|
+
const bottomRight = this.bottomRight.zip(other.bottomRight, Math.min);
|
102
|
+
|
86
103
|
return Rect2.fromCorners(topLeft, bottomRight);
|
87
104
|
}
|
88
105
|
|
package/src/rendering/Display.ts
CHANGED
@@ -31,7 +31,7 @@ export default class Display {
|
|
31
31
|
throw new Error(`Unknown rendering mode, ${mode}!`);
|
32
32
|
}
|
33
33
|
|
34
|
-
const cacheBlockResolution = Vec2.of(
|
34
|
+
const cacheBlockResolution = Vec2.of(600, 600);
|
35
35
|
this.cache = new RenderingCache({
|
36
36
|
createRenderer: () => {
|
37
37
|
if (mode === RenderingMode.DummyRenderer) {
|
@@ -54,8 +54,9 @@ export default class Display {
|
|
54
54
|
},
|
55
55
|
blockResolution: cacheBlockResolution,
|
56
56
|
cacheSize: 500 * 500 * 4 * 200,
|
57
|
-
maxScale: 1.
|
58
|
-
minComponentsPerCache:
|
57
|
+
maxScale: 1.5,
|
58
|
+
minComponentsPerCache: 50,
|
59
|
+
minComponentsToUseCache: 120,
|
59
60
|
});
|
60
61
|
|
61
62
|
this.editor.notifier.on(EditorEventType.DisplayResized, event => {
|
@@ -21,7 +21,7 @@ export default class CacheRecord {
|
|
21
21
|
}
|
22
22
|
|
23
23
|
public startRender(): AbstractRenderer {
|
24
|
-
this.lastUsedCycle = this.cacheState.currentRenderingCycle
|
24
|
+
this.lastUsedCycle = this.cacheState.currentRenderingCycle;
|
25
25
|
if (!this.allocd) {
|
26
26
|
throw new Error('Only alloc\'d canvases can be rendered to');
|
27
27
|
}
|
@@ -45,6 +45,7 @@ export default class CacheRecord {
|
|
45
45
|
}
|
46
46
|
this.allocd = true;
|
47
47
|
this.onBeforeDeallocCallback = newDeallocCallback;
|
48
|
+
this.lastUsedCycle = this.cacheState.currentRenderingCycle;
|
48
49
|
}
|
49
50
|
|
50
51
|
public getLastUsedCycle(): number {
|
@@ -39,17 +39,7 @@ export class CacheRecordManager {
|
|
39
39
|
|
40
40
|
// Returns null if there are no cache records. Returns an unalloc'd record if one exists.
|
41
41
|
private getLeastRecentlyUsedRecord(): CacheRecord|null {
|
42
|
-
|
43
|
-
|
44
|
-
if (!rec.isAllocd()) {
|
45
|
-
return rec;
|
46
|
-
}
|
47
|
-
|
48
|
-
if (!lruSoFar || rec.getLastUsedCycle() < lruSoFar.getLastUsedCycle()) {
|
49
|
-
lruSoFar = rec;
|
50
|
-
}
|
51
|
-
}
|
52
|
-
|
53
|
-
return lruSoFar;
|
42
|
+
this.cacheRecords.sort((a, b) => a.getLastUsedCycle() - b.getLastUsedCycle());
|
43
|
+
return this.cacheRecords[0];
|
54
44
|
}
|
55
45
|
}
|
@@ -10,7 +10,7 @@ import Viewport from '../../Viewport';
|
|
10
10
|
import Mat33 from '../../geometry/Mat33';
|
11
11
|
|
12
12
|
describe('RenderingCache', () => {
|
13
|
-
const testPath = Path.fromString('M0,0 l100,500 l-20,20');
|
13
|
+
const testPath = Path.fromString('M0,0 l100,500 l-20,20 L-100,-100');
|
14
14
|
const testStroke = new Stroke([ testPath.toRenderable({ fill: Color4.purple }) ]);
|
15
15
|
|
16
16
|
it('should create a root node large enough to contain the viewport', () => {
|
@@ -37,11 +37,12 @@ export default class RenderingCache {
|
|
37
37
|
}
|
38
38
|
|
39
39
|
if (!this.rootNode) {
|
40
|
-
//
|
41
|
-
const
|
40
|
+
// Adjust the node so that it has the correct aspect ratio
|
41
|
+
const res = this.partialSharedState.props.blockResolution;
|
42
|
+
|
42
43
|
const topLeft = visibleRect.topLeft;
|
43
44
|
this.rootNode = new RenderingCacheNode(
|
44
|
-
new Rect2(topLeft.x, topLeft.y,
|
45
|
+
new Rect2(topLeft.x, topLeft.y, res.x, res.y),
|
45
46
|
this.getSharedState()
|
46
47
|
);
|
47
48
|
}
|
@@ -51,6 +52,12 @@ export default class RenderingCache {
|
|
51
52
|
}
|
52
53
|
|
53
54
|
this.rootNode = this.rootNode!.smallestChildContaining(visibleRect) ?? this.rootNode;
|
54
|
-
|
55
|
+
|
56
|
+
const visibleLeaves = image.getLeavesIntersectingRegion(viewport.visibleRect, rect => screenRenderer.isTooSmallToRender(rect));
|
57
|
+
if (visibleLeaves.length > this.partialSharedState.props.minComponentsToUseCache) {
|
58
|
+
this.rootNode!.renderItems(screenRenderer, [ image ], viewport);
|
59
|
+
} else {
|
60
|
+
image.render(screenRenderer, visibleRect);
|
61
|
+
}
|
55
62
|
}
|
56
63
|
}
|
@@ -172,7 +172,12 @@ export default class RenderingCacheNode {
|
|
172
172
|
const newItems = [];
|
173
173
|
// Divide [items] until nodes are leaves or smaller than this
|
174
174
|
for (const item of items) {
|
175
|
-
|
175
|
+
const bbox = item.getBBox();
|
176
|
+
if (!bbox.intersects(this.region)) {
|
177
|
+
continue;
|
178
|
+
}
|
179
|
+
|
180
|
+
if (bbox.maxDimension >= this.region.maxDimension) {
|
176
181
|
newItems.push(...item.getChildrenOrSelfIntersectingRegion(this.region));
|
177
182
|
} else {
|
178
183
|
newItems.push(item);
|
@@ -186,6 +191,10 @@ export default class RenderingCacheNode {
|
|
186
191
|
return;
|
187
192
|
}
|
188
193
|
|
194
|
+
if (debugMode) {
|
195
|
+
screenRenderer.drawRect(this.region, 0.5 * viewport.getSizeOfPixelOnCanvas(), { fill: Color4.yellow });
|
196
|
+
}
|
197
|
+
|
189
198
|
// Could we render direclty from [this] or do we need to recurse?
|
190
199
|
const couldRender = this.renderingWouldBeHighEnoughResolution(viewport);
|
191
200
|
if (!couldRender) {
|
@@ -198,7 +207,11 @@ export default class RenderingCacheNode {
|
|
198
207
|
// Determine whether we already have rendered the items
|
199
208
|
const leaves = [];
|
200
209
|
for (const item of items) {
|
201
|
-
leaves.push(
|
210
|
+
leaves.push(
|
211
|
+
...item.getLeavesIntersectingRegion(
|
212
|
+
this.region, rect => rect.w / this.region.w < 2 / this.cacheState.props.blockResolution.x,
|
213
|
+
)
|
214
|
+
);
|
202
215
|
}
|
203
216
|
sortLeavesByZIndex(leaves);
|
204
217
|
const leavesByIds = this.computeSortedByLeafIds(leaves);
|
@@ -266,7 +279,7 @@ export default class RenderingCacheNode {
|
|
266
279
|
}
|
267
280
|
|
268
281
|
if (debugMode) {
|
269
|
-
screenRenderer.drawRect(this.region, viewport.getSizeOfPixelOnCanvas(), { fill: Color4.
|
282
|
+
screenRenderer.drawRect(this.region, viewport.getSizeOfPixelOnCanvas(), { fill: Color4.clay });
|
270
283
|
}
|
271
284
|
}
|
272
285
|
}
|
@@ -21,6 +21,10 @@ export interface CacheProps {
|
|
21
21
|
|
22
22
|
// Minimum component count to cache, rather than just re-render each time.
|
23
23
|
minComponentsPerCache: number;
|
24
|
+
|
25
|
+
// Minimum number of strokes/etc. to use the cache to render, isntead of
|
26
|
+
// rendering directly.
|
27
|
+
minComponentsToUseCache: number;
|
24
28
|
}
|
25
29
|
|
26
30
|
// CacheRecordManager relies on a partial copy of the shared state. Thus,
|