We also need a nice little showcase. For that, I implemented a small application, which simulates a solar system, with a configurable number of planets, moons and stars. The application calculates the gravity which affects the objects and then determines their new positions. This is done repeatedly, leading to a simulated continuous motion. The positions (and trajectories) of all objects are displayed in the canvas element. Picture 1 shows the solar system simulator in action.
![]() |
Picture 1: Solar system simulator written with the canvas component |
After that, the canvas is ready to be used. The component already brings some important methods, e.g. drawCircle( 50, 50, 10, "red" ) which draws a red circle with a radius of 10 pixels around the point 50, 50.
And now, the most interesting part of the source code:
Ext.define('CanvasPanelClass', {
extend: 'Ext.Panel',
gridColor: '',
ctx: null, // is set when rendered
canvas: null, // is set when rendered
bodyStyle: { background: '#000' },
frame: false,
margin: '2 2 2 2',
listeners: {
afterrender: {
fn: function(){
this.canvas = this.items.items[0].el.dom;
this.ctx = this.canvas.getContext("2d"); this.clear();
}
}
},
constructor: function(config) {
//define this here because we can set width and height
this.items = {
xtype: 'box',
autoEl:{
tag: 'canvas',
height: config.height,
width: config.width
}
};
this.tempCanvas = document.createElement("canvas");
CanvasPanelClass.superclass.constructor.call(this, config);
},
drawRect: function( x, y, width, height, lineWidth, color ) {
this.ctx.strokeStyle = color;
this.ctx.lineWidth = lineWidth;
this.ctx.strokeRect(x,y,width,height);
},
fillRect: function( x, y, width, height, color ) {
this.ctx.fillStyle = color;
this.ctx.fillRect(x,y,width,height);
},
drawCircle : function( x, y, radius, color ) {
this.ctx.beginPath();
this.ctx.strokeStyle = color;
this.ctx.fillStyle = color;
this.ctx.arc( x, y, radius, 0, Math.PI*2, true );
this.ctx.closePath();
this.ctx.fill();
},
putPixel: function( x, y, size, color ) {
this.ctx.fillStyle = color;
this.ctx.fillRect(x,y,size,size);
},
clear: function() {
// Store the current transformation matrix
this.ctx.save();
// Use the identity matrix while clearing the canvas
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.clearRect ( 0, 0, this.getWidth(), this.getHeight() );
// Restore the transform
this.ctx.restore();
}
}); // define CanvasPanelClass
extend: 'Ext.Panel',
gridColor: '',
ctx: null, // is set when rendered
canvas: null, // is set when rendered
bodyStyle: { background: '#000' },
frame: false,
margin: '2 2 2 2',
listeners: {
afterrender: {
fn: function(){
this.canvas = this.items.items[0].el.dom;
this.ctx = this.canvas.getContext("2d"); this.clear();
}
}
},
constructor: function(config) {
//define this here because we can set width and height
this.items = {
xtype: 'box',
autoEl:{
tag: 'canvas',
height: config.height,
width: config.width
}
};
this.tempCanvas = document.createElement("canvas");
CanvasPanelClass.superclass.constructor.call(this, config);
},
drawRect: function( x, y, width, height, lineWidth, color ) {
this.ctx.strokeStyle = color;
this.ctx.lineWidth = lineWidth;
this.ctx.strokeRect(x,y,width,height);
},
fillRect: function( x, y, width, height, color ) {
this.ctx.fillStyle = color;
this.ctx.fillRect(x,y,width,height);
},
drawCircle : function( x, y, radius, color ) {
this.ctx.beginPath();
this.ctx.strokeStyle = color;
this.ctx.fillStyle = color;
this.ctx.arc( x, y, radius, 0, Math.PI*2, true );
this.ctx.closePath();
this.ctx.fill();
},
putPixel: function( x, y, size, color ) {
this.ctx.fillStyle = color;
this.ctx.fillRect(x,y,size,size);
},
clear: function() {
// Store the current transformation matrix
this.ctx.save();
// Use the identity matrix while clearing the canvas
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.clearRect ( 0, 0, this.getWidth(), this.getHeight() );
// Restore the transform
this.ctx.restore();
}
}); // define CanvasPanelClass
Then, the canvas component can be used like in the following code snippet. (There is an array of canvasPanels because you might want to create more than one canvas.) The mousedown handler shows how an application can react on mouse clicks into the canvas.
canvasPanel[0]
= new CanvasPanelClass({
height:
500,
width:
500
});
canvasPanel[0].on({
mousedown:
function(DOMevent) {
var
canvasPanelX = this.getPosition()[0];
var
canvasPanelY = this.getPosition()[1]
var
point = DOMevent.getPoint();
var
eventX = point.x-canvasPanelX;
var
eventY = point.y-canvasPanelY;
// do something …
canvasPanel[0].clear();
canvasPanel[0].renderGrid(25*50/ZOOM,GRIDCOLOR);
},
element:
'body',
scope: canvasPanel[i] //Ensure "this" is correct during handler execution
scope: canvasPanel[i] //Ensure "this" is correct during handler execution
});
tablePanel.add(canvasPanel[0]);
canvasPanel[0].clear();
canvasPanel[0].putPixel( 50, 50, 1, "green" );
canvasPanel[0].clear();
canvasPanel[0].putPixel( 50, 50, 1, "green" );
No comments:
Post a Comment