-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript.js
118 lines (97 loc) · 3.25 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
* By Ken Fyrstenberg Nilsen
*
* drawImageProp(context, image [, x, y, width, height [,offsetX, offsetY]])
*
* If image and context are only arguments rectangle will equal canvas
*
* https://stackoverflow.com/questions/21961839/simulation-background-size-cover-in-canvas
*/
function drawImageProp(ctx, img, x, y, w, h, offsetX, offsetY) {
if (arguments.length === 2) {
x = y = 0;
w = ctx.canvas.width;
h = ctx.canvas.height;
}
// default offset is center
offsetX = typeof offsetX === "number" ? offsetX : 0.5;
offsetY = typeof offsetY === "number" ? offsetY : 0.5;
// keep bounds [0.0, 1.0]
if (offsetX < 0) offsetX = 0;
if (offsetY < 0) offsetY = 0;
if (offsetX > 1) offsetX = 1;
if (offsetY > 1) offsetY = 1;
var iw = img.width,
ih = img.height,
r = Math.min(w / iw, h / ih),
nw = iw * r, // new prop. width
nh = ih * r, // new prop. height
cx, cy, cw, ch, ar = 1;
// decide which gap to fill
if (nw < w) ar = w / nw;
if (Math.abs(ar - 1) < 1e-14 && nh < h) ar = h / nh; // updated
nw *= ar;
nh *= ar;
// calc source rectangle
cw = iw / (nw / w);
ch = ih / (nh / h);
cx = (iw - cw) * offsetX;
cy = (ih - ch) * offsetY;
// make sure source rectangle is valid
if (cx < 0) cx = 0;
if (cy < 0) cy = 0;
if (cw > iw) cw = iw;
if (ch > ih) ch = ih;
// fill image in dest. rectangle
ctx.drawImage(img, cx, cy, cw, ch, x, y, w, h);
}
function loadImage(url) {
return new Promise((resolve, reject) => {
const img = document.createElement('img');
img.crossOrigin = 'anonymous';
img.onload = function() {
resolve(this);
}
img.src = url;
});
}
function readFileToDataUrl(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener("load", function () {
resolve(reader.result);
}, false);
reader.readAsDataURL(file);
});
}
function getBlobFromCanvas(canvas) {
return new Promise((resolve, reject) => {
canvas.toBlob((blob) => resolve(blob));
});
}
const gradientPromise = loadImage('https://cdn.glitch.com/fffdd8da-0106-4e08-94ff-81950a79b744%2Fgradient-01.png?v=1583287915356');
$(() => {
$('#image-upload').on('change', async function() {
const file = $(this)[0].files[0];
if (!file) return;
const fileDataURL = await readFileToDataUrl(file);
const uploadImage = await loadImage(fileDataURL);
const gradient = await gradientPromise;
const height = uploadImage.naturalHeight;
const width = uploadImage.naturalWidth;
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
const context = canvas.getContext("2d");
context.globalCompositeOperation = "color";
context.drawImage(uploadImage, 0, 0);
drawImageProp(context, gradient, 0, 0, width, height);
const canvasBlob = await getBlobFromCanvas(canvas);
const objectUrl = URL.createObjectURL(canvasBlob);
$('#main').
css('height', `${height}px`).
css('width', `${width}px`).
css('background', `url(${objectUrl})`);
$('#download-image').attr('href', objectUrl).show();
});
});