Browse Source

encodes local storage data, hides off-screen shapes

main
Steve Ruiz 3 years ago
parent
commit
c88206fd47
3 changed files with 107 additions and 35 deletions
  1. 30
    27
      components/canvas/page.tsx
  2. 14
    8
      state/storage.ts
  3. 63
    0
      utils/utils.ts

+ 30
- 27
components/canvas/page.tsx View File

@@ -1,7 +1,7 @@
1 1
 import { getShapeUtils } from 'lib/shape-utils'
2 2
 import state, { useSelector } from 'state'
3 3
 import { Bounds, GroupShape, PageState } from 'types'
4
-import { boundsContain } from 'utils/bounds'
4
+import { boundsCollide, boundsContain } from 'utils/bounds'
5 5
 import { deepCompareArrays, getPage, screenToWorld } from 'utils/utils'
6 6
 import Shape from './shape'
7 7
 
@@ -20,36 +20,39 @@ export default function Page() {
20 20
     const page = getPage(s.data)
21 21
     const pageState = s.data.pageStates[page.id]
22 22
 
23
-    // if (!viewportCache.has(pageState)) {
24
-    //   const [minX, minY] = screenToWorld([0, 0], s.data)
25
-    //   const [maxX, maxY] = screenToWorld(
26
-    //     [window.innerWidth, window.innerHeight],
27
-    //     s.data
28
-    //   )
29
-    //   viewportCache.set(pageState, {
30
-    //     minX,
31
-    //     minY,
32
-    //     maxX,
33
-    //     maxY,
34
-    //     height: maxX - minX,
35
-    //     width: maxY - minY,
36
-    //   })
37
-    // }
23
+    if (!viewportCache.has(pageState)) {
24
+      const [minX, minY] = screenToWorld([0, 0], s.data)
25
+      const [maxX, maxY] = screenToWorld(
26
+        [window.innerWidth, window.innerHeight],
27
+        s.data
28
+      )
29
+      viewportCache.set(pageState, {
30
+        minX,
31
+        minY,
32
+        maxX,
33
+        maxY,
34
+        height: maxX - minX,
35
+        width: maxY - minY,
36
+      })
37
+    }
38 38
 
39
-    // const viewport = viewportCache.get(pageState)
39
+    const viewport = viewportCache.get(pageState)
40 40
 
41
-    return (
42
-      Object.values(page.shapes)
43
-        .filter((shape) => shape.parentId === page.id)
44
-        // .filter((shape) => {
45
-        //   const shapeBounds = getShapeUtils(shape).getBounds(shape)
46
-        //   return boundsContain(viewport, shapeBounds)
47
-        // })
48
-        .sort((a, b) => a.childIndex - b.childIndex)
49
-        .map((shape) => shape.id)
50
-    )
41
+    return Object.values(page.shapes)
42
+      .filter((shape) => shape.parentId === page.id)
43
+      .filter((shape) => {
44
+        const shapeBounds = getShapeUtils(shape).getBounds(shape)
45
+        return (
46
+          boundsContain(viewport, shapeBounds) ||
47
+          boundsCollide(viewport, shapeBounds)
48
+        )
49
+      })
50
+      .sort((a, b) => a.childIndex - b.childIndex)
51
+      .map((shape) => shape.id)
51 52
   }, deepCompareArrays)
52 53
 
54
+  console.log(currentPageShapeIds.length)
55
+
53 56
   const isSelecting = useSelector((s) => s.isIn('selecting'))
54 57
 
