I am trying to implement Lokesh Dhakar's "Color Thief" library.
The expected outcome is to display dominant color and color palette immediately after upload.
My assumption is that there is going something wrong in the following part of the code:
window.addEventListener('load', function() {
document.querySelector('input[type="file"]').addEventListener('change', function() {
if (this.files && this.files[0]) {
var img = document.getElementById('image_0');
img.src = URL.createObjectURL(this.files[0]); // set src to file url
extractColors(img.id);
}
});
});
When I end up at dcolor = colorThief.getColor(document.getElementById(image));
, the "Uncaught TypeError" occurs.
See my effort below:
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Based on "Color Thief" by Lokesh Dhakar</title>
<meta name="description" content="Get the dominant color or color palette from an image.">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Karla%7CMontserrat:700">
<style>
element.style {
}
.image-section {
margin-bottom: 80px;
}
div {
display: block;
}
.image-wrap {
position: relative;
line-height: 1em;
min-height: 240px;
background-color: var(--hover-bg-color);
border-radius: var(--border-radius-xl);
}
.run-functions-button {
position: absolute;
top: 50%;
left: 10%;
width: 8rem;
height: 8rem;
margin-top: -4rem;
margin-left: -4rem;
border: none;
border-radius: 50%;
color: var(--link-color);
background-color: white;
border: 4px solid var(--link-color);
font-size: 2rem;
font-weight: var(--bold);
cursor: pointer;
text-transform: uppercase;
outline: none;
}
.no-touch-label {
display: inline;
}
.touch-label {
display: none;
}
.target-image {
border-radius: var(--border-radius-xl);
transition: border-radius 0.2s 0.3s;
}
.target-image {
display: block;
width: 20%;
border-radius: var(--border-radius-xl) var(--border-radius-xl) 0 0;
}
.dswatch {
width: 3rem;
height: 3rem;
}
.swatchp {
width: 3rem;
height: 3rem;
}
.dswatch {
display: inline-block;
background: #d3d3d3;
border-color: #000;
border-radius: 32px;
border-radius-large: 8px;
border-radius-xl: 12px;
}
.swatchp {
display: inline-block;
background: #d3d3d3;
border-color: #000;
border-radius: 32px;
border-radius-large: 8px;
border-radius-xl: 12px;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/color-thief/2.3.0/color-thief.umd.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/color-thief/2.3.0/color-thief.min.js"></script>
<script>
var dcolor;
var colorp;
window.addEventListener('load', function() {
document.querySelector('input[type="file"]').addEventListener('change', function() {
if (this.files && this.files[0]) {
var img = document.getElementById('image_0');
img.src = URL.createObjectURL(this.files[0]); // set src to file url
extractColors(img.id);
}
});
});
function extractColors(image){
colorThief = new ColorThief();
dcolor = colorThief.getColor(document.getElementById(image)); // error!
document.getElementById('dswatch_0').style.backgroundColor = 'rgb(' + dcolor[0] + ',' + dcolor[1] + ',' + dcolor[2] + ')';
colorp = colorThief.getPalette(document.getElementById(image), 8);
document.getElementById('swatchp_0').style.backgroundColor = 'rgb(' + colorp[0][0] + ',' + colorp[0][1] + ',' + colorp[0][2] + ')';
document.getElementById('swatchp_1').style.backgroundColor = 'rgb(' + colorp[1][0] + ',' + colorp[1][1] + ',' + colorp[1][2] + ')';
document.getElementById('swatchp_2').style.backgroundColor = 'rgb(' + colorp[2][0] + ',' + colorp[2][1] + ',' + colorp[2][2] + ')';
document.getElementById('swatchp_3').style.backgroundColor = 'rgb(' + colorp[3][0] + ',' + colorp[3][1] + ',' + colorp[3][2] + ')';
document.getElementById('swatchp_4').style.backgroundColor = 'rgb(' + colorp[4][0] + ',' + colorp[4][1] + ',' + colorp[4][2] + ')';
document.getElementById('swatchp_5').style.backgroundColor = 'rgb(' + colorp[5][0] + ',' + colorp[5][1] + ',' + colorp[5][2] + ')';
document.getElementById('swatchp_6').style.backgroundColor = 'rgb(' + colorp[6][0] + ',' + colorp[6][1] + ',' + colorp[6][2] + ')';
document.getElementById('swatchp_7').style.backgroundColor = 'rgb(' + colorp[7][0] + ',' + colorp[7][1] + ',' + colorp[7][2] + ')';
}
</script>
<div class="image-section ">
<div class="image-wrap"><input type='file' /><br><img class="target-image" id="image_0" alt="image_0" src="#"></div>
<div class="swatches">
<h6>Dominant color:</h6>
<div class="dswatch" id="dswatch_0"></div>
<h6>Color palette:</h6>
<div class="swatchp" id="swatchp_0"></div>
<div class="swatchp" id="swatchp_1"></div>
<div class="swatchp" id="swatchp_2"></div>
<div class="swatchp" id="swatchp_3"></div>
<div class="swatchp" id="swatchp_4"></div>
<div class="swatchp" id="swatchp_5"></div>
<div class="swatchp" id="swatchp_6"></div>
<div class="swatchp" id="swatchp_7"></div>
</div>
</div>
</body>
</html>
I was able to come up with a solution to my problem. See hereafter for the code snippet that should replace window.addEventListener('load', function() { ... }
:
window.addEventListener('load', function() {
document.querySelector('input[type="file"]').addEventListener('change', function() {
if (document.querySelector('input[type="file"]').files[0]) {
var img = document.getElementById('image_0');
img.id = document.getElementById('image_0').id;
var reader = new FileReader();
reader.readAsDataURL(document.querySelector('input[type="file"]').files[0]);
reader.onload = async function () {
await getResult();
function getResult(){
img.src = reader.result;
}
extractColors(img.id);
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}
});