kopia lustrzana https://github.com/backface/turtlestitch
support for retina displays, integrates #1063 - IN PROGRESS
This has bee designed and written by the amazing Bartosz Leper (@bl-nero). Since I totally suck at Git and find myself incompetent to resolve merge conflicts, I’ve decided to manually copy Bartosz’s changes mostly verbatim over, tweaking them only ever so slightly in ways that don’t alter their functionality, except for introducing a tiny test so current Safari still loads Snap, albeit not in retina mode. THIS IT NOT READY FOR RELEASE YET, IT’S WORK IN PROGRESS. Get it? Thanks!dev
rodzic
483e55a70f
commit
179d93f103
|
@ -149,7 +149,7 @@ isSnapObject, copy*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.blocks = '2016-May-04';
|
||||
modules.blocks = '2016-May-10';
|
||||
|
||||
var SyntaxElementMorph;
|
||||
var BlockMorph;
|
||||
|
@ -2664,7 +2664,7 @@ BlockMorph.prototype.showHelp = function () {
|
|||
}
|
||||
|
||||
pic.onload = function () {
|
||||
help = newCanvas(new Point(pic.width, pic.height));
|
||||
help = newCanvas(new Point(pic.width, pic.height), true); // nonRetina
|
||||
ctx = help.getContext('2d');
|
||||
ctx.drawImage(pic, 0, 0);
|
||||
new DialogBoxMorph().inform(
|
||||
|
|
9
gui.js
9
gui.js
|
@ -70,7 +70,7 @@ isSnapObject*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.gui = '2016-May-09';
|
||||
modules.gui = '2016-May-10';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -2903,7 +2903,7 @@ IDE_Morph.prototype.importMedia = function (mediaType) {
|
|||
};
|
||||
frame.addContents(icon);
|
||||
img.onload = function () {
|
||||
var canvas = newCanvas(new Point(img.width, img.height));
|
||||
var canvas = newCanvas(new Point(img.width, img.height), true);
|
||||
canvas.getContext('2d').drawImage(img, 0, 0);
|
||||
icon.object = new Costume(canvas, item.name);
|
||||
icon.refresh();
|
||||
|
@ -2911,7 +2911,7 @@ IDE_Morph.prototype.importMedia = function (mediaType) {
|
|||
img.src = url;
|
||||
});
|
||||
dialog.popUp(world);
|
||||
dialog.setExtent(new Point(390, 300));
|
||||
dialog.setExtent(new Point(400, 300));
|
||||
dialog.setCenter(world.center());
|
||||
dialog.drawNew();
|
||||
|
||||
|
@ -2931,7 +2931,7 @@ IDE_Morph.prototype.aboutSnap = function () {
|
|||
module, btn1, btn2, btn3, btn4, licenseBtn, translatorsBtn,
|
||||
world = this.world();
|
||||
|
||||
aboutTxt = 'Snap! 4.0.7.2\nBuild Your Own Blocks\n\n'
|
||||
aboutTxt = 'Snap! 4.0.8 - dev -\nBuild Your Own Blocks\n\n'
|
||||
+ 'Copyright \u24B8 2016 Jens M\u00F6nig and '
|
||||
+ 'Brian Harvey\n'
|
||||
+ 'jens@moenig.org, bh@cs.berkeley.edu\n\n'
|
||||
|
@ -2968,6 +2968,7 @@ IDE_Morph.prototype.aboutSnap = function () {
|
|||
+ '\ncountless bugfixes and optimizations'
|
||||
+ '\nKartik Chandra: Paint Editor'
|
||||
+ '\nMichael Ball: Time/Date UI, many bugfixes'
|
||||
+ '\nBartosz Leper: Retina Display Support'
|
||||
+ '\n"Ava" Yuan Yuan: Graphic Effects'
|
||||
+ '\nKyle Hotchkiss: Block search design'
|
||||
+ '\nIan Reynolds: UI Design, Event Bindings, '
|
||||
|
|
|
@ -2928,3 +2928,5 @@ http://snap.berkeley.edu/run#cloud:Username=jens&ProjectName=rotation
|
|||
* Media import dialog with thumbnail, thanks to @ubertao!
|
||||
|
||||
== v4.0.7.2 ====
|
||||
|
||||
* in progress: Retina Display Support, thanks, Bartosz Leper!!
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
/*global modules, contains*/
|
||||
|
||||
modules.locale = '2016-May-09';
|
||||
modules.locale = '2016-May-10';
|
||||
|
||||
// Global stuff
|
||||
|
||||
|
@ -167,11 +167,11 @@ SnapTranslator.dict.it = {
|
|||
'language_name':
|
||||
'Italiano',
|
||||
'language_translator':
|
||||
'Stefano Federici, Alberto Firpo',
|
||||
'Stefano Federici, Alberto Firpo, Massimo Ghisalberti',
|
||||
'translator_e-mail':
|
||||
's_federici@yahoo.com, albertofirpo12@gmail.com',
|
||||
's_federici@yahoo.com, albertofirpo12@gmail.com, zairik@gmail.com',
|
||||
'last_changed':
|
||||
'2015-01-12'
|
||||
'2016-05-10'
|
||||
};
|
||||
|
||||
SnapTranslator.dict.ja = {
|
||||
|
|
249
morphic.js
249
morphic.js
|
@ -1036,7 +1036,8 @@
|
|||
I have originally written morphic.js in Florian Balmer's Notepad2
|
||||
editor for Windows, later switched to Apple's Dashcode and later
|
||||
still to Apple's Xcode. I've also come to depend on both Douglas
|
||||
Crockford's JSLint, Mozilla's Firebug and Google's Chrome to get
|
||||
Crockford's JSLint and later the JSHint project, as well as on
|
||||
Mozilla's Firebug and Google's Chrome to get
|
||||
it right.
|
||||
|
||||
|
||||
|
@ -1048,6 +1049,7 @@
|
|||
Ian Reynolds contributed backspace key handling for Chrome.
|
||||
Davide Della Casa contributed performance optimizations for Firefox.
|
||||
Jason N (@cyderize) contributed native copy & paste for text editing.
|
||||
Bartosz Leper contributed retina display support.
|
||||
|
||||
- Jens Mönig
|
||||
*/
|
||||
|
@ -1056,7 +1058,7 @@
|
|||
|
||||
/*global window, HTMLCanvasElement, FileReader, Audio, FileList*/
|
||||
|
||||
var morphicVersion = '2016-May-04';
|
||||
var morphicVersion = '2016-May-10';
|
||||
var modules = {}; // keep track of additional loaded modules
|
||||
var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug
|
||||
|
||||
|
@ -1102,6 +1104,8 @@ var touchScreenSettings = {
|
|||
|
||||
var MorphicPreferences = standardSettings;
|
||||
|
||||
enableRetinaSupport();
|
||||
|
||||
// Global Functions ////////////////////////////////////////////////////
|
||||
|
||||
function nop() {
|
||||
|
@ -1170,13 +1174,18 @@ function fontHeight(height) {
|
|||
return minHeight * 1.2; // assuming 1/5 font size for ascenders
|
||||
}
|
||||
|
||||
function newCanvas(extentPoint) {
|
||||
function newCanvas(extentPoint, nonRetina) {
|
||||
// answer a new empty instance of Canvas, don't display anywhere
|
||||
// nonRetina - optional Boolean "false"
|
||||
// by default retina support is automatic
|
||||
var canvas, ext;
|
||||
ext = extentPoint || {x: 0, y: 0};
|
||||
canvas = document.createElement('canvas');
|
||||
canvas.width = ext.x;
|
||||
canvas.height = ext.y;
|
||||
if (nonRetina && canvas.isRetinaEnabled) {
|
||||
canvas.isRetinaEnabled = false;
|
||||
}
|
||||
return canvas;
|
||||
}
|
||||
|
||||
|
@ -1281,6 +1290,216 @@ function copy(target) {
|
|||
return c;
|
||||
}
|
||||
|
||||
// Retina Display Support //////////////////////////////////////////////
|
||||
|
||||
function enableRetinaSupport() {
|
||||
/*
|
||||
=== contributed by Bartosz Leper ===
|
||||
|
||||
This installs a series of utilities that allow using Canvas the same way
|
||||
on retina and non-retina displays. If the display is a retina one, the
|
||||
underlying dimensions of the Canvas elements are doubled, but this will
|
||||
be transparent to the code that uses Canvas. All dimensions read or
|
||||
written to the Canvas element will be scaled appropriately.
|
||||
|
||||
NOTE: This implementation is not exhaustive; it only implements what is
|
||||
needed by the Snap! UI.
|
||||
*/
|
||||
|
||||
// Get the window's pixel ratio for canvas elements.
|
||||
// See: http://www.html5rocks.com/en/tutorials/canvas/hidpi/
|
||||
var ctx = document.createElement("canvas").getContext("2d"),
|
||||
backingStorePixelRatio = ctx.webkitBackingStorePixelRatio ||
|
||||
ctx.mozBackingStorePixelRatio ||
|
||||
ctx.msBackingStorePixelRatio ||
|
||||
ctx.oBackingStorePixelRatio ||
|
||||
ctx.backingStorePixelRatio || 1,
|
||||
|
||||
// Unfortunately, it's really hard to make this work well when changing
|
||||
// zoom level, so let's leave it like this right now, and stick to
|
||||
// whatever the ratio was in the beginning.
|
||||
originalDevicePixelRatio = window.devicePixelRatio,
|
||||
|
||||
canvasProto = HTMLCanvasElement.prototype,
|
||||
contextProto = CanvasRenderingContext2D.prototype,
|
||||
|
||||
uber = {
|
||||
drawImage: contextProto.drawImage,
|
||||
getImageData: contextProto.getImageData,
|
||||
|
||||
width: Object.getOwnPropertyDescriptor(
|
||||
canvasProto,
|
||||
'width'
|
||||
),
|
||||
height: Object.getOwnPropertyDescriptor(
|
||||
canvasProto,
|
||||
'height'
|
||||
),
|
||||
shadowOffsetX: Object.getOwnPropertyDescriptor(
|
||||
contextProto,
|
||||
'shadowOffsetX'
|
||||
),
|
||||
shadowOffsetY: Object.getOwnPropertyDescriptor(
|
||||
contextProto,
|
||||
'shadowOffsetY'
|
||||
),
|
||||
shadowBlur: Object.getOwnPropertyDescriptor(
|
||||
contextProto,
|
||||
'shadowBlur'
|
||||
)
|
||||
};
|
||||
|
||||
// check whether properties can be overridden, needed for Safari
|
||||
if (Object.keys(uber).some(function (any) {
|
||||
var prop = uber[any];
|
||||
return prop.hasOwnProperty('configurable') && (!prop.configurable);
|
||||
})) {return; }
|
||||
|
||||
function getPixelRatio(imageSource) {
|
||||
return imageSource.isRetinaEnabled ?
|
||||
(originalDevicePixelRatio || 1) / backingStorePixelRatio : 1;
|
||||
}
|
||||
|
||||
canvasProto._isRetinaEnabled = true;
|
||||
Object.defineProperty(canvasProto, 'isRetinaEnabled', {
|
||||
get: function() {
|
||||
return this._isRetinaEnabled;
|
||||
},
|
||||
set: function(enabled) {
|
||||
var prevPixelRatio = getPixelRatio(this);
|
||||
var prevWidth = this.width;
|
||||
var prevHeight = this.height;
|
||||
|
||||
this._isRetinaEnabled = enabled;
|
||||
if (getPixelRatio(this) != prevPixelRatio) {
|
||||
this.width = prevWidth;
|
||||
this.height = prevHeight;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(canvasProto, 'width', {
|
||||
get: function() {
|
||||
return uber.width.get.call(this) / getPixelRatio(this);
|
||||
},
|
||||
set: function(width) {
|
||||
var pixelRatio = getPixelRatio(this);
|
||||
uber.width.set.call(this, width * pixelRatio);
|
||||
var context = this.getContext('2d');
|
||||
context.restore();
|
||||
context.save();
|
||||
context.scale(pixelRatio, pixelRatio);
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(canvasProto, 'height', {
|
||||
get: function() {
|
||||
return uber.height.get.call(this) / getPixelRatio(this);
|
||||
},
|
||||
set: function(height) {
|
||||
var pixelRatio = getPixelRatio(this);
|
||||
uber.height.set.call(this, height * pixelRatio);
|
||||
var context = this.getContext('2d');
|
||||
context.restore();
|
||||
context.save();
|
||||
context.scale(pixelRatio, pixelRatio);
|
||||
}
|
||||
});
|
||||
|
||||
contextProto.drawImage = function(image) {
|
||||
var pixelRatio = getPixelRatio(image),
|
||||
sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight;
|
||||
|
||||
// Different signatures of drawImage() method have different
|
||||
// parameter assignments.
|
||||
switch (arguments.length) {
|
||||
case 9:
|
||||
sx = arguments[1];
|
||||
sy = arguments[2];
|
||||
sWidth = arguments[3];
|
||||
sHeight = arguments[4];
|
||||
dx = arguments[5];
|
||||
dy = arguments[6];
|
||||
dWidth = arguments[7];
|
||||
dHeight = arguments[8];
|
||||
break;
|
||||
|
||||
case 5:
|
||||
sx = 0;
|
||||
sy = 0;
|
||||
sWidth = image.width;
|
||||
sHeight = image.height;
|
||||
dx = arguments[1];
|
||||
dy = arguments[2];
|
||||
dWidth = arguments[3];
|
||||
dHeight = arguments[4];
|
||||
break;
|
||||
|
||||
case 3:
|
||||
sx = 0;
|
||||
sy = 0;
|
||||
sWidth = image.width;
|
||||
sHeight = image.height;
|
||||
dx = arguments[1];
|
||||
dy = arguments[2];
|
||||
dWidth = image.width;
|
||||
dHeight = image.height;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw Error('Called drawImage() with ' + arguments.length +
|
||||
' arguments');
|
||||
}
|
||||
uber.drawImage.call(
|
||||
this, image,
|
||||
sx * pixelRatio, sy * pixelRatio,
|
||||
sWidth * pixelRatio, sHeight * pixelRatio,
|
||||
dx, dy,
|
||||
dWidth, dHeight);
|
||||
};
|
||||
|
||||
contextProto.getImageData = function(sx, sy, sw, sh) {
|
||||
var pixelRatio = getPixelRatio(this.canvas);
|
||||
return uber.getImageData.call(
|
||||
this,
|
||||
sx * pixelRatio, sy * pixelRatio,
|
||||
sw * pixelRatio, sh * pixelRatio);
|
||||
};
|
||||
|
||||
Object.defineProperty(contextProto, 'shadowOffsetX', {
|
||||
get: function() {
|
||||
return uber.shadowOffsetX.get.call(this) /
|
||||
getPixelRatio(this.canvas);
|
||||
},
|
||||
set: function(offset) {
|
||||
var pixelRatio = getPixelRatio(this.canvas);
|
||||
uber.shadowOffsetX.set.call(this, offset * pixelRatio);
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(contextProto, 'shadowOffsetY', {
|
||||
get: function() {
|
||||
return uber.shadowOffsetY.get.call(this) /
|
||||
getPixelRatio(this.canvas);
|
||||
},
|
||||
set: function(offset) {
|
||||
var pixelRatio = getPixelRatio(this.canvas);
|
||||
uber.shadowOffsetY.set.call(this, offset * pixelRatio);
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(contextProto, 'shadowBlur', {
|
||||
get: function() {
|
||||
return uber.shadowBlur.get.call(this) /
|
||||
getPixelRatio(this.canvas);
|
||||
},
|
||||
set: function(blur) {
|
||||
var pixelRatio = getPixelRatio(this.canvas);
|
||||
uber.shadowBlur.set.call(this, blur * pixelRatio);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Colors //////////////////////////////////////////////////////////////
|
||||
|
||||
// Color instance creation:
|
||||
|
@ -9947,7 +10166,7 @@ HandMorph.prototype.processDrop = function (event) {
|
|||
target = target.parent;
|
||||
}
|
||||
pic.onload = function () {
|
||||
canvas = newCanvas(new Point(pic.width, pic.height));
|
||||
canvas = newCanvas(new Point(pic.width, pic.height), true);
|
||||
canvas.getContext('2d').drawImage(pic, 0, 0);
|
||||
target.droppedImage(canvas, aFile.name);
|
||||
};
|
||||
|
@ -10038,7 +10257,7 @@ HandMorph.prototype.processDrop = function (event) {
|
|||
}
|
||||
img = new Image();
|
||||
img.onload = function () {
|
||||
canvas = newCanvas(new Point(img.width, img.height));
|
||||
canvas = newCanvas(new Point(img.width, img.height), true);
|
||||
canvas.getContext('2d').drawImage(img, 0, 0);
|
||||
target.droppedImage(canvas);
|
||||
};
|
||||
|
@ -10050,7 +10269,7 @@ HandMorph.prototype.processDrop = function (event) {
|
|||
}
|
||||
img = new Image();
|
||||
img.onload = function () {
|
||||
canvas = newCanvas(new Point(img.width, img.height));
|
||||
canvas = newCanvas(new Point(img.width, img.height), true);
|
||||
canvas.getContext('2d').drawImage(img, 0, 0);
|
||||
target.droppedImage(canvas);
|
||||
};
|
||||
|
@ -10190,22 +10409,16 @@ WorldMorph.prototype.doOneCycle = function () {
|
|||
};
|
||||
|
||||
WorldMorph.prototype.fillPage = function () {
|
||||
var pos = getDocumentPositionOf(this.worldCanvas),
|
||||
clientHeight = window.innerHeight,
|
||||
var clientHeight = window.innerHeight,
|
||||
clientWidth = window.innerWidth,
|
||||
myself = this;
|
||||
|
||||
this.worldCanvas.style.position = "absolute";
|
||||
this.worldCanvas.style.left = "0px";
|
||||
this.worldCanvas.style.right = "0px";
|
||||
this.worldCanvas.style.width = "100%";
|
||||
this.worldCanvas.style.height = "100%";
|
||||
|
||||
if (pos.x > 0) {
|
||||
this.worldCanvas.style.position = "absolute";
|
||||
this.worldCanvas.style.left = "0px";
|
||||
pos.x = 0;
|
||||
}
|
||||
if (pos.y > 0) {
|
||||
this.worldCanvas.style.position = "absolute";
|
||||
this.worldCanvas.style.top = "0px";
|
||||
pos.y = 0;
|
||||
}
|
||||
if (document.documentElement.scrollTop) {
|
||||
// scrolled down b/c of viewport scaling
|
||||
clientHeight = document.documentElement.clientHeight;
|
||||
|
|
22
objects.js
22
objects.js
|
@ -82,7 +82,7 @@ SpeechBubbleMorph, RingMorph, isNil, FileReader, TableDialogMorph,
|
|||
BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
|
||||
TableMorph, TableFrameMorph*/
|
||||
|
||||
modules.objects = '2016-May-04';
|
||||
modules.objects = '2016-May-10';
|
||||
|
||||
var SpriteMorph;
|
||||
var StageMorph;
|
||||
|
@ -1498,7 +1498,7 @@ SpriteMorph.prototype.drawNew = function () {
|
|||
|
||||
// create a new, adequately dimensioned canvas
|
||||
// and draw the costume on it
|
||||
this.image = newCanvas(costumeExtent);
|
||||
this.image = newCanvas(costumeExtent, true);
|
||||
this.silentSetExtent(costumeExtent);
|
||||
ctx = this.image.getContext('2d');
|
||||
ctx.scale(this.scale * stageScale, this.scale * stageScale);
|
||||
|
@ -1527,7 +1527,7 @@ SpriteMorph.prototype.drawNew = function () {
|
|||
1000
|
||||
);
|
||||
this.silentSetExtent(new Point(newX, newX));
|
||||
this.image = newCanvas(this.extent());
|
||||
this.image = newCanvas(this.extent(), true);
|
||||
this.setCenter(currentCenter, true); // just me
|
||||
SpriteMorph.uber.drawNew.call(this, facing);
|
||||
this.rotationOffset = this.extent().divideBy(2);
|
||||
|
@ -1576,7 +1576,7 @@ SpriteMorph.prototype.colorFiltered = function (aColor) {
|
|||
dta;
|
||||
|
||||
src = this.image.getContext('2d').getImageData(0, 0, ext.x, ext.y);
|
||||
morph.image = newCanvas(ext);
|
||||
morph.image = newCanvas(ext, true);
|
||||
morph.bounds = this.bounds.copy();
|
||||
ctx = morph.image.getContext('2d');
|
||||
dta = ctx.createImageData(ext.x, ext.y);
|
||||
|
@ -3005,11 +3005,11 @@ SpriteMorph.prototype.goBack = function (layers) {
|
|||
SpriteMorph.prototype.overlappingImage = function (otherSprite) {
|
||||
// overrides method from Morph because Sprites aren't nested Morphs
|
||||
var oRect = this.bounds.intersect(otherSprite.bounds),
|
||||
oImg = newCanvas(oRect.extent()),
|
||||
oImg = newCanvas(oRect.extent(), true),
|
||||
ctx = oImg.getContext('2d');
|
||||
|
||||
if (oRect.width() < 1 || oRect.height() < 1) {
|
||||
return newCanvas(new Point(1, 1));
|
||||
return newCanvas(new Point(1, 1), true);
|
||||
}
|
||||
ctx.drawImage(
|
||||
this.image,
|
||||
|
@ -6522,7 +6522,7 @@ SpriteBubbleMorph.prototype.fixLayout = function () {
|
|||
// Costume instance creation
|
||||
|
||||
function Costume(canvas, name, rotationCenter) {
|
||||
this.contents = canvas || newCanvas();
|
||||
this.contents = canvas || newCanvas(null, true);
|
||||
this.shrinkToFit(this.maxExtent());
|
||||
this.name = name || null;
|
||||
this.rotationCenter = rotationCenter || this.center();
|
||||
|
@ -6566,7 +6566,7 @@ Costume.prototype.shrinkWrap = function () {
|
|||
// adjust my contents' bounds to my visible bounding box
|
||||
var bb = this.boundingBox(),
|
||||
ext = bb.extent(),
|
||||
pic = newCanvas(ext),
|
||||
pic = newCanvas(ext, true),
|
||||
ctx = pic.getContext('2d');
|
||||
|
||||
ctx.drawImage(
|
||||
|
@ -6652,7 +6652,7 @@ Costume.prototype.boundingBox = function () {
|
|||
// Costume duplication
|
||||
|
||||
Costume.prototype.copy = function () {
|
||||
var canvas = newCanvas(this.extent()),
|
||||
var canvas = newCanvas(this.extent(), true),
|
||||
cpy,
|
||||
ctx;
|
||||
ctx = canvas.getContext('2d');
|
||||
|
@ -6670,7 +6670,7 @@ Costume.prototype.flipped = function () {
|
|||
(mirrored along a vertical axis), used for
|
||||
SpriteMorph's rotation style type 2
|
||||
*/
|
||||
var canvas = newCanvas(this.extent()),
|
||||
var canvas = newCanvas(this.extent(), true),
|
||||
ctx = canvas.getContext('2d'),
|
||||
flipped;
|
||||
|
||||
|
@ -6696,7 +6696,7 @@ Costume.prototype.edit = function (aWorld, anIDE, isnew, oncancel, onsubmit) {
|
|||
editor.openIn(
|
||||
aWorld,
|
||||
isnew ?
|
||||
newCanvas(StageMorph.prototype.dimensions) :
|
||||
newCanvas(StageMorph.prototype.dimensions, true) :
|
||||
this.contents,
|
||||
isnew ?
|
||||
null :
|
||||
|
|
31
paint.js
31
paint.js
|
@ -62,6 +62,7 @@
|
|||
Dec 15 - center rotation point on costume creating (Craxic)
|
||||
Jan 18 - avoid pixel collision detection in PaintCanvas (Jens)
|
||||
Mar 22 - fixed automatic rotation center point mechanism (Jens)
|
||||
May 10 - retina display support adjustments (Jens)
|
||||
*/
|
||||
|
||||
/*global Point, Rectangle, DialogBoxMorph, AlignmentMorph, PushButtonMorph,
|
||||
|
@ -72,7 +73,7 @@ StageMorph, isNil*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.paint = '2016-May-02';
|
||||
modules.paint = '2016-May-10';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -572,9 +573,9 @@ PaintCanvasMorph.prototype.init = function (shift) {
|
|||
this.dragRect = new Rectangle();
|
||||
// rectangle with origin being the starting drag position and
|
||||
// corner being the current drag position
|
||||
this.mask = newCanvas(this.extent()); // Temporary canvas
|
||||
this.paper = newCanvas(this.extent()); // Actual canvas
|
||||
this.erasermask = newCanvas(this.extent()); // eraser memory
|
||||
this.mask = newCanvas(this.extent(), true); // Temporary canvas
|
||||
this.paper = newCanvas(this.extent(), true); // Actual canvas
|
||||
this.erasermask = newCanvas(this.extent(), true); // eraser memory
|
||||
this.background = newCanvas(this.extent()); // checkers
|
||||
this.settings = {
|
||||
"primarycolor": new Color(0, 0, 0, 255), // usually fill color
|
||||
|
@ -617,8 +618,8 @@ PaintCanvasMorph.prototype.updateAutomaticCenter = function () {
|
|||
|
||||
PaintCanvasMorph.prototype.scale = function (x, y) {
|
||||
this.updateAutomaticCenter();
|
||||
this.mask = newCanvas(this.extent());
|
||||
var c = newCanvas(this.extent());
|
||||
this.mask = newCanvas(this.extent(), true);
|
||||
var c = newCanvas(this.extent(), true);
|
||||
c.getContext("2d").save();
|
||||
c.getContext("2d").translate(
|
||||
this.rotationCenter.x,
|
||||
|
@ -637,14 +638,14 @@ PaintCanvasMorph.prototype.scale = function (x, y) {
|
|||
};
|
||||
|
||||
PaintCanvasMorph.prototype.cacheUndo = function () {
|
||||
var cachecan = newCanvas(this.extent());
|
||||
var cachecan = newCanvas(this.extent(), true);
|
||||
this.merge(this.paper, cachecan);
|
||||
this.undoBuffer.push(cachecan);
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.undo = function () {
|
||||
if (this.undoBuffer.length > 0) {
|
||||
this.paper = newCanvas(this.extent());
|
||||
this.paper = newCanvas(this.extent(), true);
|
||||
this.mask.width = this.mask.width + 1 - 1;
|
||||
this.merge(this.undoBuffer.pop(), this.paper);
|
||||
this.drawNew();
|
||||
|
@ -671,7 +672,7 @@ PaintCanvasMorph.prototype.clearCanvas = function () {
|
|||
};
|
||||
|
||||
PaintCanvasMorph.prototype.toolChanged = function (tool) {
|
||||
this.mask = newCanvas(this.extent());
|
||||
this.mask = newCanvas(this.extent(), true);
|
||||
if (tool === "crosshairs") {
|
||||
this.updateAutomaticCenter();
|
||||
this.drawcrosshair();
|
||||
|
@ -812,7 +813,7 @@ PaintCanvasMorph.prototype.mouseDownLeft = function (pos) {
|
|||
}
|
||||
if (this.settings.primarycolor === "transparent" &&
|
||||
this.currentTool !== "crosshairs") {
|
||||
this.erasermask = newCanvas(this.extent());
|
||||
this.erasermask = newCanvas(this.extent(), true);
|
||||
this.merge(this.paper, this.erasermask);
|
||||
}
|
||||
};
|
||||
|
@ -953,7 +954,7 @@ PaintCanvasMorph.prototype.mouseMove = function (pos) {
|
|||
}
|
||||
mctx.stroke();
|
||||
mctx.restore();
|
||||
this.paper = newCanvas(this.extent());
|
||||
this.paper = newCanvas(this.extent(), true);
|
||||
this.merge(this.mask, this.paper);
|
||||
break;
|
||||
default:
|
||||
|
@ -977,9 +978,9 @@ PaintCanvasMorph.prototype.mouseLeaveDragging
|
|||
|
||||
PaintCanvasMorph.prototype.buildContents = function () {
|
||||
this.background = newCanvas(this.extent());
|
||||
this.paper = newCanvas(this.extent());
|
||||
this.mask = newCanvas(this.extent());
|
||||
this.erasermask = newCanvas(this.extent());
|
||||
this.paper = newCanvas(this.extent(), true);
|
||||
this.mask = newCanvas(this.extent(), true);
|
||||
this.erasermask = newCanvas(this.extent(), true);
|
||||
var i, j, bkctx = this.background.getContext("2d");
|
||||
for (i = 0; i < this.background.width; i += 5) {
|
||||
for (j = 0; j < this.background.height; j += 5) {
|
||||
|
@ -994,7 +995,7 @@ PaintCanvasMorph.prototype.buildContents = function () {
|
|||
};
|
||||
|
||||
PaintCanvasMorph.prototype.drawNew = function () {
|
||||
var can = newCanvas(this.extent());
|
||||
var can = newCanvas(this.extent(), true);
|
||||
this.merge(this.background, can);
|
||||
this.merge(this.paper, can);
|
||||
this.merge(this.mask, can);
|
||||
|
|
5
store.js
5
store.js
|
@ -60,7 +60,7 @@ SyntaxElementMorph, Variable, isSnapObject, console*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.store = '2016-May-02';
|
||||
modules.store = '2016-May-10';
|
||||
|
||||
|
||||
// XML_Serializer ///////////////////////////////////////////////////////
|
||||
|
@ -1321,7 +1321,8 @@ SnapSerializer.prototype.loadValue = function (model) {
|
|||
v = new Costume(null, name, center);
|
||||
image.onload = function () {
|
||||
var canvas = newCanvas(
|
||||
new Point(image.width, image.height)
|
||||
new Point(image.width, image.height),
|
||||
true // nonRetina
|
||||
),
|
||||
context = canvas.getContext('2d');
|
||||
context.drawImage(image, 0, 0);
|
||||
|
|
Ładowanie…
Reference in New Issue