encodes local storage data, hides off-screen shapes
This commit is contained in:
parent
c8070857b1
commit
c88206fd47
3 changed files with 107 additions and 35 deletions
|
@ -1,7 +1,7 @@
|
||||||
import { getShapeUtils } from 'lib/shape-utils'
|
import { getShapeUtils } from 'lib/shape-utils'
|
||||||
import state, { useSelector } from 'state'
|
import state, { useSelector } from 'state'
|
||||||
import { Bounds, GroupShape, PageState } from 'types'
|
import { Bounds, GroupShape, PageState } from 'types'
|
||||||
import { boundsContain } from 'utils/bounds'
|
import { boundsCollide, boundsContain } from 'utils/bounds'
|
||||||
import { deepCompareArrays, getPage, screenToWorld } from 'utils/utils'
|
import { deepCompareArrays, getPage, screenToWorld } from 'utils/utils'
|
||||||
import Shape from './shape'
|
import Shape from './shape'
|
||||||
|
|
||||||
|
@ -20,36 +20,39 @@ export default function Page() {
|
||||||
const page = getPage(s.data)
|
const page = getPage(s.data)
|
||||||
const pageState = s.data.pageStates[page.id]
|
const pageState = s.data.pageStates[page.id]
|
||||||
|
|
||||||
// if (!viewportCache.has(pageState)) {
|
if (!viewportCache.has(pageState)) {
|
||||||
// const [minX, minY] = screenToWorld([0, 0], s.data)
|
const [minX, minY] = screenToWorld([0, 0], s.data)
|
||||||
// const [maxX, maxY] = screenToWorld(
|
const [maxX, maxY] = screenToWorld(
|
||||||
// [window.innerWidth, window.innerHeight],
|
[window.innerWidth, window.innerHeight],
|
||||||
// s.data
|
s.data
|
||||||
// )
|
)
|
||||||
// viewportCache.set(pageState, {
|
viewportCache.set(pageState, {
|
||||||
// minX,
|
minX,
|
||||||
// minY,
|
minY,
|
||||||
// maxX,
|
maxX,
|
||||||
// maxY,
|
maxY,
|
||||||
// height: maxX - minX,
|
height: maxX - minX,
|
||||||
// width: maxY - minY,
|
width: maxY - minY,
|
||||||
// })
|
})
|
||||||
// }
|
}
|
||||||
|
|
||||||
// const viewport = viewportCache.get(pageState)
|
const viewport = viewportCache.get(pageState)
|
||||||
|
|
||||||
return (
|
return Object.values(page.shapes)
|
||||||
Object.values(page.shapes)
|
.filter((shape) => shape.parentId === page.id)
|
||||||
.filter((shape) => shape.parentId === page.id)
|
.filter((shape) => {
|
||||||
// .filter((shape) => {
|
const shapeBounds = getShapeUtils(shape).getBounds(shape)
|
||||||
// const shapeBounds = getShapeUtils(shape).getBounds(shape)
|
return (
|
||||||
// return boundsContain(viewport, shapeBounds)
|
boundsContain(viewport, shapeBounds) ||
|
||||||
// })
|
boundsCollide(viewport, shapeBounds)
|
||||||
.sort((a, b) => a.childIndex - b.childIndex)
|
)
|
||||||
.map((shape) => shape.id)
|
})
|
||||||
)
|
.sort((a, b) => a.childIndex - b.childIndex)
|
||||||
|
.map((shape) => shape.id)
|
||||||
}, deepCompareArrays)
|
}, deepCompareArrays)
|
||||||
|
|
||||||
|
console.log(currentPageShapeIds.length)
|
||||||
|
|
||||||
const isSelecting = useSelector((s) => s.isIn('selecting'))
|
const isSelecting = useSelector((s) => s.isIn('selecting'))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import * as fa from 'browser-fs-access'
|
import * as fa from 'browser-fs-access'
|
||||||
import { Data, Page, PageState, TLDocument } from 'types'
|
import { Data, Page, PageState, TLDocument } from 'types'
|
||||||
import { setToArray } from 'utils/utils'
|
import { lzw_decode, lzw_encode, setToArray } from 'utils/utils'
|
||||||
import state from './state'
|
import state from './state'
|
||||||
import { current } from 'immer'
|
import { current } from 'immer'
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
import * as idb from 'idb-keyval'
|
import * as idb from 'idb-keyval'
|
||||||
|
|
||||||
const CURRENT_VERSION = 'code_slate_0.0.5'
|
const CURRENT_VERSION = 'code_slate_0.0.6'
|
||||||
const DOCUMENT_ID = '0001'
|
const DOCUMENT_ID = '0001'
|
||||||
|
|
||||||
function storageId(fileId: string, label: string, id?: string) {
|
function storageId(fileId: string, label: string, id?: string) {
|
||||||
|
@ -69,7 +69,7 @@ class Storage {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
const restoredData: any = JSON.parse(savedData)
|
const restoredData: any = JSON.parse(lzw_decode(savedData))
|
||||||
|
|
||||||
for (let pageId in restoredData.document.pages) {
|
for (let pageId in restoredData.document.pages) {
|
||||||
const selectedIds = restoredData.pageStates[pageId].selectedIds
|
const selectedIds = restoredData.pageStates[pageId].selectedIds
|
||||||
|
@ -88,7 +88,7 @@ class Storage {
|
||||||
)
|
)
|
||||||
|
|
||||||
if (savedPage !== null) {
|
if (savedPage !== null) {
|
||||||
const restored: Page = JSON.parse(savedPage)
|
const restored: Page = JSON.parse(lzw_decode(savedPage))
|
||||||
dataToSave.document.pages[pageId] = restored
|
dataToSave.document.pages[pageId] = restored
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,10 @@ class Storage {
|
||||||
const dataToSave = this.getDataToSave(data)
|
const dataToSave = this.getDataToSave(data)
|
||||||
|
|
||||||
// Save current data to local storage
|
// Save current data to local storage
|
||||||
localStorage.setItem(storageId(fileId, 'document', fileId), dataToSave)
|
localStorage.setItem(
|
||||||
|
storageId(fileId, 'document', fileId),
|
||||||
|
lzw_encode(dataToSave)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDocumentFromJson(data: Data, restoredData: any) {
|
loadDocumentFromJson(data: Data, restoredData: any) {
|
||||||
|
@ -134,7 +137,7 @@ class Storage {
|
||||||
const page = data.document.pages[pageId]
|
const page = data.document.pages[pageId]
|
||||||
const json = JSON.stringify(page)
|
const json = JSON.stringify(page)
|
||||||
|
|
||||||
localStorage.setItem(storageId(fileId, 'page', pageId), json)
|
localStorage.setItem(storageId(fileId, 'page', pageId), lzw_encode(json))
|
||||||
|
|
||||||
// Save page state
|
// Save page state
|
||||||
|
|
||||||
|
@ -167,7 +170,7 @@ class Storage {
|
||||||
const savedPage = localStorage.getItem(storageId(fileId, 'page', pageId))
|
const savedPage = localStorage.getItem(storageId(fileId, 'page', pageId))
|
||||||
|
|
||||||
if (savedPage !== null) {
|
if (savedPage !== null) {
|
||||||
data.document.pages[pageId] = JSON.parse(savedPage)
|
data.document.pages[pageId] = JSON.parse(lzw_decode(savedPage))
|
||||||
} else {
|
} else {
|
||||||
data.document.pages[pageId] = {
|
data.document.pages[pageId] = {
|
||||||
id: pageId,
|
id: pageId,
|
||||||
|
@ -186,7 +189,6 @@ class Storage {
|
||||||
|
|
||||||
if (savedPageState !== null) {
|
if (savedPageState !== null) {
|
||||||
const restored: PageState = JSON.parse(savedPageState)
|
const restored: PageState = JSON.parse(savedPageState)
|
||||||
restored.selectedIds = new Set(restored.selectedIds)
|
|
||||||
data.pageStates[pageId] = restored
|
data.pageStates[pageId] = restored
|
||||||
} else {
|
} else {
|
||||||
data.pageStates[pageId] = {
|
data.pageStates[pageId] = {
|
||||||
|
@ -198,6 +200,10 @@ class Storage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.pageStates[pageId].selectedIds = new Set(
|
||||||
|
data.pageStates[pageId].selectedIds
|
||||||
|
)
|
||||||
|
|
||||||
// Empty shapes in state for other pages
|
// Empty shapes in state for other pages
|
||||||
|
|
||||||
for (let key in data.document.pages) {
|
for (let key in data.document.pages) {
|
||||||
|
|
|
@ -1768,3 +1768,66 @@ export function getPoint(
|
||||||
'pressure' in e ? e.pressure || 0.5 : 0.5,
|
'pressure' in e ? e.pressure || 0.5 : 0.5,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function lzw_encode(s: string) {
|
||||||
|
const dict = {}
|
||||||
|
const data = (s + '').split('')
|
||||||
|
|
||||||
|
let currChar: string
|
||||||
|
let phrase = data[0]
|
||||||
|
let code = 256
|
||||||
|
|
||||||
|
const out = []
|
||||||
|
|
||||||
|
for (var i = 1; i < data.length; i++) {
|
||||||
|
currChar = data[i]
|
||||||
|
|
||||||
|
if (dict[phrase + currChar] != null) {
|
||||||
|
phrase += currChar
|
||||||
|
} else {
|
||||||
|
out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0))
|
||||||
|
dict[phrase + currChar] = code
|
||||||
|
code++
|
||||||
|
phrase = currChar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0))
|
||||||
|
|
||||||
|
for (var i = 0; i < out.length; i++) {
|
||||||
|
out[i] = String.fromCharCode(out[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.join('')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decompress an LZW-encoded string
|
||||||
|
export function lzw_decode(s: string) {
|
||||||
|
const dict = {}
|
||||||
|
const data = (s + '').split('')
|
||||||
|
|
||||||
|
let currChar = data[0]
|
||||||
|
let oldPhrase = currChar
|
||||||
|
let code = 256
|
||||||
|
let phrase: string
|
||||||
|
|
||||||
|
const out = [currChar]
|
||||||
|
|
||||||
|
for (var i = 1; i < data.length; i++) {
|
||||||
|
let currCode = data[i].charCodeAt(0)
|
||||||
|
|
||||||
|
if (currCode < 256) {
|
||||||
|
phrase = data[i]
|
||||||
|
} else {
|
||||||
|
phrase = dict[currCode] ? dict[currCode] : oldPhrase + currChar
|
||||||
|
}
|
||||||
|
|
||||||
|
out.push(phrase)
|
||||||
|
currChar = phrase.charAt(0)
|
||||||
|
dict[code] = oldPhrase + currChar
|
||||||
|
code++
|
||||||
|
oldPhrase = phrase
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.join('')
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue