JSFiddle - React, Tailwind, and code Playground
by acbabis
HTML
<b>View 1</b><br/>
<canvas id="view1" style="border: solid 1px black" width="500" height="200"></canvas><br/>
<b>View 2</b><br/>
<span id="view2">()</span><br/>
<br/><br/>
<b>Controller</b><br/>
X: <input id="x">, Y: <input id="y"> <button id="button">Move</button>
JavaScript
/*******************
* MODEL
*******************/
function Model() {
this._observers = [];
this._x = 0;
this._y = 0;
this._distance = 0;
}
Model.prototype.move = function(x, y) {
this._x = x;
this._y = y;
this._distance = Math.sqrt(x * x + y * y);
// The state of the model has changed, so
// we notify all observers.
var obs = this._observers;
for(var i = 0, l = obs.length; i < l; i++) {
try {
obs[i]('move');
} catch(e) {
console.error(e);
}
}
};
Model.prototype.addObserver = function(observer) {
this._observers.push(observer);
}
Model.prototype.x = function() {return this._x};
Model.prototype.y = function() {return this._y};
Model.prototype.distance = function() {return this._distance};
var model = new Model();
/*******************
* CONTROLLER
*******************/
document.getElementById('button').addEventListener('click', function() {
model.move(document.getElementById('x').value, document.getElementById('y').value);
});
/*******************
* VIEW
*******************/
// Important Note: There are 2 independent views
// that the model code knows nothing about.
model.addObserver(function(type) {
var canvas = document.getElementById('view1');
var ctx = canvas.getContext('2d');
var width = canvas.width;
var height = canvas.height;
ctx.clearRect(0, 0, width, height);
ctx.beginPath();
ctx.moveTo(width / 2, 0);
ctx.lineTo(width / 2, height);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0, height / 2);
ctx.lineTo(width, height / 2);
ctx.stroke();
ctx.beginPath();
var x = model.x() - 2 + width / 2;
var y = model.y() - 2 + height / 2;
ctx.arc(x, y, 4, 0, 2 * Math.PI);
ctx.fillStyle = '#0000FF';
ctx.fill();
});
model.addObserver(function(type) {
document.getElementById('view2').innerHTML = 'Dot is ' + model.distance().toFixed(1) + ' pixels from the center';
});
model.move(20, 20);