Draw two images over each other

1

Draw two images over each other

2
@Def(body)
<div>
<canvas id="img-a"
class="separate"
></canvas><canvas id="img-b"
class="separate"></canvas>
</div><div>
<img id="ref" src="ref.png">
</div>
@End(body)
3
@Def(css)
img, canvas {
-ms-interpolation-mode: nearest-neighbor;
image-rendering: -webkit-optimize-contrast;
image-rendering: -moz-crisp-edges;
image-rendering: -o-pixelated;
image-rendering: pixelated;
}
#img-a, div {
position: relative;
}
#img-b {
position: absolute;
}
#img-b.overlay {
left: 0px;
transition: left 2s linear;
}
@End(css)
4
@Add(css)
#img-b.separate {
left: 420px;
transition: left 2s linear;
}
@End(css)
5
@Def(js)
const $ = xp => {
return document.getElementById(
xp.substr(1)
);
};
@End(js)
6
@Add(js)
window.addEventListener(
'load', () => {
@Put(main);
}
);
@End(js)
7
@Def(main)
const $ref = $('#ref');
const $img_a = $('#img-a');
const $img_b = $('#img-b');
@End(main)
8
@Add(main)
const refresh = () => {
@Put(refresh)
};
refresh();
@End(main)
9
@Def(refresh)
const w = ref.width + (ref.width % 2);
const h = ref.height;
@End(refresh)
10
@Add(refresh)
const ref_c =
document.createElement('canvas');
ref_c.width = $img_a.width =
$img_b.width = w;
ref_c.height = $img_a.height =
$img_b.height = h;
@End(refresh)
11
@Add(refresh)
const ref_ctx =
ref_c.getContext('2d');
ref_ctx.drawImage($ref, 0, 0, w, h);
@End(refresh)
12
@Add(refresh)
const ref_id =
ref_ctx.getImageData(0, 0, w, h);
const ref_d = ref_id.data;
@End(refresh)
13
@Add(refresh)
const getBlack = ctx => {
const id =
ctx_a.createImageData(1,1);
const d = id.data;
d[0] = d[1] = d[2] = 0;
d[3] = 255;
return id;
};
@End(refresh)
14
@Add(refresh)
const ctx_a = $img_a.getContext('2d');
let black_a = getBlack(ctx_a);
const ctx_b = $img_b.getContext('2d');
let black_b = getBlack(ctx_b);
@End(refresh)
15
@Add(refresh)
const gcd = (a, b) => {
while (b != 0) {
const t = a % b;
a = b; b = t;
}
return a;
};

let x = 0;
let y = 0;
let m = w * h;
let c = m;
let d = Math.trunc(m/7);
while (gcd(d, m) != 1) { ++d; }

const draw = () => {
for (let k = 0; c > 0 && k < 345; ++k) {
let r = (y * w + x) * 4;
@put(draw);
--c;
let i = y * w + x;
i = i + d;
while (i > m) { i -= m; }

y = Math.floor(i / w);
x = i - w * y;
}
if (c > 0) {
setTimeout(draw, 0);
}
};
draw();

@End(refresh)
16
@def(draw)
let v = 0;
for (let i = 0; i < 2; ++i) {
let vv = 0;
for (let j = 0; j < 3; ++j) {
vv += ref_d[r++];
}
v += vv * ref_d[r++] / 255;
}
@end(draw)
17
@add(draw)
const putPixel = (x1, x2, y, v) => {
ctx_a.putImageData(
black_a, x1, y
);
ctx_b.putImageData(
black_b,
(v < 255 + 128) ? x2 : x1,
y
);
};
@end(draw)
18
@add(draw)
if (Math.random() < 0.5) {
putPixel(x, x + 1, y, v);
} else {
putPixel(x + 1, x, y, v);
}
@end(draw)

Move Images

19

Move Images

20
@Add(body)
<form>
<button id="overlay">Overlay</button>
<button
id="separate">Separate</button>
<input id="upload" type="file" />
</form>
@End(body)
21
@Add(main)
$('#overlay').addEventListener(
'click',
evt => {
evt.preventDefault();
$img_a.className = 'overlay';
$img_b.className = 'overlay';
$img_b.style.removeProperty('left');
$img_b.style.removeProperty('top');
}
);
@end(main)
22
@Add(main)
$('#separate').addEventListener(
'click',
evt => {
evt.preventDefault();
$img_a.className = 'separate';
$img_b.className = 'separate';
$img_b.style.removeProperty('left');
$img_b.style.removeProperty('top');
}
);
@end(main)

Move elements

23

Move elements

24
@Add(main) {
@put(mouse move);
} @End(main)
25
@def(mouse move)
let mouse_down = false;
let x = 0;
let y = 0;
@end(mouse move)
26
@add(mouse move)
$img_b.addEventListener('mousedown', function (e) {
mouse_down = true;
x = $img_b.offsetLeft - e.clientX;
y = $img_b.offsetTop - e.clientY;
$img_b.className = '';
$img_b.style.left = e.clientX + x + 'px';
$img_b.style.top = e.clientY + y + 'px';
}, true);
$img_b.addEventListener('mouseup', function (e) {
mouse_down = false;
}, true);
$img_b.addEventListener('mousemove', function (e) {
if (mouse_down) {
$img_b.style.left = e.clientX + x + 'px';
$img_b.style.top = e.clientY + y + 'px';
}
}, true);
@end(mouse move)
27
@Add(main) {
$('#upload').addEventListener('change', function () {
if (this.files && this.files[0]) {
$ref.onload = refresh;
$ref.src = URL.createObjectURL(this.files[0]);
}
});
} @End(main)