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 state, { useSelector } from 'state'
|
||||
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 Shape from './shape'
|
||||
|
||||
|
@ -20,36 +20,39 @@ export default function Page() {
|
|||
const page = getPage(s.data)
|
||||
const pageState = s.data.pageStates[page.id]
|
||||
|
||||
// if (!viewportCache.has(pageState)) {
|
||||
// const [minX, minY] = screenToWorld([0, 0], s.data)
|
||||
// const [maxX, maxY] = screenToWorld(
|
||||
// [window.innerWidth, window.innerHeight],
|
||||
// s.data
|
||||
// )
|
||||
// viewportCache.set(pageState, {
|
||||
// minX,
|
||||
// minY,
|
||||
// maxX,
|
||||
// maxY,
|
||||
// height: maxX - minX,
|
||||
// width: maxY - minY,
|
||||
// })
|
||||
// }
|
||||
if (!viewportCache.has(pageState)) {
|
||||
const [minX, minY] = screenToWorld([0, 0], s.data)
|
||||
const [maxX, maxY] = screenToWorld(
|
||||
[window.innerWidth, window.innerHeight],
|
||||
s.data
|
||||
)
|
||||
viewportCache.set(pageState, {
|
||||
minX,
|
||||
minY,
|
||||
maxX,
|
||||
maxY,
|
||||
height: maxX - minX,
|
||||
width: maxY - minY,
|
||||
})
|
||||
}
|
||||
|
||||
// const viewport = viewportCache.get(pageState)
|
||||
const viewport = viewportCache.get(pageState)
|
||||
|
||||
return (
|
||||
Object.values(page.shapes)
|
||||
.filter((shape) => shape.parentId === page.id)
|
||||
// .filter((shape) => {
|
||||
// const shapeBounds = getShapeUtils(shape).getBounds(shape)
|
||||
// return boundsContain(viewport, shapeBounds)
|
||||
// })
|
||||
.sort((a, b) => a.childIndex - b.childIndex)
|
||||
.map((shape) => shape.id)
|
||||
)
|
||||
return Object.values(page.shapes)
|
||||
.filter((shape) => shape.parentId === page.id)
|
||||
.filter((shape) => {
|
||||
const shapeBounds = getShapeUtils(shape).getBounds(shape)
|
||||
return (
|
||||
boundsContain(viewport, shapeBounds) ||
|
||||
boundsCollide(viewport, shapeBounds)
|
||||
)
|
||||
})
|
||||
.sort((a, b) => a.childIndex - b.childIndex)
|
||||
.map((shape) => shape.id)
|
||||
}, deepCompareArrays)
|
||||
|
||||
console.log(currentPageShapeIds.length)
|
||||
|
||||
const isSelecting = useSelector((s) => s.isIn('selecting'))
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import * as fa from 'browser-fs-access'
|
||||
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 { current } from 'immer'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
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'
|
||||
|
||||
function storageId(fileId: string, label: string, id?: string) {
|
||||
|
@ -69,7 +69,7 @@ class Storage {
|
|||
return false
|
||||
}
|
||||
|
||||
const restoredData: any = JSON.parse(savedData)
|
||||
const restoredData: any = JSON.parse(lzw_decode(savedData))
|
||||
|
||||
for (let pageId in restoredData.document.pages) {
|
||||
const selectedIds = restoredData.pageStates[pageId].selectedIds
|
||||
|
@ -88,7 +88,7 @@ class Storage {
|
|||
)
|
||||
|
||||
if (savedPage !== null) {
|
||||
const restored: Page = JSON.parse(savedPage)
|
||||
const restored: Page = JSON.parse(lzw_decode(savedPage))
|
||||
dataToSave.document.pages[pageId] = restored
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,10 @@ class Storage {
|
|||
const dataToSave = this.getDataToSave(data)
|
||||
|
||||
// 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) {
|
||||
|
@ -134,7 +137,7 @@ class Storage {
|
|||
const page = data.document.pages[pageId]
|
||||
const json = JSON.stringify(page)
|
||||
|
||||
localStorage.setItem(storageId(fileId, 'page', pageId), json)
|
||||
localStorage.setItem(storageId(fileId, 'page', pageId), lzw_encode(json))
|
||||
|
||||
// Save page state
|
||||
|
||||
|
@ -167,7 +170,7 @@ class Storage {
|
|||
const savedPage = localStorage.getItem(storageId(fileId, 'page', pageId))
|
||||
|
||||
if (savedPage !== null) {
|
||||
data.document.pages[pageId] = JSON.parse(savedPage)
|
||||
data.document.pages[pageId] = JSON.parse(lzw_decode(savedPage))
|
||||
} else {
|
||||
data.document.pages[pageId] = {
|
||||
id: pageId,
|
||||
|
@ -186,7 +189,6 @@ class Storage {
|
|||
|
||||
if (savedPageState !== null) {
|
||||
const restored: PageState = JSON.parse(savedPageState)
|
||||
restored.selectedIds = new Set(restored.selectedIds)
|
||||
data.pageStates[pageId] = restored
|
||||
} else {
|
||||
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
|
||||
|
||||
for (let key in data.document.pages) {
|
||||
|
|
|
@ -1768,3 +1768,66 @@ export function getPoint(
|
|||
'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…
Reference in a new issue