Skip to content

Commit

Permalink
Merge pull request #2143 from wonderunit/sg-image-insertion
Browse files Browse the repository at this point in the history
Shot-generator image insertion
  • Loading branch information
audionerd authored Oct 29, 2020
2 parents 207a314 + 77995e6 commit ef7d99e
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/js/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@
"image": {
"tooltip": {
"title": "Add Image",
"description": "Add an image. You can specify a custom image properties on the left. This is useful for reference images or posters or matte paintings in your scene."
"description": "Useful for reference images, posters, or matte paintings in your scene. Once added, use the Inspector (at left) to select an image file and set properties. Images can also be pasted from the clipboard."
},
"title": "Image"
},
Expand Down
4 changes: 2 additions & 2 deletions src/js/shared/actions/scene-object-creators.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ const createVolume = (id, camera, room) => {
})
}

const createImage = (id, camera, room) => {
const createImage = (id, camera, room, imagePath = 'placeholder') => {
let { x, y, z, rotation } = generatePositionAndRotation(camera, room)

return createObject({
Expand All @@ -174,7 +174,7 @@ const createImage = (id, camera, room) => {
visible: true,
opacity: 1,
visibleToCam: true,
imageAttachmentIds: ['placeholder']
imageAttachmentIds: [imagePath]
})
}

Expand Down
36 changes: 30 additions & 6 deletions src/js/shot-generator/components/Toolbar/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { connect } from 'react-redux'
import React, { useMemo, useRef } from 'react'
import React, { useMemo, useRef, useEffect } from 'react'
import {
// action creators
selectObject,
Expand All @@ -17,7 +17,10 @@ import SceneObjectCreators from '../../../shared/actions/scene-object-creators'

import Icon from '../Icon'
import useTooltip from '../../../hooks/use-tooltip'


import { useTranslation } from 'react-i18next'
import { useInsertImage } from '../../hooks/use-insert-image'
// because webpack
const { shell } = require('electron')

Expand Down Expand Up @@ -70,6 +73,7 @@ const Toolbar = connect(

notifications
}) => {

let cameraState = null
let camera = useRef(null)
let { t } = useTranslation()
Expand All @@ -90,6 +94,28 @@ const Toolbar = connect(
[room]
)

const initializeImage = (id, imagePath = "") => {
initCamera()
undoGroupStart()
createImage(id, camera.current, room.visible && roomObject3d, imagePath)
selectObject(id)
undoGroupEnd()
}

const { dragOver, imageDrop, createImageFromClipboard } = useInsertImage(initializeImage)

useEffect(() => {
window.addEventListener('paste', createImageFromClipboard, false)
window.addEventListener('drop', imageDrop, false)
window.addEventListener('dragover', dragOver, false);
return () => {
window.removeEventListener('dragover', dragOver);
window.removeEventListener('drop', imageDrop)
window.removeEventListener('paste', createImageFromClipboard)
}
}, [])


const initCamera = () => {
withState((dispatch, state) => {
cameraState = getSceneObjects(state)[getActiveCamera(state)]
Expand Down Expand Up @@ -155,13 +181,11 @@ const Toolbar = connect(

const onCreateImageClick = () => {
let id = THREE.Math.generateUUID()
initCamera()
undoGroupStart()
createImage(id, camera.current, room.visible && roomObject3d)
selectObject(id)
undoGroupEnd()
initializeImage(id)
}



const onSaveToBoardClick = () => {
ipcRenderer.send('shot-generator:requestSaveShot')
}
Expand Down
59 changes: 59 additions & 0 deletions src/js/shot-generator/hooks/use-insert-image.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import fs from 'fs-extra'
import path from 'path'
import { useContext } from 'react'
import FilepathsContext from '../contexts/filepaths'
const useInsertImage = (initializeImage) => {
const { getAssetPath } = useContext(FilepathsContext)
const dragOver = (e) => {
e.preventDefault();
e.stopPropagation();
}

const imageDrop = (e) => {
for (const f of e.dataTransfer.files) {
let { name, ext } = path.parse( f.path)
let imageId = THREE.Math.generateUUID()
let imageProjectPath = path.join('models', 'images', name + ext)
let imagePath = getAssetPath('image', imageProjectPath)
fs.ensureDirSync(path.dirname(imagePath))
if(!fs.existsSync(imagePath))
fs.copyFileSync(f.path, imagePath)
initializeImage(imageId, imageProjectPath)
}
}

const createImageFromClipboard = (pasteEvent) => {
if(pasteEvent.clipboardData == false) {
return
}
let items = pasteEvent.clipboardData.items
if(items == undefined) {
return
}
for(let i = 0; i < items.length; i++) {
let item = items[i]
if(item.type.indexOf("image") == -1) continue
let blob = item.getAsFile()

let imageId = THREE.Math.generateUUID()
let imageProjectPath = path.join('models', 'images', `${imageId}-texture.png`)
let imagePath = getAssetPath('image', imageProjectPath)
let reader = new FileReader()
reader.onload = function() {
if(reader.readyState == 2) {
let buffer = Buffer.from(reader.result)
fs.ensureDirSync(path.dirname(imagePath))
fs.writeFileSync(imagePath, buffer)
initializeImage(imageId, imageProjectPath)
}
}
reader.readAsArrayBuffer(blob)
}

}

return { dragOver, imageDrop, createImageFromClipboard }

}

export { useInsertImage }
6 changes: 4 additions & 2 deletions src/js/shot-generator/services/filepaths.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ function getSystemDirectoryFor (pathToShotGeneratorData) {
'character': path.join(pathToShotGeneratorData, 'dummies', 'gltf'),
'attachable': path.join(pathToShotGeneratorData, 'attachables'),
'emotion': path.join(pathToShotGeneratorData, 'emotions'),
'xr': path.join(pathToShotGeneratorData, 'xr')
'xr': path.join(pathToShotGeneratorData, 'xr'),
'image': path.join(pathToShotGeneratorData, 'images')
}[type]
}
}
Expand All @@ -19,7 +20,8 @@ function getProjectDirectory (base) {
'character': path.join(base, 'models', 'characters'),
'environment': path.join(base, 'models', 'environments'),
'attachable': path.join(base, 'models', 'attachables'),
'emotion': path.join(base, 'models', 'emotions')
'emotion': path.join(base, 'models', 'emotions'),
'image': path.join(base, 'models', 'images')
}[type]
}
}
Expand Down
12 changes: 12 additions & 0 deletions test/shot-generator/services/filepaths.renderer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,17 @@ describe('filepaths', function () {
path.normalize('PROJECT_DIR/models/attachables')
)
})
it('can get system image file path', () => {
assert.strictEqual(
getAssetPath('image', `placeholder.png`),
'APP_DIR/data/shot-generator/images/placeholder.png'
)
})
it('can get user image file path', () => {
assert.strictEqual(
getAssetPath('image', `models/images/texture.png`),
'PROJECT_DIR/models/images/texture.png'
)
})
})
})

0 comments on commit ef7d99e

Please sign in to comment.