Compare commits

...
3 Commits
Author SHA1 Message Date
shadowcz007 ed61ca761a v0.2.4
Clicking on the floating window image can copy it to the clipboard.
2023-12-02 11:55:15 +08:00
shadowcz007 95ca17d816 点击悬浮窗图片可以拷贝到剪切板 2023-12-02 11:54:30 +08:00
shadowcz007 db6c721a8f 单击图片可复制到剪切板 2023-12-02 11:35:27 +08:00
4 changed files with 185 additions and 19 deletions
+6 -5
View File
@@ -640,14 +640,15 @@ class LoadImagesFromPath:
global watcher_folder
# print('###监听:',watcher_folder,watcher,file_path,result)
if watcher=='enable':
if watcher_folder==None:
watcher_folder = FolderWatcher(file_path)
if watcher_folder==None:
watcher_folder = FolderWatcher(file_path)
watcher_folder.set_folder_path(file_path)
if watcher=='enable':
# 在这里可以进行其他操作,监听会在后台持续
watcher_folder.set_folder_path(file_path)
watcher_folder.start()
else:
if watcher_folder!=None:
watcher_folder.stop()
+7 -6
View File
@@ -48,7 +48,7 @@ class FolderWatcher:
config['folder_path']=folder_path
save_to_json(config_json,config)
# self.observer = Observer()
self.observer = None
self.event_handler = self._create_event_handler()
self.status = "Not started"
self.event_type='-'
@@ -97,11 +97,12 @@ class FolderWatcher:
print('Listening')
def stop(self):
self.observer.stop()
self.observer.join()
self.observer=None
self.status = "Stopped"
self.event_type='-'
if self.observer!=None:
self.observer.stop()
self.observer.join()
self.observer=None
self.status = "Stopped"
self.event_type='-'
print('Stopped')
+1 -1
View File
@@ -3,7 +3,7 @@ import { app } from '../../../scripts/app.js'
const repoOwner = 'shadowcz007' // 替换为仓库的所有者
const repoName = 'comfyui-mixlab-nodes' // 替换为仓库的名称
const version='v0.2.3'
const version='v0.2.4'
fetch(`https://api.github.com/repos/${repoOwner}/${repoName}/releases/latest`)
+171 -7
View File
@@ -29,6 +29,36 @@ async function interrupt () {
})
}
async function clipboardWriteImage (win, url) {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
// console.log(url)
const img = await createImage(url)
// console.log(img)
canvas.width = img.naturalWidth
canvas.height = img.naturalHeight
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(img, 0, 0)
// 将canvas转为blob
canvas.toBlob(async blob => {
const data = [
new ClipboardItem({
[blob.type]: blob
})
]
win.navigator.clipboard
.write(data)
.then(() => {
console.log('Image copied to clipboard')
})
.catch(error => {
console.error('Failed to copy image to clipboard:', error)
})
})
}
async function uploadFile (file) {
try {
const body = new FormData()
@@ -801,6 +831,7 @@ app.registerExtension({
widget.preview = $el('video', {
controls: true,
draggable: true,
style: {
width: '100%'
},
@@ -808,6 +839,28 @@ app.registerExtension({
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAAAXNSR0IArs4c6QAAALZJREFUKFOFkLERwjAQBPdbgBkInECGaMLUQDsE0AkRVRAYWqAByxldPPOWHwnw4OBGye1p50UDSoA+W2ABLPN7i+C5dyC6R/uiAUXRQCs0bXoNIu4QPQzAxDKxHoALOrZcqtiyR/T6CXw7+3IGHhkYcy6BOR2izwT8LptG8rbMiCRAUb+CQ6WzQVb0SNOi5Z2/nX35DRyb/ENazhpWKoGwrpD6nICp5c2qogc4of+c7QcrhgF4Aa/aoAFHiL+RAAAAAElFTkSuQmCC'
})
// })
// const dropTarget = document.getElementById('your-drop-target-id')
// dropTarget.addEventListener('dragover', event => {
// event.preventDefault()
// })
// dropTarget.addEventListener('drop', event => {
// event.preventDefault()
// const imageUrl = event.dataTransfer.getData('text/plain')
// navigator.clipboard
// .writeText(imageUrl)
// .then(() => {
// console.log('Image URL copied to clipboard')
// })
// .catch(error => {
// console.error('Failed to copy image URL to clipboard:', error)
// })
// })
widget.canvas = $el('canvas', {
style: {
display: 'none'
@@ -818,7 +871,6 @@ app.registerExtension({
innerText: 'PictureInPicture',
style: {
display: 'pictureInPictureEnabled' in document ? 'block' : 'none',
cursor: 'pointer',
padding: '8px 0',
fontWeight: '300',
@@ -831,6 +883,28 @@ app.registerExtension({
widget.card.appendChild(widget.preview)
widget.card.appendChild(widget.canvas)
widget.preview.addEventListener('click', event => {
const imageUrl = window._mixlab_screen_result || ''
// console.log(imageUrl)
try {
if (imageUrl) clipboardWriteImage(pipWindow, imageUrl)
} catch (error) {
console.log(error)
if (imageUrl) clipboardWriteImage(window, imageUrl)
}
// pipWindow.navigator.permissions
// .query({ name: 'clipboard-write' })
// .then(result => {
// if (result.state === 'granted' || result.state === 'prompt') {
// // 执行复制操作
// } else {
// console.error('Clipboard write permission denied')
// }
// })
})
// widget.card.appendChild(widget.PictureInPicture)
widget.PictureInPicture.addEventListener('click', async () => {
@@ -874,7 +948,17 @@ app.registerExtension({
width: calc(100% - 24px);
margin: 12px;`
// console.log(pipWindow.document)
let inputDiv = document.createElement('div')
// inputDiv.style = ``
let infoDiv = document.createElement('div')
infoDiv.style = ` width: 100%;
height: 16px;
color: white;
margin-bottom: 4px;
font-size: 12px;
text-shadow: 1px 1px gray;`
infoDiv.id = 'info'
// Move the player to the Picture-in-Picture window.
let input = document.createElement('textarea')
input.style = `
@@ -928,8 +1012,14 @@ app.registerExtension({
} else {
input.style.display = 'none'
}
try {
pipWindow.document.querySelector('#info').innerText = ''
} catch (error) {
console.log(error)
}
})
// TODO 需要判断是否有screenshare节点,没有的话,不需要添加
let pauseBtn = document.createElement('butotn')
pauseBtn.innerText = '⏸'
pauseBtn.style = `cursor: pointer;height: 24px;margin:4px;
@@ -950,6 +1040,13 @@ app.registerExtension({
if (w) {
w.liveBtn.innerText = 'Live Run'
}
try {
pipWindow.document.querySelector('#info').innerText =
'Stop Live'
} catch (error) {
console.log(error)
}
} else {
pauseBtn.innerText = '⏸'
let node = this.graph._nodes.filter(
@@ -961,6 +1058,12 @@ app.registerExtension({
window._mixlab_stopLive = await startLive(w.liveBtn)
console.log('window._mixlab_stopLive', window._mixlab_stopLive)
}
try {
pipWindow.document.querySelector('#info').innerText = 'Live'
} catch (error) {
console.log(error)
}
}
})
@@ -972,19 +1075,69 @@ app.registerExtension({
window._mixlab_screen_prompt =
window._mixlab_screen_prompt_input || window._mixlab_screen_prompt
document.querySelector('#queue-button').click()
try {
pipWindow.document.querySelector('#info').innerText =
'Update Prompt'
} catch (error) {
console.log(error)
}
})
widget.preview.addEventListener('click', event => {
const imageUrl = window._mixlab_screen_result || ''
// console.log(imageUrl)
try {
if (imageUrl) clipboardWriteImage(pipWindow, imageUrl)
} catch (error) {
console.log(error)
if (imageUrl) clipboardWriteImage(window, imageUrl)
}
try {
pipWindow.document.querySelector('#info').innerText =
'Image copied to clipboard'
setTimeout(
() =>
(pipWindow.document.querySelector('#info').innerText = ''),
8000
)
} catch (error) {
console.log(error)
}
// pipWindow.navigator.permissions
// .query({ name: 'clipboard-write' })
// .then(result => {
// if (result.state === 'granted' || result.state === 'prompt') {
// // 执行复制操作
// } else {
// console.error('Clipboard write permission denied')
// }
// })
})
pipWindow.document.body.append(widget.preview)
pipWindow.document.body.append(div)
// console.log(pipWindow)
div.appendChild(btnDiv)
btnDiv.appendChild(btn)
btnDiv.appendChild(pauseBtn)
btnDiv.appendChild(promptFinishBtn)
div.appendChild(input)
// 输入框
div.appendChild(inputDiv)
inputDiv.appendChild(infoDiv)
inputDiv.appendChild(input)
input.addEventListener('input', () => {
window._mixlab_screen_prompt_input = input.value
try {
pipWindow.document.querySelector('#info').innerText = ''
} catch (error) {
console.log(error)
}
})
input.addEventListener('keydown', handleKeyDown)
@@ -1000,6 +1153,13 @@ app.registerExtension({
window._mixlab_screen_prompt_input ||
window._mixlab_screen_prompt
document.querySelector('#queue-button').click()
try {
pipWindow.document.querySelector('#info').innerText =
'Update Prompt'
} catch (error) {
console.log(error)
}
}
}
}
@@ -1035,7 +1195,11 @@ app.registerExtension({
const videoTrack = stream.getVideoTracks()[0]
video.preview.srcObject = new MediaStream([videoTrack])
video.preview.play()
try {
video.preview.play()
} catch (error) {
console.log(error)
}
// 检查浏览器是否支持画中画模式
if ('pictureInPictureEnabled' in document) {
@@ -1068,7 +1232,7 @@ app.registerExtension({
const context = canvas.getContext('2d')
if (message?.images_) {
const base64 = message.images_[0]
window._mixlab_screen_result = `data:image/png;base64,${message.images_[0]}`
const image = new Image()
image.onload = function () {
canvas.width = image.width
@@ -1076,7 +1240,7 @@ app.registerExtension({
context.drawImage(image, 0, 0)
}
// console.log(`data:image/jpeg;base64,${base64}`)
image.src = `data:image/jpeg;base64,${base64}`
image.src = window._mixlab_screen_result
}
const onRemoved = this.onRemoved
this.onRemoved = () => {
@@ -1457,7 +1621,7 @@ const node = {
)[0]
if (my_workflow?.data) {
// app.loadGraphData(my_workflow.data)
localStorage.setItem('workflow',JSON.stringify(my_workflow.data));
localStorage.setItem('workflow', JSON.stringify(my_workflow.data))
}
})
}