Fix whirl effect and avoid excessive property lookups

Scale the whirl effect to affect the entire image and flip the whirl
direction like Scratch 1.4 does. Image dimensions are also now stored
in variables to avoid looking them up thousands of times in a row.
dev
djdolphin 2016-06-11 22:21:34 -04:00
rodzic 6cdc861926
commit 3d7ea257f1
1 zmienionych plików z 56 dodań i 40 usunięć

Wyświetl plik

@ -3135,16 +3135,19 @@ SpriteMorph.prototype.applyGraphicsEffects = function (canvas) {
function transform_fisheye (imagedata, value) { function transform_fisheye (imagedata, value) {
var pixels, newImageData, newPixels, centerX, centerY, var pixels, newImageData, newPixels, centerX, centerY,
x, y, dx, dy, r, angle, srcX, srcY, i, srcI; w, h, x, y, dx, dy, r, angle, srcX, srcY, i, srcI;
w = imagedata.width;
h = imagedata.height;
pixels = imagedata.data; pixels = imagedata.data;
newImageData = ctx.createImageData(imagedata.width, imagedata.height); newImageData = ctx.createImageData(w, h);
newPixels = newImageData.data; newPixels = newImageData.data;
centerX = imagedata.width / 2; centerX = w / 2;
centerY = imagedata.height / 2; centerY = h / 2;
value = Math.max(0, (value + 100) / 100); value = Math.max(0, (value + 100) / 100);
for (y = 0; y < imagedata.height; y++) { for (y = 0; y < h; y++) {
for (x = 0; x < imagedata.width; x++) { for (x = 0; x < w; x++) {
dx = (x - centerX) / centerX; dx = (x - centerX) / centerX;
dy = (y - centerY) / centerY; dy = (y - centerY) / centerY;
r = Math.pow(Math.sqrt(dx * dx + dy * dy), value); r = Math.pow(Math.sqrt(dx * dx + dy * dy), value);
@ -3156,8 +3159,8 @@ SpriteMorph.prototype.applyGraphicsEffects = function (canvas) {
srcX = x; srcX = x;
srcY = y; srcY = y;
} }
i = (y * imagedata.width + x) * 4; i = (y * w + x) * 4;
srcI = (srcY * imagedata.width + srcX) * 4; srcI = (srcY * w + srcX) * 4;
newPixels[i] = pixels[srcI]; newPixels[i] = pixels[srcI];
newPixels[i + 1] = pixels[srcI + 1]; newPixels[i + 1] = pixels[srcI + 1];
newPixels[i + 2] = pixels[srcI + 2]; newPixels[i + 2] = pixels[srcI + 2];
@ -3168,36 +3171,46 @@ SpriteMorph.prototype.applyGraphicsEffects = function (canvas) {
} }
function transform_whirl (imagedata, value) { function transform_whirl (imagedata, value) {
var pixels, newImageData, newPixels, centerX, centerY, var pixels, newImageData, newPixels, w, h, centerX, centerY,
x, y, radius, scaleX, scaleY, whirlRadians, radiusSquared, x, y, radius, scaleX, scaleY, whirlRadians, radiusSquared,
dx, dy, d, factor, angle, srcX, srcY, i, srcI; dx, dy, d, factor, angle, srcX, srcY, i, srcI;
w = imagedata.width;
h = imagedata.height;
pixels = imagedata.data; pixels = imagedata.data;
newImageData = ctx.createImageData(imagedata.width, imagedata.height); newImageData = ctx.createImageData(w, h);
newPixels = newImageData.data; newPixels = newImageData.data;
centerX = imagedata.width / 2; centerX = w / 2;
centerY = imagedata.height / 2; centerY = h / 2;
radius = Math.min(centerX, centerY); radius = Math.min(centerX, centerY);
whirlRadians = radians(value); if (w < h) {
scaleX = h / w;
scaleY = 1;
} else {
scaleX = 1;
scaleY = w / h;
}
whirlRadians = -radians(value);
radiusSquared = radius * radius; radiusSquared = radius * radius;
for (y = 0; y < imagedata.height; y++) { for (y = 0; y < h; y++) {
for (x = 0; x < imagedata.width; x++) { for (x = 0; x < w; x++) {
dx = x - centerX; dx = scaleX * (x - centerX);
dy = y - centerY; dy = scaleY * (y - centerY);
d = dx * dx + dy * dy; d = dx * dx + dy * dy;
if (d < radiusSquared) { if (d < radiusSquared) {
factor = 1 - (Math.sqrt(d) / radius); factor = 1 - (Math.sqrt(d) / radius);
angle = whirlRadians * (factor * factor); angle = whirlRadians * (factor * factor);
sina = Math.sin(angle); sina = Math.sin(angle);
cosa = Math.cos(angle); cosa = Math.cos(angle);
srcX = Math.floor((cosa * dx - sina * dy) + centerX); srcX = Math.floor((cosa * dx - sina * dy) / scaleX + centerX);
srcY = Math.floor((sina * dx + cosa * dy) + centerY); srcY = Math.floor((sina * dx + cosa * dy) / scaleY + centerY);
} else { } else {
srcX = x; srcX = x;
srcY = y; srcY = y;
} }
i = (y * imagedata.width + x) * 4; i = (y * w + x) * 4;
srcI = (srcY * imagedata.width + srcX) * 4; srcI = (srcY * w + srcX) * 4;
newPixels[i] = pixels[srcI]; newPixels[i] = pixels[srcI];
newPixels[i + 1] = pixels[srcI + 1]; newPixels[i + 1] = pixels[srcI + 1];
newPixels[i + 2] = pixels[srcI + 2]; newPixels[i + 2] = pixels[srcI + 2];
@ -3208,19 +3221,22 @@ SpriteMorph.prototype.applyGraphicsEffects = function (canvas) {
} }
function transform_pixelate (imagedata, value) { function transform_pixelate (imagedata, value) {
var pixels, newImageData, newPixels, x, y, var pixels, newImageData, newPixels, w, h,
srcX, srcY, i, srcI; x, y, srcX, srcY, i, srcI;
w = imagedata.width;
h = imagedata.height;
pixels = imagedata.data; pixels = imagedata.data;
newImageData = ctx.createImageData(imagedata.width, imagedata.height); newImageData = ctx.createImageData(w, h);
newPixels = newImageData.data; newPixels = newImageData.data;
value = Math.floor(Math.abs(value / 10) + 1); value = Math.floor(Math.abs(value / 10) + 1);
for (y = 0; y < imagedata.height; y++) { for (y = 0; y < h; y++) {
for (x = 0; x < imagedata.width; x++) { for (x = 0; x < w; x++) {
srcX = Math.floor(x / value) * value; srcX = Math.floor(x / value) * value;
srcY = Math.floor(y / value) * value; srcY = Math.floor(y / value) * value;
i = (y * imagedata.width + x) * 4; i = (y * w + x) * 4;
srcI = (srcY * imagedata.width + srcX) * 4; srcI = (srcY * w + srcX) * 4;
newPixels[i] = pixels[srcI]; newPixels[i] = pixels[srcI];
newPixels[i + 1] = pixels[srcI + 1]; newPixels[i + 1] = pixels[srcI + 1];
newPixels[i + 2] = pixels[srcI + 2]; newPixels[i + 2] = pixels[srcI + 2];
@ -3231,15 +3247,15 @@ SpriteMorph.prototype.applyGraphicsEffects = function (canvas) {
} }
function transform_mosaic (imagedata, value) { function transform_mosaic (imagedata, value) {
var i, pixels, newImageData, newPixels, srcI; var pixels, i, l, newImageData, newPixels, srcI;
pixels = imagedata.data; pixels = imagedata.data;
newImageData = ctx.createImageData(imagedata.width, imagedata.height); newImageData = ctx.createImageData(imagedata.width, imagedata.height);
newPixels = newImageData.data; newPixels = newImageData.data;
value = Math.round((Math.abs(value) + 10) / 10); value = Math.round((Math.abs(value) + 10) / 10);
value = Math.max(0, Math.min(value, Math.min(imagedata.width, imagedata.height))); value = Math.max(0, Math.min(value, Math.min(imagedata.width, imagedata.height)));
for (i = 0; i < pixels.length; i += 4) { for (i = 0, l = pixels.length; i < l; i += 4) {
srcI = i * value % pixels.length srcI = i * value % l
newPixels[i] = pixels[srcI]; newPixels[i] = pixels[srcI];
newPixels[i + 1] = pixels[srcI + 1]; newPixels[i + 1] = pixels[srcI + 1];
newPixels[i + 2] = pixels[srcI + 2]; newPixels[i + 2] = pixels[srcI + 2];
@ -3249,7 +3265,7 @@ SpriteMorph.prototype.applyGraphicsEffects = function (canvas) {
} }
function transform_duplicate (imagedata, value) { function transform_duplicate (imagedata, value) {
var pixels, i; var pixels, i, l;
pixels = imagedata.data; pixels = imagedata.data;
for (i = 0; i < pixels.length; i += 4) { for (i = 0; i < pixels.length; i += 4) {
pixels[i] = pixels[i * value]; pixels[i] = pixels[i * value];
@ -3261,10 +3277,10 @@ SpriteMorph.prototype.applyGraphicsEffects = function (canvas) {
} }
function transform_HSV (imagedata, hueShift, saturationShift, brightnessShift) { function transform_HSV (imagedata, hueShift, saturationShift, brightnessShift) {
var pixels, index, r, g, b, max, min, span, var pixels, index, l, r, g, b, max, min, span,
h, s, v, i, f, p, q, t, newR, newG, newB; h, s, v, i, f, p, q, t, newR, newG, newB;
pixels = imagedata.data; pixels = imagedata.data;
for (index = 0; index < pixels.length; index += 4) { for (index = 0, l = pixels.length; index < l; index += 4) {
r = pixels[index]; r = pixels[index];
g = pixels[index + 1]; g = pixels[index + 1];
b = pixels[index + 2]; b = pixels[index + 2];
@ -3333,9 +3349,9 @@ SpriteMorph.prototype.applyGraphicsEffects = function (canvas) {
} }
function transform_negative (imagedata, value) { function transform_negative (imagedata, value) {
var pixels, i, rcom, gcom, bcom; var pixels, i, l, rcom, gcom, bcom;
pixels = imagedata.data; pixels = imagedata.data;
for (i = 0; i < pixels.length; i += 4) { for (i = 0, l = pixels.length; i < l; i += 4) {
rcom = 255 - pixels[i]; rcom = 255 - pixels[i];
gcom = 255 - pixels[i + 1]; gcom = 255 - pixels[i + 1];
bcom = 255 - pixels[i + 2]; bcom = 255 - pixels[i + 2];
@ -3360,9 +3376,9 @@ SpriteMorph.prototype.applyGraphicsEffects = function (canvas) {
} }
function transform_comic (imagedata, value) { function transform_comic (imagedata, value) {
var pixels, i; var pixels, i, l;
pixels = imagedata.data; pixels = imagedata.data;
for (i = 0; i < pixels.length; i += 4) { for (i = 0, l = pixels.length; i < l; i += 4) {
pixels[i] += Math.sin(i * value) * 127 + 128; pixels[i] += Math.sin(i * value) * 127 + 128;
pixels[i + 1] += Math.sin(i * value) * 127 + 128; pixels[i + 1] += Math.sin(i * value) * 127 + 128;
pixels[i + 2] += Math.sin(i * value) * 127 + 128; pixels[i + 2] += Math.sin(i * value) * 127 + 128;
@ -3371,9 +3387,9 @@ SpriteMorph.prototype.applyGraphicsEffects = function (canvas) {
} }
function transform_confetti (imagedata, value) { function transform_confetti (imagedata, value) {
var pixels, i; var pixels, i, l;
pixels = imagedata.data; pixels = imagedata.data;
for (i = 0; i < pixels.length; i += 1) { for (i = 0, l = pixels.length; i < l; i += 1) {
pixels[i] = Math.sin(value * pixels[i]) * 127 + pixels[i]; pixels[i] = Math.sin(value * pixels[i]) * 127 + pixels[i];
} }
return imagedata; return imagedata;