mirror of
https://github.com/Doodle3D/Doodle3D-Core.git
synced 2025-04-20 09:46:25 +02:00
update fileformat
- don’t include images guides - don’t store sketch data and app version in object
This commit is contained in:
parent
12ba7f624f
commit
da12939253
3
index.js
3
index.js
@ -58,7 +58,8 @@ window.addEventListener('keydown',(event) => {
|
|||||||
// add model to store
|
// add model to store
|
||||||
import modelData from './models/circle_error.d3sketch';
|
import modelData from './models/circle_error.d3sketch';
|
||||||
import JSONToSketchData from './src/shape/JSONToSketchData.js';
|
import JSONToSketchData from './src/shape/JSONToSketchData.js';
|
||||||
JSONToSketchData(JSON.parse(modelData)).then(data => {
|
const { data, appVersion } = JSON.parse(modelData);
|
||||||
|
JSONToSketchData(data, appVersion).then(data => {
|
||||||
store.dispatch(actions.openSketch({ data }));
|
store.dispatch(actions.openSketch({ data }));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -99,8 +99,8 @@ class App extends React.Component {
|
|||||||
case 'D3SKETCH':
|
case 'D3SKETCH':
|
||||||
case 'JSON':
|
case 'JSON':
|
||||||
const url = URL.createObjectURL(file);
|
const url = URL.createObjectURL(file);
|
||||||
const data = await fetch(url).then(result => result.json());
|
const { data, appVersion } = await fetch(url).then(result => result.json());
|
||||||
const sketchData = await JSONToSketchData(data);
|
const sketchData = await JSONToSketchData(data, appVersion);
|
||||||
openSketch({ data: sketchData });
|
openSketch({ data: sketchData });
|
||||||
break;
|
break;
|
||||||
case 'JPG':
|
case 'JPG':
|
||||||
|
@ -37,7 +37,7 @@ class DoodlePreview extends React.Component {
|
|||||||
sketchData: PropTypes.object, // TODO
|
sketchData: PropTypes.object, // TODO
|
||||||
docData: PropTypes.shape({
|
docData: PropTypes.shape({
|
||||||
appVersion: PropTypes.string,
|
appVersion: PropTypes.string,
|
||||||
data: PropTypes.string
|
data: PropTypes.oneOf([PropTypes.string, PropTypes.object])
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ class DoodlePreview extends React.Component {
|
|||||||
async componentWillMount() {
|
async componentWillMount() {
|
||||||
let { docData, sketchData } = this.props;
|
let { docData, sketchData } = this.props;
|
||||||
|
|
||||||
if (docData) sketchData = await JSONToSketchData(this.props.docData);
|
if (docData) sketchData = await JSONToSketchData(docData.data, docData.appVersion);
|
||||||
|
|
||||||
const { canvas } = this.refs;
|
const { canvas } = this.refs;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import * as contextTools from './contextTools.js';
|
import * as contextTools from './contextTools.js';
|
||||||
|
|
||||||
export const VERSION = '0.17.4';
|
export const VERSION = '0.18.0';
|
||||||
export const SHAPE_CACHE_LIMIT = 50;
|
export const SHAPE_CACHE_LIMIT = 50;
|
||||||
export const PIXEL_RATIO = 1.0;
|
export const PIXEL_RATIO = 1.0;
|
||||||
|
|
||||||
|
@ -5,47 +5,71 @@ import { recursivePromiseApply } from '../utils/async.js';
|
|||||||
import { base64ToImage, base64ToVectorArray } from '../utils/binaryUtils.js';
|
import { base64ToImage, base64ToVectorArray } from '../utils/binaryUtils.js';
|
||||||
import { LEGACY_HEIGHT_STEP } from '../constants/d3Constants.js';
|
import { LEGACY_HEIGHT_STEP } from '../constants/d3Constants.js';
|
||||||
|
|
||||||
export default async function JSONToSketchData({ data, appVersion }) {
|
export function recursiveMap(objects, reviver) {
|
||||||
let sketchData = JSON.parse(data, (key, value) => {
|
const newObjects = {};
|
||||||
if (semver.lt(appVersion, '0.1.2')) {
|
|
||||||
if (key === 'imageData') {
|
for (const i in objects) {
|
||||||
|
if (!objects.hasOwnProperty(i)) continue;
|
||||||
|
|
||||||
|
let object = objects[i];
|
||||||
|
if (typeof object === 'object') {
|
||||||
|
object = recursiveMap(object, reviver);
|
||||||
|
}
|
||||||
|
object = reviver(i, object) || object;
|
||||||
|
newObjects[i] = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
function revive(appVersion, key, value) {
|
||||||
|
if (semver.lt(appVersion, '0.1.2')) {
|
||||||
|
if (key === 'imageData') {
|
||||||
|
return base64ToImage(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.metadata && value.metadata.type) {
|
||||||
|
switch (value.metadata.type) {
|
||||||
|
case 'Vector':
|
||||||
|
return new Vector().fromJSON(value);
|
||||||
|
|
||||||
|
case 'Matrix':
|
||||||
|
return new Matrix().fromJSON(value);
|
||||||
|
|
||||||
|
case 'VectorArray':
|
||||||
|
return base64ToVectorArray(value);
|
||||||
|
|
||||||
|
case 'Image':
|
||||||
return base64ToImage(value);
|
return base64ToImage(value);
|
||||||
}
|
|
||||||
|
case 'Matrix4':
|
||||||
|
return new Matrix4().copy(value);
|
||||||
|
|
||||||
|
case 'Color':
|
||||||
|
return new Color(value.data).getHex();
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.metadata && value.metadata.type) {
|
|
||||||
switch (value.metadata.type) {
|
|
||||||
case 'Vector':
|
|
||||||
return new Vector().fromJSON(value);
|
|
||||||
|
|
||||||
case 'Matrix':
|
|
||||||
return new Matrix().fromJSON(value);
|
|
||||||
|
|
||||||
case 'VectorArray':
|
|
||||||
return base64ToVectorArray(value);
|
|
||||||
|
|
||||||
case 'Image':
|
|
||||||
return base64ToImage(value);
|
|
||||||
|
|
||||||
case 'Matrix4':
|
|
||||||
return new Matrix4().copy(value);
|
|
||||||
|
|
||||||
case 'Color':
|
|
||||||
return new Color(value.data).getHex();
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// legacy, convert { r: Float, g: Float, b: Float } to hex
|
|
||||||
if (typeof value.r === 'number' && typeof value.g === 'number' && typeof value.b === 'number') {
|
|
||||||
return new Color(value.r, value.g, value.b).getHex();
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
// legacy, convert { r: Float, g: Float, b: Float } to hex
|
||||||
|
if (typeof value.r === 'number' && typeof value.g === 'number' && typeof value.b === 'number') {
|
||||||
|
return new Color(value.r, value.g, value.b).getHex();
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function JSONToSketchData(data, appVersion) {
|
||||||
|
let sketchData;
|
||||||
|
if (semver.gt(appVersion, '0.17.4')) {
|
||||||
|
sketchData = recursiveMap(data, (key, value) => revive(appVersion, key, value));
|
||||||
|
} else {
|
||||||
|
sketchData = JSON.parse(data.data, (key, value) => revive(appVersion, key, value));
|
||||||
|
}
|
||||||
sketchData = await recursivePromiseApply(sketchData);
|
sketchData = await recursivePromiseApply(sketchData);
|
||||||
|
|
||||||
if (semver.lt(appVersion, '0.4.0')) {
|
if (semver.lt(appVersion, '0.4.0')) {
|
||||||
|
@ -26,7 +26,8 @@ export default async function docToFile(db, doc, { image = false, sketch = false
|
|||||||
throw new Error(`'${doc.name}' doesn't include sketch attachment`);
|
throw new Error(`'${doc.name}' doesn't include sketch attachment`);
|
||||||
}
|
}
|
||||||
const data = await blobToJSON(doc._attachments.sketch.data);
|
const data = await blobToJSON(doc._attachments.sketch.data);
|
||||||
response.data = await JSONToSketchData(data);
|
|
||||||
|
response.data = await JSONToSketchData(data, appVersion);
|
||||||
} else {
|
} else {
|
||||||
const data = { data: doc.data, appVersion };
|
const data = { data: doc.data, appVersion };
|
||||||
response.data = await JSONToSketchData(data);
|
response.data = await JSONToSketchData(data);
|
||||||
|
@ -1,49 +1,55 @@
|
|||||||
import { vectorArrayToBase64, imageToBase64 } from '../utils/binaryUtils.js';
|
import { vectorArrayToBase64, imageToBase64 } from '../utils/binaryUtils.js';
|
||||||
import { VERSION } from '../constants/general.js';
|
|
||||||
|
function createShapeData(shape) {
|
||||||
|
shape = { ...shape };
|
||||||
|
delete shape.UID;
|
||||||
|
delete shape.space;
|
||||||
|
|
||||||
|
switch (shape.type) {
|
||||||
|
case 'POLYGON':
|
||||||
|
case 'BRUSH':
|
||||||
|
case 'FREE_HAND': {
|
||||||
|
shape.points = vectorArrayToBase64(shape.points);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'COMPOUND_PATH': {
|
||||||
|
shape.points = vectorArrayToBase64(shape.points);
|
||||||
|
shape.holes = shape.holes.map(vectorArrayToBase64);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'IMAGE_GUIDE': {
|
||||||
|
shape.imageData = imageToBase64(shape.imageData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function sketchDataToJSON({ objectsById, spaces }) {
|
export default function sketchDataToJSON({ objectsById, spaces }) {
|
||||||
|
const mapToShapes = id => objectsById[id];
|
||||||
|
const filter = (shape) => {
|
||||||
|
if (shape.type === 'IMAGE_GUIDE') return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
spaces: []
|
spaces: []
|
||||||
};
|
};
|
||||||
|
|
||||||
function createShapeData(id) {
|
|
||||||
const shape = { ...objectsById[id] };
|
|
||||||
delete shape.UID;
|
|
||||||
delete shape.space;
|
|
||||||
|
|
||||||
switch (shape.type) {
|
|
||||||
case 'POLYGON':
|
|
||||||
case 'BRUSH':
|
|
||||||
case 'FREE_HAND': {
|
|
||||||
shape.points = vectorArrayToBase64(shape.points);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'COMPOUND_PATH': {
|
|
||||||
shape.points = vectorArrayToBase64(shape.points);
|
|
||||||
shape.holes = shape.holes.map(vectorArrayToBase64);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'IMAGE_GUIDE': {
|
|
||||||
shape.imageData = imageToBase64(shape.imageData);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return shape;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const spaceId in spaces) {
|
for (const spaceId in spaces) {
|
||||||
const space = {
|
const space = {
|
||||||
matrix: {
|
matrix: {
|
||||||
metadata: { type: 'Matrix4', library: 'three.js' },
|
metadata: { type: 'Matrix4', library: 'three.js' },
|
||||||
elements: Array.from(spaces[spaceId].matrix.elements)
|
elements: Array.from(spaces[spaceId].matrix.elements)
|
||||||
},
|
},
|
||||||
objects: spaces[spaceId].objectIds.map(createShapeData)
|
objects: spaces[spaceId].objectIds.map(mapToShapes).filter(filter).map(createShapeData)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (spaceId === 'world') {
|
if (spaceId === 'world') {
|
||||||
@ -53,8 +59,5 @@ export default function sketchDataToJSON({ objectsById, spaces }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return data;
|
||||||
data: JSON.stringify(data),
|
|
||||||
appVersion: VERSION
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user