Skip to content

Commit cd2001b

Browse files
committed
Mousewheel zoom
1 parent e9b58f3 commit cd2001b

File tree

5 files changed

+119
-12
lines changed

5 files changed

+119
-12
lines changed

lib/weltmeister/config.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,17 @@ wm.config = {
3535
'G': 'grid',
3636
'C': 'clone',
3737
'Z': 'undo',
38-
'Y': 'redo'
38+
'Y': 'redo',
39+
'MWHEEL_UP': 'zoomin',
40+
'PLUS': 'zoomin',
41+
'MWHEEL_DOWN': 'zoomout',
42+
'MINUS': 'zoomout'
3943
},
4044

4145
'view': {
42-
'zoom': 2,
46+
'zoom': 1,
47+
'zoomMax': 4,
48+
'zoomMin': 0.125,
4349
'grid': false
4450
},
4551

lib/weltmeister/edit-map.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,10 @@ wm.EditMap = ig.BackgroundMap.extend({
243243
// -------------------------------------------------------------------------
244244
// Drawing
245245

246-
draw: function() {
247-
if( this.visible ) {
246+
draw: function() {
247+
// For performance reasons, repeated background maps are not drawn
248+
// when zoomed out
249+
if( this.visible && !(wm.config.view.zoom < 1 && this.repeat) ) {
248250
this.drawTiled();
249251
}
250252

lib/weltmeister/weltmeister.css

+10
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,16 @@ input.modalDialogPath:focus {
432432
float: right;
433433
}
434434

435+
div#zoomIndicator {
436+
font-weight: bold;
437+
font-size: 300%;
438+
position: absolute;
439+
left: 50px;
440+
top: 30px;
441+
color: #fff;
442+
display: none;
443+
}
444+
435445
input#toggleSidebar {
436446
width: 200px;
437447
height: 47px;

lib/weltmeister/weltmeister.js

+95-8
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ wm.Weltmeister = ig.Class.extend({
3737

3838
tilsetSelectDialog: null,
3939
levelSavePathDialog: null,
40-
rot: 0,
40+
labelsStep: 32,
4141

4242
collisionSolid: 1,
4343

@@ -55,6 +55,7 @@ wm.Weltmeister = ig.Class.extend({
5555

5656
ig.system.context.textBaseline = 'top';
5757
ig.system.context.font = wm.config.labels.font;
58+
this.labelsStep = wm.config.labels.step;
5859

5960

6061

@@ -209,6 +210,50 @@ wm.Weltmeister = ig.Class.extend({
209210
},
210211

211212

213+
drag: function() {
214+
this.screen.x -= ig.input.mouse.x - this.mouseLast.x;
215+
this.screen.y -= ig.input.mouse.y - this.mouseLast.y;
216+
this._rscreen.x = Math.round(this.screen.x * ig.system.scale)/ig.system.scale;
217+
this._rscreen.y = Math.round(this.screen.y * ig.system.scale)/ig.system.scale;
218+
for( var i = 0; i < this.layers.length; i++ ) {
219+
this.layers[i].setScreenPos( this.screen.x, this.screen.y );
220+
}
221+
},
222+
223+
224+
zoom: function( delta ) {
225+
var z = wm.config.view.zoom;
226+
var mx = ig.input.mouse.x * z,
227+
my = ig.input.mouse.y * z;
228+
229+
if( z <= 1 ) {
230+
if( delta < 0 ) {
231+
z /= 2;
232+
}
233+
else {
234+
z *= 2;
235+
}
236+
}
237+
else {
238+
z += delta;
239+
}
240+
241+
wm.config.view.zoom = z.limit( wm.config.view.zoomMin, wm.config.view.zoomMax );
242+
wm.config.labels.step = Math.round( this.labelsStep / wm.config.view.zoom );
243+
$('#zoomIndicator').text( wm.config.view.zoom + 'x' ).stop(true,true).show().delay(300).fadeOut();
244+
245+
// Adjust mouse pos and screen coordinates
246+
ig.input.mouse.x = mx / wm.config.view.zoom;
247+
ig.input.mouse.y = my / wm.config.view.zoom;
248+
this.drag();
249+
250+
for( var i in ig.Image.cache ) {
251+
ig.Image.cache[i].resize( wm.config.view.zoom );
252+
}
253+
254+
this.resize();
255+
},
256+
212257

213258
// -------------------------------------------------------------------------
214259
// Loading
@@ -531,6 +576,7 @@ wm.Weltmeister = ig.Class.extend({
531576
this.collisionLayer = null;
532577
}
533578

579+
534580
this.activeLayer.setName( newName );
535581
this.setModified();
536582
this.draw();
@@ -586,13 +632,7 @@ wm.Weltmeister = ig.Class.extend({
586632

587633
// scroll map
588634
if( ig.input.state('drag') ) {
589-
this.screen.x -= ig.input.mouse.x - this.mouseLast.x;
590-
this.screen.y -= ig.input.mouse.y - this.mouseLast.y;
591-
this._rscreen.x = Math.round(this.screen.x * ig.system.scale)/ig.system.scale;
592-
this._rscreen.y = Math.round(this.screen.y * ig.system.scale)/ig.system.scale;
593-
for( var i = 0; i < this.layers.length; i++ ) {
594-
this.layers[i].setScreenPos( this.screen.x, this.screen.y );
595-
}
635+
this.drag();
596636
}
597637

598638
else if( ig.input.state('draw') ) {
@@ -700,6 +740,13 @@ wm.Weltmeister = ig.Class.extend({
700740
}
701741
}
702742

743+
else if( action == 'zoomin' ) {
744+
this.zoom( 1 );
745+
}
746+
else if( action == 'zoomout' ) {
747+
this.zoom( -1 );
748+
}
749+
703750

704751
if( action == 'draw' ) {
705752
// select tile
@@ -846,6 +893,46 @@ wm.Weltmeister.getMaxHeight = function() {
846893
};
847894

848895

896+
// Custom ig.Image class for use in Weltmeister. To make the zoom function
897+
// work, we need some additional scaling behavior:
898+
// Keep the original image, maintain a cache of scaled versions and use the
899+
// default Canvas scaling (~bicubic) instead of nearest neighbor when
900+
// zooming out.
901+
ig.Image.inject({
902+
scaleCache: {},
903+
resize: function( scale ) {
904+
if( this.scaleCache['x'+scale] ) {
905+
this.data = this.scaleCache['x'+scale];
906+
this.width = this.data.width;
907+
this.width = this.data.height;
908+
return;
909+
}
910+
911+
// Retain the original image when scaling
912+
this.origData = this.data = this.origData || this.data;
913+
914+
this.width = this.data.width;
915+
this.height = this.data.height;
916+
917+
if( scale > 1 ) {
918+
// Nearest neighbor when zooming in
919+
this.parent( scale );
920+
}
921+
else {
922+
// Otherwise blur
923+
var scaled = ig.$new('canvas');
924+
scaled.width = this.width * scale;
925+
scaled.height = this.height * scale;
926+
var scaledCtx = scaled.getContext('2d');
927+
scaledCtx.drawImage( this.data, 0, 0, this.width, this.height, 0, 0, scaled.width, scaled.height );
928+
this.data = scaled;
929+
}
930+
931+
this.scaleCache[scale] = this.data;
932+
}
933+
});
934+
935+
849936

850937
// Create a custom loader, to skip sound files and the run loop creation
851938
wm.Loader = ig.Loader.extend({

weltmeister.html

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ <h3 id="entityClass">EntityClassName</h3>
9191
</div>
9292
</div>
9393

94+
<div id="zoomIndicator">1x</div>
95+
9496
</div>
9597
</body>
9698
</html>

0 commit comments

Comments
 (0)