diff --git a/code/_globalvars/lists/wiremod.dm b/code/_globalvars/lists/wiremod.dm index bada761dcd2..59c575dfa31 100644 --- a/code/_globalvars/lists/wiremod.dm +++ b/code/_globalvars/lists/wiremod.dm @@ -1,4 +1,4 @@ -GLOBAL_LIST_INIT(wiremod_types, list( +GLOBAL_LIST_INIT(wiremod_basic_types, list( PORT_TYPE_ANY, PORT_TYPE_STRING, PORT_TYPE_NUMBER, diff --git a/code/game/machinery/computer/launchpad_control.dm b/code/game/machinery/computer/launchpad_control.dm index fd212c7388e..b987204b19b 100644 --- a/code/game/machinery/computer/launchpad_control.dm +++ b/code/game/machinery/computer/launchpad_control.dm @@ -92,11 +92,11 @@ the_pad.set_offset(x_pos.value, y_pos.value) if(COMPONENT_TRIGGERED_BY(port, x_pos)) - x_pos.set_input(the_pad.x_offset, FALSE) + x_pos.set_value(the_pad.x_offset) return if(COMPONENT_TRIGGERED_BY(port, y_pos)) - y_pos.set_input(the_pad.y_offset, FALSE) + y_pos.set_value(the_pad.y_offset) return var/checks = attached_console.teleport_checks(the_pad) diff --git a/code/modules/research/designs/wiremod_designs.dm b/code/modules/research/designs/wiremod_designs.dm index 170f6ce2ac9..595110cd3d1 100644 --- a/code/modules/research/designs/wiremod_designs.dm +++ b/code/modules/research/designs/wiremod_designs.dm @@ -88,11 +88,6 @@ id = "comp_not" build_path = /obj/item/circuit_component/not -/datum/design/component/ram - name = "RAM Component" - id = "comp_ram" - build_path = /obj/item/circuit_component/ram - /datum/design/component/random name = "Random Component" id = "comp_random" diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index d9064803dbd..3b3b2e941a6 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -221,7 +221,6 @@ "comp_not", "comp_pressuresensor", "comp_radio", - "comp_ram", "comp_random", "comp_router", "comp_select_query", diff --git a/code/modules/wiremod/components/abstract/module.dm b/code/modules/wiremod/components/abstract/module.dm index 518ab11b53b..a3c04b2a11e 100644 --- a/code/modules/wiremod/components/abstract/module.dm +++ b/code/modules/wiremod/components/abstract/module.dm @@ -211,7 +211,7 @@ /obj/item/circuit_component/module/ui_static_data(mob/user) . = list() - .["global_port_types"] = GLOB.wiremod_types + .["global_port_types"] = GLOB.wiremod_basic_types /obj/item/circuit_component/module/attackby(obj/item/I, mob/living/user, params) if(istype(I, /obj/item/circuit_component)) @@ -280,7 +280,7 @@ if(action == "set_port_type") var/type = params["port_type"] - if(!(type in GLOB.wiremod_types)) + if(!(type in GLOB.wiremod_basic_types)) return component_port.set_datatype(type) internal_component_port.set_datatype(type) diff --git a/code/modules/wiremod/components/action/light.dm b/code/modules/wiremod/components/action/light.dm index bc598b8905b..14427eae0ec 100644 --- a/code/modules/wiremod/components/action/light.dm +++ b/code/modules/wiremod/components/action/light.dm @@ -45,10 +45,10 @@ /obj/item/circuit_component/light/input_received(datum/port/input/port) . = ..() - brightness.set_input(clamp(brightness.value || 0, 0, max_power)) - red.set_input(clamp(red.value, 0, 255)) - blue.set_input(clamp(blue.value, 0, 255)) - green.set_input(clamp(green.value, 0, 255)) + brightness.set_value(clamp(brightness.value || 0, 0, max_power)) + red.set_value(clamp(red.value, 0, 255)) + blue.set_value(clamp(blue.value, 0, 255)) + green.set_value(clamp(green.value, 0, 255)) var/list/hsl = rgb2hsl(red.value || 0, green.value || 0, blue.value || 0) var/list/light_col = hsl2rgb(hsl[1], hsl[2], max(min_lightness, hsl[3])) shell_light_color = rgb(light_col[1], light_col[2], light_col[3]) diff --git a/code/modules/wiremod/components/action/radio.dm b/code/modules/wiremod/components/action/radio.dm index cd29e5770a2..540b79f7cf5 100644 --- a/code/modules/wiremod/components/action/radio.dm +++ b/code/modules/wiremod/components/action/radio.dm @@ -45,7 +45,7 @@ /obj/item/circuit_component/radio/input_received(datum/port/input/port) . = ..() - freq.set_input(sanitize_frequency(freq.value, TRUE)) + freq.set_value(sanitize_frequency(freq.value, TRUE)) if(.) return var/frequency = freq.value diff --git a/code/modules/wiremod/components/action/soundemitter.dm b/code/modules/wiremod/components/action/soundemitter.dm index e78b6642919..6d18978c539 100644 --- a/code/modules/wiremod/components/action/soundemitter.dm +++ b/code/modules/wiremod/components/action/soundemitter.dm @@ -49,8 +49,8 @@ /obj/item/circuit_component/soundemitter/input_received(datum/port/input/port) . = ..() - volume.set_input(clamp(volume.value, 0, 100)) - frequency.set_input(clamp(frequency.value, -100, 100)) + volume.set_value(clamp(volume.value, 0, 100)) + frequency.set_value(clamp(frequency.value, -100, 100)) if(.) return diff --git a/code/modules/wiremod/components/utility/getter.dm b/code/modules/wiremod/components/utility/getter.dm new file mode 100644 index 00000000000..7bca3083da0 --- /dev/null +++ b/code/modules/wiremod/components/utility/getter.dm @@ -0,0 +1,70 @@ +/** + * # Getter Component + * + * Gets the current value from a variable. + */ +/obj/item/circuit_component/getter + display_name = "Variable Getter" + desc = "A component that gets a variable globally on the circuit." + + /// Variable name + var/datum/port/input/option/variable_name + + /// The value of the variable + var/datum/port/output/value + + var/datum/circuit_variable/current_variable + +/obj/item/circuit_component/getter/populate_options() + variable_name = add_option_port("Variable", null) + +/obj/item/circuit_component/getter/add_to(obj/item/integrated_circuit/added_to) + . = ..() + variable_name.possible_options = added_to.circuit_variables + +/obj/item/circuit_component/getter/removed_from(obj/item/integrated_circuit/removed_from) + variable_name.possible_options = null + return ..() + +/obj/item/circuit_component/getter/Initialize() + . = ..() + value = add_output_port("Value", PORT_TYPE_ANY) + +/obj/item/circuit_component/getter/input_received(datum/port/input/port) + . = ..() + // We don't care much about the parent's return value. We only care if the parent exists + // since this should never really fail. + if(!parent) + return + + var/variable_string = variable_name.value + if(!variable_string) + remove_current_variable() + value.set_output(null) + return + + var/datum/circuit_variable/variable = parent.circuit_variables[variable_string] + if(!variable) + remove_current_variable() + value.set_output(null) + return + + set_current_variable(variable) + value.set_output(variable.value) + +/obj/item/circuit_component/getter/proc/remove_current_variable() + SIGNAL_HANDLER + if(current_variable) + current_variable.remove_listener(src) + UnregisterSignal(current_variable, COMSIG_PARENT_QDELETING) + current_variable = null + +/obj/item/circuit_component/getter/proc/set_current_variable(datum/circuit_variable/variable) + if(variable == current_variable) + return + + remove_current_variable() + current_variable = variable + current_variable.add_listener(src) + RegisterSignal(current_variable, COMSIG_PARENT_QDELETING, .proc/remove_current_variable) + value.set_datatype(variable.datatype) diff --git a/code/modules/wiremod/components/utility/ram.dm b/code/modules/wiremod/components/utility/ram.dm deleted file mode 100644 index 76a6d4d2eae..00000000000 --- a/code/modules/wiremod/components/utility/ram.dm +++ /dev/null @@ -1,72 +0,0 @@ -/** - * # RAM Component - * - * Stores the current input when triggered. - * Players will need to think logically when using the RAM component - * as there can be race conditions due to the delays of transferring signals - */ -/obj/item/circuit_component/ram - display_name = "RAM" - desc = "A component that retains a variable." - circuit_flags = CIRCUIT_FLAG_OUTPUT_SIGNAL - - var/datum/port/input/option/ram_options - - /// The input to store - var/datum/port/input/input_port - /// The trigger to store the current value of the input - var/datum/port/input/trigger - /// Clears the current input - var/datum/port/input/clear - - /// The current set value - var/datum/port/output/output - - var/current_type - -/obj/item/circuit_component/ram/populate_options() - var/static/component_options = list( - PORT_TYPE_ANY, - PORT_TYPE_STRING, - PORT_TYPE_NUMBER, - PORT_TYPE_LIST, - PORT_TYPE_ATOM, - PORT_TYPE_SIGNAL, - ) - ram_options = add_option_port("RAM Options", component_options) - -/obj/item/circuit_component/ram/Initialize() - . = ..() - input_port = add_input_port("Input", PORT_TYPE_ANY) - trigger = add_input_port("Store", PORT_TYPE_SIGNAL) - clear = add_input_port("Clear", PORT_TYPE_SIGNAL) - - output = add_output_port("Stored Value", PORT_TYPE_ANY) - -/obj/item/circuit_component/ram/Destroy() - input_port = null - trigger = null - clear = null - output = null - return ..() - -/obj/item/circuit_component/ram/input_received(datum/port/input/port) - . = ..() - if(current_type != ram_options.value) - current_type = ram_options.value - input_port.set_datatype(current_type) - output.set_datatype(current_type) - - if(.) - return - - if(COMPONENT_TRIGGERED_BY(clear, port)) - output.set_output(null) - return - - if(!COMPONENT_TRIGGERED_BY(trigger, port)) - return TRUE - - var/input_val = input_port.value - - output.set_output(input_val) diff --git a/code/modules/wiremod/components/utility/setter.dm b/code/modules/wiremod/components/utility/setter.dm new file mode 100644 index 00000000000..614e7007981 --- /dev/null +++ b/code/modules/wiremod/components/utility/setter.dm @@ -0,0 +1,58 @@ +/** + * # Setter Component + * + * Stores the current input when triggered into a variable. + */ +/obj/item/circuit_component/setter + display_name = "Variable Setter" + desc = "A component that sets a variable globally on the circuit." + + circuit_flags = CIRCUIT_FLAG_OUTPUT_SIGNAL + + /// Variable name + var/datum/port/input/option/variable_name + + /// The input to store + var/datum/port/input/input_port + /// The trigger to store the current value of the input + var/datum/port/input/trigger + + var/current_type + +/obj/item/circuit_component/setter/populate_options() + variable_name = add_option_port("Variable", null) + +/obj/item/circuit_component/setter/add_to(obj/item/integrated_circuit/added_to) + . = ..() + variable_name.possible_options = added_to.circuit_variables + +/obj/item/circuit_component/setter/removed_from(obj/item/integrated_circuit/removed_from) + variable_name.possible_options = null + return ..() + +/obj/item/circuit_component/setter/Initialize() + . = ..() + input_port = add_input_port("Input", PORT_TYPE_ANY) + trigger = add_input_port("Store", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/setter/input_received(datum/port/input/port) + . = ..() + var/variable_string = variable_name.value + if(!variable_string) + return + + var/datum/circuit_variable/variable = parent.circuit_variables[variable_string] + if(!variable) + return + + if(variable.datatype != current_type) + current_type = variable.datatype + input_port.set_datatype(current_type) + + if(.) + return + + if(!COMPONENT_TRIGGERED_BY(trigger, port)) + return TRUE + + variable.set_value(input_port.value) diff --git a/code/modules/wiremod/datatypes/option.dm b/code/modules/wiremod/datatypes/option.dm index c93f60512fd..c6de346c9df 100644 --- a/code/modules/wiremod/datatypes/option.dm +++ b/code/modules/wiremod/datatypes/option.dm @@ -4,7 +4,7 @@ /datum/port/input/option/New(obj/item/circuit_component/to_connect, name, datatype, trigger, default, possible_options) . = ..() src.possible_options = possible_options - set_input(default, FALSE) + set_value(default, force = TRUE) /datum/circuit_datatype/option datatype = PORT_TYPE_OPTION diff --git a/code/modules/wiremod/duplicator.dm b/code/modules/wiremod/duplicator.dm index b871df862bc..581d6dc1760 100644 --- a/code/modules/wiremod/duplicator.dm +++ b/code/modules/wiremod/duplicator.dm @@ -20,6 +20,11 @@ GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list( if(general_data["display_name"]) set_display_name(general_data["display_name"]) + var/list/variable_data = general_data["variables"] + for(var/list/variable as anything in variable_data) + var/variable_name = variable["name"] + circuit_variables[variable_name] = new /datum/circuit_variable(variable_name, variable["datatype"]) + admin_only = general_data["admin_only"] var/list/circuit_data = general_data["components"] @@ -164,6 +169,15 @@ GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list( general_data["display_name"] = display_name general_data["admin_only"] = admin_only + var/list/variables = list() + for(var/variable_identifier in circuit_variables) + var/list/new_data = list() + var/datum/circuit_variable/variable = circuit_variables[variable_identifier] + new_data["name"] = variable.name + new_data["datatype"] = variable.datatype + variables += list(new_data) + general_data["variables"] = variables + return json_encode(general_data) /obj/item/integrated_circuit/proc/load_component(type) diff --git a/code/modules/wiremod/integrated_circuit.dm b/code/modules/wiremod/integrated_circuit.dm index dd9d22cb283..f69caa75425 100644 --- a/code/modules/wiremod/integrated_circuit.dm +++ b/code/modules/wiremod/integrated_circuit.dm @@ -48,12 +48,27 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) /// Set by the shell. Holds the reference to the owner who inserted the component into the shell. var/datum/weakref/inserter_mind + /// Variables stored on this integrated circuit. with a `variable_name = value` structure + var/list/datum/circuit_variable/circuit_variables = list() + + /// The maximum amount of setters and getters a circuit can have + var/max_setters_and_getters = 30 + + /// The current setter and getter count the circuit has. + var/setter_and_getter_count = 0 + /// X position of the examined_component var/examined_rel_x = 0 /// Y position of the examined component var/examined_rel_y = 0 + /// The X position of the screen. Used for adding components + var/screen_x = 0 + + /// The Y position of the screen. Used for adding components. + var/screen_y = 0 + /obj/item/integrated_circuit/Initialize() . = ..() @@ -69,6 +84,7 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) for(var/obj/item/circuit_component/to_delete in attached_components) remove_component(to_delete) qdel(to_delete) + QDEL_LIST(circuit_variables) attached_components.Cut() shell = null examined_component = null @@ -182,8 +198,8 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) if(!success) return - to_add.rel_x = rand(COMPONENT_MIN_RANDOM_POS, COMPONENT_MAX_RANDOM_POS) - to_add.rel_y = rand(COMPONENT_MIN_RANDOM_POS, COMPONENT_MAX_RANDOM_POS) + to_add.rel_x = rand(COMPONENT_MIN_RANDOM_POS, COMPONENT_MAX_RANDOM_POS) - screen_x + to_add.rel_y = rand(COMPONENT_MIN_RANDOM_POS, COMPONENT_MAX_RANDOM_POS) - screen_y to_add.parent = src attached_components += to_add RegisterSignal(to_add, COMSIG_MOVABLE_MOVED, .proc/component_move_handler) @@ -191,6 +207,7 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) if(shell) to_add.register_shell(shell) + return TRUE /** * Adds a component to the circuitboard through a manual action. @@ -199,7 +216,7 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) if (SEND_SIGNAL(src, COMSIG_CIRCUIT_ADD_COMPONENT_MANUALLY, to_add, user) & COMPONENT_CANCEL_ADD_COMPONENT) return - add_component(to_add, user) + return add_component(to_add, user) /obj/item/integrated_circuit/proc/component_move_handler(obj/item/circuit_component/source) SIGNAL_HANDLER @@ -231,6 +248,12 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) get_asset_datum(/datum/asset/simple/circuit_assets) ) +/obj/item/integrated_circuit/ui_static_data(mob/user) + . = list() + .["global_basic_types"] = GLOB.wiremod_basic_types + .["screen_x"] = screen_x + .["screen_y"] = screen_y + /obj/item/integrated_circuit/ui_data(mob/user) . = list() .["components"] = list() @@ -272,6 +295,16 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) component_data["removable"] = component.removable .["components"] += list(component_data) + .["variables"] = list() + for(var/variable_name in circuit_variables) + var/datum/circuit_variable/variable = circuit_variables[variable_name] + var/list/variable_data = list() + variable_data["name"] = variable.name + variable_data["datatype"] = variable.datatype + variable_data["color"] = variable.color + .["variables"] += list(variable_data) + + .["display_name"] = display_name var/obj/item/circuit_component/examined @@ -479,6 +512,51 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) . = TRUE if("save_circuit") return attempt_save_to(usr.client) + if("add_variable") + var/variable_identifier = trim(copytext(params["variable_name"], 1, PORT_MAX_NAME_LENGTH)) + if(variable_identifier in circuit_variables) + return TRUE + if(variable_identifier == "") + return TRUE + var/variable_datatype = params["variable_datatype"] + if(!(variable_datatype in GLOB.wiremod_basic_types)) + return + + circuit_variables[variable_identifier] = new /datum/circuit_variable(variable_identifier, variable_datatype) + . = TRUE + if("remove_variable") + var/variable_identifier = params["variable_name"] + if(!(variable_identifier in circuit_variables)) + return + var/datum/circuit_variable/variable = circuit_variables[variable_identifier] + if(!variable) + return + circuit_variables -= variable_identifier + qdel(variable) + . = TRUE + if("add_setter_or_getter") + if(setter_and_getter_count >= max_setters_and_getters) + balloon_alert(usr, "setter and getter count at maximum capacity") + return + var/designated_type = /obj/item/circuit_component/getter + if(params["is_setter"]) + designated_type = /obj/item/circuit_component/setter + var/obj/item/circuit_component/component = new designated_type(src) + if(!add_component(component, usr)) + qdel(component) + return + RegisterSignal(component, COMSIG_CIRCUIT_COMPONENT_REMOVED, .proc/clear_setter_or_getter) + setter_and_getter_count++ + if("move_screen") + screen_x = text2num(params["screen_x"]) + screen_y = text2num(params["screen_y"]) + +/obj/item/integrated_circuit/proc/clear_setter_or_getter(datum/source) + SIGNAL_HANDLER + // This'll also be called in the Destroy() override of /obj/item/circuit_component + if(!QDELING(source)) + qdel(source) + setter_and_getter_count-- /obj/item/integrated_circuit/proc/on_atom_usb_cable_try_attach(datum/source, obj/item/usb_cable/usb_cable, mob/user) SIGNAL_HANDLER diff --git a/code/modules/wiremod/port.dm b/code/modules/wiremod/port.dm index b06b927c706..27f4f8cd9ae 100644 --- a/code/modules/wiremod/port.dm +++ b/code/modules/wiremod/port.dm @@ -41,8 +41,8 @@ * Sets the port's value to value. * Casts to the port's datatype (e.g. number -> string), and assumes this can be done. */ -/datum/port/proc/set_value(value) - if(src.value != value) +/datum/port/proc/set_value(value, force = FALSE) + if(src.value != value || force) if(isatom(value)) UnregisterSignal(value, COMSIG_PARENT_QDELETING) src.value = datatype_handler.convert_value(src, value) @@ -156,7 +156,7 @@ /datum/port/input/New(obj/item/circuit_component/to_connect, name, datatype, trigger, default) . = ..() - set_input(default) + set_value(default) src.trigger = trigger src.connected_ports = list() diff --git a/code/modules/wiremod/variable.dm b/code/modules/wiremod/variable.dm new file mode 100644 index 00000000000..62d5239ade2 --- /dev/null +++ b/code/modules/wiremod/variable.dm @@ -0,0 +1,49 @@ +/** + * A circuit variable that holds the name, the datatype and the colour of the variable (taken from the datatype). + * + * Used in integrated circuits for setter and getter circuit components. + */ +/datum/circuit_variable + /// The display name of the circuit variable + var/name + + /// The datatype of the circuit variable. Used by the setter and getter circuit components + var/datatype + + /// The colour that appears in the UI. The value is set to the datatype's matching colour + var/color + + /// The current value held by the variable. + var/value + + /// The components that are currently listening. Triggers them when the value is updated. + var/list/obj/item/circuit_component/listeners + +/datum/circuit_variable/New(name, datatype) + . = ..() + src.name = name + src.datatype = datatype + + var/datum/circuit_datatype/circuit_datatype = GLOB.circuit_datatypes[datatype] + + src.listeners = list() + src.color = circuit_datatype.color + + +/datum/circuit_variable/Destroy(force, ...) + listeners = null + return ..() + +/// Sets the value of the circuit component and triggers the appropriate listeners +/datum/circuit_variable/proc/set_value(new_value) + value = new_value + for(var/obj/item/circuit_component/component as anything in listeners) + TRIGGER_CIRCUIT_COMPONENT(component, null) + +/// Adds a listener to receive inputs when the variable has a value that is set. +/datum/circuit_variable/proc/add_listener(obj/item/circuit_component/to_add) + listeners += to_add + +/// Removes a listener to receive inputs when the variable has a value that is set. Listener will usually clean themselves up +/datum/circuit_variable/proc/remove_listener(obj/item/circuit_component/to_remove) + listeners -= to_remove diff --git a/tgstation.dme b/tgstation.dme index 523b0b89521..1f32950150b 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3704,6 +3704,7 @@ #include "code\modules\wiremod\marker.dm" #include "code\modules\wiremod\port.dm" #include "code\modules\wiremod\usb_cable.dm" +#include "code\modules\wiremod\variable.dm" #include "code\modules\wiremod\components\abstract\compare.dm" #include "code\modules\wiremod\components\abstract\module.dm" #include "code\modules\wiremod\components\action\light.dm" @@ -3751,7 +3752,8 @@ #include "code\modules\wiremod\components\string\tostring.dm" #include "code\modules\wiremod\components\utility\clock.dm" #include "code\modules\wiremod\components\utility\delay.dm" -#include "code\modules\wiremod\components\utility\ram.dm" +#include "code\modules\wiremod\components\utility\getter.dm" +#include "code\modules\wiremod\components\utility\setter.dm" #include "code\modules\wiremod\components\utility\router.dm" #include "code\modules\wiremod\components\utility\typecast.dm" #include "code\modules\wiremod\components\utility\typecheck.dm" diff --git a/tgui/packages/tgui/components/InfinitePlane.js b/tgui/packages/tgui/components/InfinitePlane.js index 7d15a37e382..393ac1de81d 100644 --- a/tgui/packages/tgui/components/InfinitePlane.js +++ b/tgui/packages/tgui/components/InfinitePlane.js @@ -98,7 +98,11 @@ export class InfinitePlane extends Component { } handleMouseMove(event) { - const { onBackgroundMoved } = this.props; + const { + onBackgroundMoved, + initialLeft = 0, + initialTop = 0, + } = this.props; if (this.state.mouseDown) { let newX, newY; this.setState((state) => { @@ -110,7 +114,7 @@ export class InfinitePlane extends Component { }; }); if (onBackgroundMoved) { - onBackgroundMoved(newX, newY); + onBackgroundMoved(newX+initialLeft, newY+initialTop); } } } @@ -120,6 +124,8 @@ export class InfinitePlane extends Component { children, backgroundImage, imageWidth, + initialLeft = 0, + initialTop = 0, ...rest } = this.props; const { @@ -128,6 +134,9 @@ export class InfinitePlane extends Component { zoom, } = this.state; + const finalLeft = initialLeft + left; + const finalTop = initialTop + top; + return (