55 58
   return (

+ 14
- 8
state/storage.ts View File

@@ -1,12 +1,12 @@
1 1
 import * as fa from 'browser-fs-access'
2 2
 import { Data, Page, PageState, TLDocument } from 'types'
3
-import { setToArray } from 'utils/utils'
3
+import { lzw_decode, lzw_encode, setToArray } from 'utils/utils'
4 4
 import state from './state'
5 5
 import { current } from 'immer'
6 6
 import { v4 as uuid } from 'uuid'
7 7
 import * as idb from 'idb-keyval'
8 8
 
9
-const CURRENT_VERSION = 'code_slate_0.0.5'
9
+const CURRENT_VERSION = 'code_slate_0.0.6'
10 10
 const DOCUMENT_ID = '0001'
11 11
 
12 12
 function storageId(fileId: string, label: string, id?: string) {
@@ -69,7 +69,7 @@ class Storage {
69 69
       return false
70 70
     }
71 71
 
72
-    const restoredData: any = JSON.parse(savedData)
72
+    const restoredData: any = JSON.parse(lzw_decode(savedData))
73 73
 
74 74
     for (let pageId in restoredData.document.pages) {
75 75
       const selectedIds = restoredData.pageStates[pageId].selectedIds
@@ -88,7 +88,7 @@ class Storage {
88 88
       )
89 89
 
90 90
       if (savedPage !== null) {
91
-        const restored: Page = JSON.parse(savedPage)
91
+        const restored: Page = JSON.parse(lzw_decode(savedPage))
92 92
         dataToSave.document.pages[pageId] = restored
93 93
       }
94 94
 
@@ -106,7 +106,10 @@ class Storage {
106 106
     const dataToSave = this.getDataToSave(data)
107 107
 
108 108
     // Save current data to local storage
109
-    localStorage.setItem(storageId(fileId, 'document', fileId), dataToSave)
109
+    localStorage.setItem(
110
+      storageId(fileId, 'document', fileId),
111
+      lzw_encode(dataToSave)
112
+    )
110 113
   }
111 114
 
112 115
   loadDocumentFromJson(data: Data, restoredData: any) {
@@ -134,7 +137,7 @@ class Storage {
134 137
     const page = data.document.pages[pageId]
135 138
     const json = JSON.stringify(page)
136 139
 
137
-    localStorage.setItem(storageId(fileId, 'page', pageId), json)
140
+    localStorage.setItem(storageId(fileId, 'page', pageId), lzw_encode(json))
138 141
 
139 142
     // Save page state
140 143
 
@@ -167,7 +170,7 @@ class Storage {
167 170
     const savedPage = localStorage.getItem(storageId(fileId, 'page', pageId))
168 171
 
169 172
     if (savedPage !== null) {
170
-      data.document.pages[pageId] = JSON.parse(savedPage)
173
+      data.document.pages[pageId] = JSON.parse(lzw_decode(savedPage))
171 174
     } else {
172 175
       data.document.pages[pageId] = {
173 176
         id: pageId,
@@ -186,7 +189,6 @@ class Storage {
186 189
 
187 190
     if (savedPageState !== null) {
188 191
       const restored: PageState = JSON.parse(savedPageState)
189
-      restored.selectedIds = new Set(restored.selectedIds)
190 192
       data.pageStates[pageId] = restored
191 193
     } else {
192 194
       data.pageStates[pageId] = {
@@ -198,6 +200,10 @@ class Storage {
198 200
       }
199 201
     }
200 202
 
203
+    data.pageStates[pageId].selectedIds = new Set(
204
+      data.pageStates[pageId].selectedIds
205
+    )
206
+
201 207
     // Empty shapes in state for other pages
202 208
 
203 209
     for (let key in data.document.pages) {

+ 63
- 0
utils/utils.ts View File

@@ -1768,3 +1768,66 @@ export function getPoint(
1768 1768
     'pressure' in e ? e.pressure || 0.5 : 0.5,
1769 1769
   ]
1770 1770
 }
1771
+
1772
+export function lzw_encode(s: string) {
1773
+  const dict = {}
1774
+  const data = (s + '').split('')
1775
+
1776
+  let currChar: string
1777
+  let phrase = data[0]
1778
+  let code = 256
1779
+
1780
+  const out = []
1781
+
1782
+  for (var i = 1; i < data.length; i++) {
1783
+    currChar = data[i]
1784
+
1785
+    if (dict[phrase + currChar] != null) {
1786
+      phrase += currChar
1787
+    } else {
1788
+      out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0))
1789
+      dict[phrase + currChar] = code
1790
+      code++
1791
+      phrase = currChar
1792
+    }
1793
+  }
1794
+
1795
+  out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0))
1796
+
1797
+  for (var i = 0; i < out.length; i++) {
1798
+    out[i] = String.fromCharCode(out[i])
1799
+  }
1800
+
1801
+  return out.join('')
1802
+}
1803
+
1804
+// Decompress an LZW-encoded string
1805
+export function lzw_decode(s: string) {
1806
+  const dict = {}
1807
+  const data = (s + '').split('')
1808
+
1809
+  let currChar = data[0]
1810
+  let oldPhrase = currChar
1811
+  let code = 256
1812
+  let phrase: string
1813
+
1814
+  const out = [currChar]
1815
+
1816
+  for (var i = 1; i < data.length; i++) {
1817
+    let currCode = data[i].charCodeAt(0)
1818
+
1819
+    if (currCode < 256) {
1820
+      phrase = data[i]
1821
+    } else {
1822
+      phrase = dict[currCode] ? dict[currCode] : oldPhrase + currChar
1823
+    }
1824
+
1825
+    out.push(phrase)
1826
+    currChar = phrase.charAt(0)
1827
+    dict[code] = oldPhrase + currChar
1828
+    code++
1829
+    oldPhrase = phrase
1830
+  }
1831
+
1832
+  return out.join('')
1833
+}

Loading…
Cancel
Save