Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ComfyUI Workflow</title> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', system-ui, sans-serif; | |
| background-color: #000000; | |
| color: #f5f5f7; | |
| line-height: 1.6; | |
| padding: 20px; | |
| min-height: 100vh; | |
| } | |
| .container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| } | |
| .header { | |
| text-align: center; | |
| margin-bottom: 40px; | |
| padding: 40px 20px; | |
| } | |
| .header h1 { | |
| font-size: 48px; | |
| font-weight: 600; | |
| color: #ffffff; | |
| margin-bottom: 12px; | |
| letter-spacing: -0.02em; | |
| } | |
| .header p { | |
| font-size: 18px; | |
| color: #86868b; | |
| font-weight: 400; | |
| } | |
| .controls { | |
| display: flex; | |
| gap: 12px; | |
| margin-bottom: 24px; | |
| justify-content: center; | |
| } | |
| .btn { | |
| padding: 12px 24px; | |
| border: none; | |
| border-radius: 24px; | |
| font-size: 14px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| font-family: inherit; | |
| } | |
| .btn-primary { | |
| background: #ffffff; | |
| color: #000000; | |
| } | |
| .btn-primary:hover { | |
| background: #f5f5f7; | |
| transform: scale(0.98); | |
| } | |
| .btn-secondary { | |
| background: #1d1d1f; | |
| color: #f5f5f7; | |
| border: 1px solid #424245; | |
| } | |
| .btn-secondary:hover { | |
| background: #2d2d2f; | |
| transform: scale(0.98); | |
| } | |
| .json-container { | |
| background-color: #1d1d1f; | |
| border-radius: 16px; | |
| padding: 32px; | |
| overflow-x: auto; | |
| border: 1px solid #424245; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3); | |
| } | |
| pre { | |
| margin: 0; | |
| font-family: 'SF Mono', 'Monaco', 'Menlo', 'Consolas', monospace; | |
| font-size: 13px; | |
| line-height: 1.6; | |
| white-space: pre-wrap; | |
| word-wrap: break-word; | |
| } | |
| .json-key { | |
| color: #9cdcfe; | |
| } | |
| .json-string { | |
| color: #ce9178; | |
| } | |
| .json-number { | |
| color: #b5cea8; | |
| } | |
| .json-boolean { | |
| color: #569cd6; | |
| } | |
| .json-null { | |
| color: #569cd6; | |
| } | |
| .success { | |
| color: #30d158; | |
| } | |
| @media (max-width: 768px) { | |
| .header h1 { | |
| font-size: 32px; | |
| } | |
| .controls { | |
| flex-direction: column; | |
| } | |
| .json-container { | |
| padding: 20px; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <div class="header"> | |
| <h1>ComfyUI Workflow</h1> | |
| <p>View and download your workflow JSON</p> | |
| </div> | |
| <div class="controls"> | |
| <button class="btn btn-primary" onclick="downloadJSON()">Download JSON</button> | |
| <button class="btn btn-secondary" onclick="copyToClipboard()">Copy to Clipboard</button> | |
| </div> | |
| <div class="json-container"> | |
| <pre id="json-content">{ | |
| "last_id": 0, | |
| "last_link_id": 0, | |
| "nodes": [ | |
| { | |
| "id": 1, | |
| "type": "VideoInput", | |
| "pos": [ | |
| 100, | |
| 300 | |
| ], | |
| "size": { | |
| "0": 315, | |
| "1": 106 | |
| }, | |
| "flags": {}, | |
| "order": 0, | |
| "mode": 0, | |
| "outputs": [ | |
| { | |
| "name": "VIDEO", | |
| "type": "VIDEO", | |
| "links": null, | |
| "slot_index": 0 | |
| } | |
| ], | |
| "properties": { | |
| "Node name for saving": "VideoInput" | |
| }, | |
| "widgets": [ | |
| { | |
| "name": "video", | |
| "config": "", | |
| "value": "", | |
| "options": {}, | |
| "label": "Select Video" | |
| } | |
| ], | |
| "color": "#323224", | |
| "bgcolor": "#434330" | |
| }, | |
| { | |
| "id": 2, | |
| "type": "PrimitiveNode", | |
| "pos": [ | |
| 100, | |
| 450 | |
| ], | |
| "size": { | |
| "0": 200, | |
| "1": 50 | |
| }, | |
| "flags": {}, | |
| "order": 1, | |
| "mode": 0, | |
| "outputs": [ | |
| { | |
| "name": "value", | |
| "type": "FLOAT", | |
| "links": null, | |
| "slot_index": 0 | |
| } | |
| ], | |
| "properties": { | |
| "Node name for saving": "FPS_Input" | |
| }, | |
| "widgets": [ | |
| { | |
| "name": "value", | |
| "config": "30", | |
| "value": "30", | |
| "options": { | |
| "precision": 0, | |
| "step": 1, | |
| "min": 1, | |
| "max": 120 | |
| }, | |
| "label": "FPS" | |
| } | |
| ], | |
| "color": "#223322", | |
| "bgcolor": "#334433" | |
| }, | |
| { | |
| "id": 3, | |
| "type": "VideoFrameSampler", | |
| "pos": [ | |
| 500, | |
| 300 | |
| ], | |
| "size": { | |
| "0": 315, | |
| "1": 150 | |
| }, | |
| "flags": {}, | |
| "order": 2, | |
| "mode": 0, | |
| "inputs": [ | |
| { | |
| "name": "video", | |
| "type": "VIDEO", | |
| "link": 1 | |
| }, | |
| { | |
| "name": "fps", | |
| "type": "FLOAT", | |
| "link": 2 | |
| } | |
| ], | |
| "outputs": [ | |
| { | |
| "name": "frames", | |
| "type": "IMAGE", | |
| "links": null, | |
| "slot_index": 0 | |
| }, | |
| { | |
| "name": "frame_count", | |
| "type": "INT", | |
| "links": null, | |
| "slot_index": 1 | |
| } | |
| ], | |
| "properties": { | |
| "Node name for saving": "VideoFrameSampler" | |
| }, | |
| "widgets": [ | |
| { | |
| "name": "start_frame", | |
| "config": "0", | |
| "value": "0", | |
| "options": {}, | |
| "label": "Start Frame" | |
| }, | |
| { | |
| "name": "max_frames", | |
| "config": "100", | |
| "value": "100", | |
| "options": {}, | |
| "label": "Max Frames" | |
| } | |
| ], | |
| "color": "#222244", | |
| "bgcolor": "#333355" | |
| }, | |
| { | |
| "id": 4, | |
| "type": "PrimitiveNode", | |
| "pos": [ | |
| 500, | |
| 500 | |
| ], | |
| "size": { | |
| "0": 280, | |
| "1": 50 | |
| }, | |
| "flags": {}, | |
| "order": 3, | |
| "mode": 0, | |
| "outputs": [ | |
| { | |
| "name": "value", | |
| "type": "STRING", | |
| "links": null, | |
| "slot_index": 0 | |
| } | |
| ], | |
| "properties": { | |
| "Node name for saving": "Math_Formula_Input" | |
| }, | |
| "widgets": [ | |
| { | |
| "name": "value", | |
| "config": "x * y", | |
| "value": "x * y", | |
| "options": {}, | |
| "label": "Math Formula (JS)" | |
| } | |
| ], | |
| "color": "#442222", | |
| "bgcolor": "#553333" | |
| }, | |
| { | |
| "id": 5, | |
| "type": "CanvasAutoCrop", | |
| "pos": [ | |
| 900, | |
| 300 | |
| ], | |
| "size": { | |
| "0": 315, | |
| "1": 120 | |
| }, | |
| "flags": {}, | |
| "order": 4, | |
| "mode": 0, | |
| "inputs": [ | |
| { | |
| "name": "images", | |
| "type": "IMAGE", | |
| "link": 3 | |
| } | |
| ], | |
| "outputs": [ | |
| { | |
| "name": "cropped_images", | |
| "type": "IMAGE", | |
| "links": null, | |
| "slot_index": 0 | |
| }, | |
| { | |
| "name": "crop_coords", | |
| "type": "INT", | |
| "links": null, | |
| "slot_index": 1 | |
| } | |
| ], | |
| "properties": { | |
| "Node name for saving": "CanvasAutoCrop" | |
| }, | |
| "widgets": [ | |
| { | |
| "name": "canvas_width", | |
| "config": "512", | |
| "value": "512", | |
| "options": { | |
| "precision": 0, | |
| "step": 8 | |
| }, | |
| "label": "Canvas Width" | |
| }, | |
| { | |
| "name": "canvas_height", | |
| "config": "512", | |
| "value": "512", | |
| "options": { | |
| "precision": 0, | |
| "step": 8 | |
| }, | |
| "label": "Canvas Height" | |
| }, | |
| { | |
| "name": "crop_mode", | |
| "config": "center", | |
| "value": "center", | |
| "options": { | |
| "values": [ | |
| "center", | |
| "top", | |
| "bottom", | |
| "left", | |
| "right" | |
| ] | |
| }, | |
| "label": "Crop Mode" | |
| } | |
| ], | |
| "color": "#224422", | |
| "bgcolor": "#335533" | |
| }, | |
| { | |
| "id": 6, | |
| "type": "VideoMatchMixer", | |
| "pos": [ | |
| 1300, | |
| 300 | |
| ], | |
| "size": { | |
| "0": 350, | |
| "1": 200 | |
| }, | |
| "flags": {}, | |
| "order": 5, | |
| "mode": 0, | |
| "inputs": [ | |
| { | |
| "name": "frames", | |
| "type": "IMAGE", | |
| "link": 5 | |
| }, | |
| { | |
| "name": "formula", | |
| "type": "STRING", | |
| "link": 4 | |
| } | |
| ], | |
| "outputs": [ | |
| { | |
| "name": "mixed_frames", | |
| "type": "IMAGE", | |
| "links": null, | |
| "slot_index": 0 | |
| }, | |
| { | |
| "name": "match_data", | |
| "type": "DATA", | |
| "links": null, | |
| "slot_index": 1 | |
| } | |
| ], | |
| "properties": { | |
| "Node name for saving": "VideoMatchMixer" | |
| }, | |
| "widgets": [ | |
| { | |
| "name": "match_strength", | |
| "config": "0.5", | |
| "value": "0.5", | |
| "options": { | |
| "precision": 2, | |
| "step": 0.01, | |
| "min": 0, | |
| "max": 1 | |
| }, | |
| "label": "Match Strength" | |
| }, | |
| { | |
| "name": "mix_mode", | |
| "config": "multiply", | |
| "value": "multiply", | |
| "options": { | |
| "values": [ | |
| "multiply", | |
| "screen", | |
| "overlay", | |
| "soft_light", | |
| "hard_light" | |
| ] | |
| }, | |
| "label": "Mix Mode" | |
| }, | |
| { | |
| "name": "rematch_on_click", | |
| "config": true, | |
| "value": true, | |
| "options": {}, | |
| "label": "Enable Rematch on Click" | |
| } | |
| ], | |
| "color": "#332266", | |
| "bgcolor": "#443377" | |
| }, | |
| { | |
| "id": 7, | |
| "type": "CanvasEffect", | |
| "pos": [ | |
| 1700, | |
| 300 | |
| ], | |
| "size": { | |
| "0": 315, | |
| "1": 180 | |
| }, | |
| "flags": {}, | |
| "order": 6, | |
| "mode": 0, | |
| "inputs": [ | |
| { | |
| "name": "images", | |
| "type": "IMAGE", | |
| "link": 6 | |
| } | |
| ], | |
| "outputs": [ | |
| { | |
| "name": "processed", | |
| "type": "IMAGE", | |
| "links": null, | |
| "slot_index": 0 | |
| } | |
| ], | |
| "properties": { | |
| "Node name for saving": "CanvasEffect" | |
| }, | |
| "widgets": [ | |
| { | |
| "name": "brightness", | |
| "config": "0", | |
| "value": "0", | |
| "options": { | |
| "precision": 1, | |
| "step": 0.1, | |
| "min": -1, | |
| "max": 1 | |
| }, | |
| "label": "Brightness" | |
| }, | |
| { | |
| "name": "contrast", | |
| "config": "1", | |
| "value": "1", | |
| "options": { | |
| "precision": 2, | |
| "step": 0.1, | |
| "min": 0, | |
| "max": 3 | |
| }, | |
| "label": "Contrast" | |
| }, | |
| { | |
| "name": "saturation", | |
| "config": "1", | |
| "value": "1", | |
| "options": { | |
| "precision": 2, | |
| "step": 0.1, | |
| "min": 0, | |
| "max": 3 | |
| }, | |
| "label": "Saturation" | |
| }, | |
| { | |
| "name": "hue_shift", | |
| "config": "0", | |
| "value": "0", | |
| "options": { | |
| "precision": 0, | |
| "step": 1, | |
| "min": 0, | |
| "max": 360 | |
| }, | |
| "label": "Hue Shift" | |
| } | |
| ], | |
| "color": "#224466", | |
| "bgcolor": "#335577" | |
| }, | |
| { | |
| "id": 8, | |
| "type": "SaveVideo", | |
| "pos": [ | |
| 2100, | |
| 300 | |
| ], | |
| "size": { | |
| "0": 315, | |
| "1": 140 | |
| }, | |
| "flags": {}, | |
| "order": 7, | |
| "mode": 0, | |
| "inputs": [ | |
| { | |
| "name": "images", | |
| "type": "IMAGE", | |
| "link": 7 | |
| }, | |
| { | |
| "name": "fps", | |
| "type": "FLOAT", | |
| "link": 2 | |
| } | |
| ], | |
| "outputs": [ | |
| { | |
| "name": "output_path", | |
| "type": "STRING", | |
| "links": null, | |
| "slot_index": 0 | |
| } | |
| ], | |
| "properties": { | |
| "Node name for saving": "SaveVideo" | |
| }, | |
| "widgets": [ | |
| { | |
| "name": "output_path", | |
| "config": "./output/video_output.mp4", | |
| "value": "./output/video_output.mp4", | |
| "options": {}, | |
| "label": "Output Path" | |
| }, | |
| { | |
| "name": "codec", | |
| "config": "libx264", | |
| "value": "libx264", | |
| "options": { | |
| "values": [ | |
| "libx264", | |
| "libx265", | |
| "vp9" | |
| ] | |
| }, | |
| "label": "Codec" | |
| }, | |
| { | |
| "name": "quality", | |
| "config": "23", | |
| "value": "23", | |
| "options": { | |
| "precision": 0, | |
| "step": 1, | |
| "min": 0, | |
| "max": 51 | |
| }, | |
| "label": "CRF Quality" | |
| } | |
| ], | |
| "color": "#224422", | |
| "bgcolor": "#335533" | |
| }, | |
| { | |
| "id": 9, | |
| "type": "PreviewVideo", | |
| "pos": [ | |
| 2100, | |
| 500 | |
| ], | |
| "size": { | |
| "0": 315, | |
| "1": 80 | |
| }, | |
| "flags": {}, | |
| "order": 8, | |
| "mode": 0, | |
| "inputs": [ | |
| { | |
| "name": "images", | |
| "type": "IMAGE", | |
| "link": 7 | |
| } | |
| ], | |
| "outputs": [], | |
| "properties": { | |
| "Node name for saving": "PreviewVideo" | |
| }, | |
| "widgets": [], | |
| "color": "#333333", | |
| "bgcolor": "#444444" | |
| }, | |
| { | |
| "id": 10, | |
| "type": "JavaScriptExecute", | |
| "pos": [ | |
| 100, | |
| 100 | |
| ], | |
| "size": { | |
| "0": 400, | |
| "1": 150 | |
| }, | |
| "flags": {}, | |
| "order": 9, | |
| "mode": 0, | |
| "outputs": [ | |
| { | |
| "name": "trigger", | |
| "type": "EVENT", | |
| "links": null, | |
| "slot_index": 0 | |
| } | |
| ], | |
| "properties": { | |
| "Node name for saving": "JavaScript_Controller" | |
| }, | |
| "widgets": [ | |
| { | |
| "name": "video_button", | |
| "config": "Upload Video", | |
| "value": "Upload Video", | |
| "options": { | |
| "type": "button" | |
| }, | |
| "label": "Video Input Button" | |
| }, | |
| { | |
| "name": "fps_input", | |
| "config": "30", | |
| "value": "30", | |
| "options": { | |
| "type": "number", | |
| "min": 1, | |
| "max": 120 | |
| }, | |
| "label": "FPS Input" | |
| }, | |
| { | |
| "name": "formula_input", | |
| "config": "Math.sin(x) * Math.cos(y)", | |
| "value": "Math.sin(x) * Math.cos(y)", | |
| "options": { | |
| "type": "text" | |
| }, | |
| "label": "JS Math Formula" | |
| }, | |
| { | |
| "name": "rematch_button", | |
| "config": "Rematch", | |
| "value": "Rematch", | |
| "options": { | |
| "type": "button" | |
| }, | |
| "label": "Rematch Button" | |
| } | |
| ], | |
| "color": "#442266", | |
| "bgcolor": "#553377" | |
| }, | |
| { | |
| "id": 11, | |
| "type": "CanvasDisplay", | |
| "pos": [ | |
| 1700, | |
| 550 | |
| ], | |
| "size": { | |
| "0": 350, | |
| "1": 200 | |
| }, | |
| "flags": {}, | |
| "order": 10, | |
| "mode": 0, | |
| "inputs": [ | |
| { | |
| "name": "images", | |
| "type": "IMAGE", | |
| "link": 7 | |
| } | |
| ], | |
| "outputs": [ | |
| { | |
| "name": "canvas_data", | |
| "type": "DATA", | |
| "links": null, | |
| "slot_index": 0 | |
| } | |
| ], | |
| "properties": { | |
| "Node name for saving": "CanvasDisplay" | |
| }, | |
| "widgets": [ | |
| { | |
| "name": "auto_play", | |
| "config": true, | |
| "value": true, | |
| "options": {}, | |
| "label": "Auto Play" | |
| }, | |
| { | |
| "name": "loop", | |
| "config": true, | |
| "value": true, | |
| "options": {}, | |
| "label": "Loop" | |
| } | |
| ], | |
| "color": "#224444", | |
| "bgcolor": "#335555" | |
| }, | |
| { | |
| "id": 12, | |
| "type": "EventHandler", | |
| "pos": [ | |
| 100, | |
| 50 | |
| ], | |
| "size": { | |
| "0": 300, | |
| "1": 40 | |
| }, | |
| "flags": {}, | |
| "order": 11, | |
| "mode": 0, | |
| "outputs": [ | |
| { | |
| "name": "events", | |
| "type": "EVENT", | |
| "links": null, | |
| "slot_index": 0 | |
| } | |
| ], | |
| "properties": { | |
| "Node name for saving": "EventHandler" | |
| }, | |
| "widgets": [ | |
| { | |
| "name": "click_handler", | |
| "config": "true", | |
| "value": "true", | |
| "options": {}, | |
| "label": "Click Handler" | |
| } | |
| ], | |
| "color": "#333333", | |
| "bgcolor": "#444444" | |
| } | |
| ], | |
| "links": [ | |
| [ | |
| 1, | |
| "VIDEO", | |
| 3, | |
| "video" | |
| ], | |
| [ | |
| 2, | |
| "value", | |
| 3, | |
| "fps" | |
| ], | |
| [ | |
| 2, | |
| "value", | |
| 8, | |
| "fps" | |
| ], | |
| [ | |
| 3, | |
| "frames", | |
| 5, | |
| "images" | |
| ], | |
| [ | |
| 4, | |
| "value", | |
| 6, | |
| "formula" | |
| ], | |
| [ | |
| 5, | |
| "cropped_images", | |
| 6, | |
| "frames" | |
| ], | |
| [ | |
| 6, | |
| "mixed_frames", | |
| 7, | |
| "images" | |
| ], | |
| [ | |
| 7, | |
| "processed", | |
| 8, | |
| "images" | |
| ], | |
| [ | |
| 7, | |
| "processed", | |
| 9, | |
| "images" | |
| ], | |
| [ | |
| 7, | |
| "processed", | |
| 11, | |
| "images" | |
| ] | |
| ], | |
| "groups": [ | |
| { | |
| "title": "Input Section", | |
| "bounding": [ | |
| 0, | |
| 0, | |
| 550, | |
| 250 | |
| ], | |
| "color": "#444444", | |
| "font_size": 14 | |
| }, | |
| { | |
| "title": "Processing Section", | |
| "bounding": [ | |
| 500, | |
| 200, | |
| 600, | |
| 400 | |
| ], | |
| "color": "#444466", | |
| "font_size": 14 | |
| }, | |
| { | |
| "title": "Output Section", | |
| "bounding": [ | |
| 1600, | |
| 200, | |
| 650, | |
| 400 | |
| ], | |
| "color": "#444444", | |
| "font_size": 14 | |
| } | |
| ], | |
| "config": {}, | |
| "extra": { | |
| "title": "JavaScript Video Input with Canvas Effects & Match Mix", | |
| "description": "Video processing workflow with JS input buttons, canvas effects, auto-crop, match mix, rematch on click, FPS input, and JS math formula support", | |
| "author": "ComfyUI Workflow", | |
| "version": "1.0.0", | |
| "created_with": "ComfyUI", | |
| "comments": "Built with anycoder - https://huggingface.co/spaces/akhaliq/anycoder" | |
| }, | |
| "version": 0.4 | |
| }</pre> | |
| </div> | |
| </div> | |
| <script> | |
| function copyToClipboard() { | |
| const jsonContent = document.getElementById('json-content').textContent; | |
| navigator.clipboard.writeText(jsonContent).then(() => { | |
| const btn = event.target; | |
| const originalText = btn.textContent; | |
| btn.textContent = 'Copied!'; | |
| btn.classList.add('success'); | |
| setTimeout(() => { | |
| btn.textContent = originalText; | |
| btn.classList.remove('success'); | |
| }, 2000); | |
| }).catch(err => { | |
| alert('Failed to copy to clipboard'); | |
| }); | |
| } | |
| function downloadJSON() { | |
| const jsonContent = document.getElementById('json-content').textContent; | |
| const blob = new Blob([jsonContent], { type: 'application/json' }); | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| a.download = 'comfyui_workflow.json'; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| URL.revokeObjectURL(url); | |
| const btn = event.target; | |
| const originalText = btn.textContent; | |
| btn.textContent = 'Downloaded!'; | |
| btn.classList.add('success'); | |
| setTimeout(() => { | |
| btn.textContent = originalText; | |
| btn.classList.remove('success'); | |
| }, 2000); | |
| } | |
| // Add syntax highlighting | |
| function highlightJSON() { | |
| const content = document.getElementById('json-content'); | |
| let html = content.innerHTML; | |
| // Highlight different JSON elements | |
| html = html.replace(/"([^"]+)":/g, '<span class="json-key">"$1":</span>'); | |
| html = html.replace(/: "([^"]*)"/g, ': <span class="json-string">"$1"</span>'); | |
| html = html.replace(/: (-?\d+\.?\d*)/g, ': <span class="json-number">$1</span>'); | |
| html = html.replace(/: (true|false)/g, ': <span class="json-boolean">$1</span>'); | |
| html = html.replace(/: null/g, ': <span class="json-null">null</span>'); | |
| content.innerHTML = html; | |
| } | |
| // Apply syntax highlighting after page load | |
| window.addEventListener('load', highlightJSON); | |
| </script> | |
| </body> | |
| </html> |