@@ -1776,47 +1776,24 @@ export class LGraphCanvas
17761776 menu : ContextMenu ,
17771777 node : LGraphNode
17781778 ) : void {
1779- const { graph } = node
1780- if ( ! graph ) throw new NullGraphError ( )
1781- graph . beforeChange ( )
1782-
1783- const newSelected = new Set < LGraphNode > ( )
1784-
1785- const fApplyMultiNode = function (
1786- node : LGraphNode ,
1787- newNodes : Set < LGraphNode >
1788- ) : void {
1789- if ( node . clonable === false ) return
1790-
1791- const newnode = node . clone ( )
1792- if ( ! newnode ) return
1793-
1794- newnode . pos = [ node . pos [ 0 ] + 5 , node . pos [ 1 ] + 5 ]
1795- if ( ! node . graph ) throw new NullGraphError ( )
1796-
1797- node . graph . add ( newnode )
1798- newNodes . add ( newnode )
1799- }
1800-
18011779 const canvas = LGraphCanvas . active_canvas
1802- if (
1803- ! canvas . selected_nodes ||
1804- Object . keys ( canvas . selected_nodes ) . length <= 1
1805- ) {
1806- fApplyMultiNode ( node , newSelected )
1807- } else {
1808- for ( const i in canvas . selected_nodes ) {
1809- fApplyMultiNode ( canvas . selected_nodes [ i ] , newSelected )
1810- }
1811- }
1780+ const nodes = canvas . selectedItems . size ? canvas . selectedItems : [ node ]
18121781
1813- if ( newSelected . size ) {
1814- canvas . selectNodes ( [ ...newSelected ] )
1782+ // Find top-left-most boundary
1783+ let offsetX = Infinity
1784+ let offsetY = Infinity
1785+ for ( const item of nodes ) {
1786+ if ( item . pos == null )
1787+ throw new TypeError (
1788+ 'Invalid node encountered on clone. `pos` was null.'
1789+ )
1790+ if ( item . pos [ 0 ] < offsetX ) offsetX = item . pos [ 0 ]
1791+ if ( item . pos [ 1 ] < offsetY ) offsetY = item . pos [ 1 ]
18151792 }
18161793
1817- graph . afterChange ( )
1818-
1819- canvas . setDirty ( true , true )
1794+ canvas . _deserializeItems ( canvas . _serializeItems ( nodes ) , {
1795+ position : [ offsetX + 5 , offsetY + 5 ]
1796+ } )
18201797 }
18211798
18221799 /**
0 commit comments