JSFiddle - React, Tailwind, and code Playground

HTML

<canvas id="canvas" style="border: 1px solid #0095DD;"></canvas>

JavaScript

function distance(x1, y1, x2, y2) {
    x = x1 - x2;
    y = y1 - y2;
    return Math.sqrt(x * x + y * y);
}

function eachObject(obj, func) {
    Object.keys(obj).map(func);
}

class Scene {
    constructor(config = {}) {
        //default options
        this.canvasId = 'canvas';
        this.width = 500;
        this.height = 300;

        //default objectsConfig
        this.objectsConfig = {
            'ball1': {
                'class': Ball,
                'config': {
                    'x': 50,
                    'y': 100,
                    'r': 30,
                    'color': 'blue'
                }
            },
            'ball2': {
                'class': Ball,
                'config': {
                    'x': 140,
                    'y': 40,
                    'r': 30,
                    'color': 'green'
                }
            },
            'dependents': {
                listenCollision: {'ball1': 'ball2'},
            },
        };

        Object.assign(this, config);
        let canvas = document.getElementById(this.canvasId);
        canvas.width = this.width;
        canvas.height = this.height;
        this.context = canvas.getContext('2d');
        this.objects = [];
    }

    initObjects() {
        for (let key in this.objectsConfig) {
            if (key !== 'dependents') {
                if (!this.objectsConfig[key].config) {
                    this.objectsConfig[key].config = {}
                }
                Object.assign(this.objectsConfig[key].config, {'_scene': this});
                this.objects[key] = new this.objectsConfig[key].class(this.objectsConfig[key].config);
            }
        }
    }

    initDependents() {
        let dp = this.objectsConfig['dependents'];
        let objects = this.objects;
        eachObject(dp, function (value) {
            eachObject(dp[value], function (val) {
                if (Array.isArray(dp[value][val])) {
                    dp[value][val].forEach(function...