0

I make some CODE to change images in CANVAS on selecting item from dropDown list. It working as it should in IE but in Chrome and FireFox when I chose item from dropDown list nothing happened until I click on dropDown list again. Here is link to sample: Here is CODE:

<html>
<head>
<style>
    body{ margin:40px; background:#666; }
    #my_canvas{ background:#FFF; border:#000 1px solid; }
</style>
<script>
    var text = "";
    var i;
    var slika01 = new Image();
    var slika02 = new Image();
    var slika03 = new Image();
    slika01.src = "images/sloj01_01.png";
    slika02.src = "images/sloj02_01.png";
    slika03.src = "images/sloj03_01.png";

function clear(){
    var ctx = document.getElementById('my_canvas').getContext('2d');
    ctx.clearRect(0, 0, 500, 300);
}
function draw(){
    var ctx = document.getElementById('my_canvas').getContext('2d');
    //ctx.clearRect(0, 0, 500, 300);
    ctx.drawImage(slika01, 0, 0, 500, 300); // Positioning, sizing
    ctx.drawImage(slika02, 0, 0, 500, 300); // Positioning, sizing
    ctx.drawImage(slika03, 0, 0, 500, 300); // Positioning, sizing
}
function osvezi01(vrednost){
        slika01.src = "images/sloj01_0" + vrednost + ".png";
        clear();
        draw();
    }
function osvezi02(vrednost){
        slika02.src = "images/sloj02_0" + vrednost + ".png";
        clear();
        draw();
    }
function osvezi03(vrednost){
        slika03.src = "images/sloj03_0" + vrednost + ".png";
        clear();
        draw();
    }

window.onload = draw;
</script>
</head>
<body>
<canvas id="my_canvas" width="500" height="300"></canvas>
<p>
<label for="slikai01">slikai 1. sloja</label>
<select name="slikai01" id="slikai01" onClick="osvezi01(this.value);">
<script>
    text = "";
    for (i = 1; i<=5; i++){
        text += '<option value="' + i + '">' + i + '</option>';
    }
    document.getElementById("slikai01").innerHTML = text;
</script>
</select>
<label for="slikai02"> | slikai 2. sloja</label>
<select name="slikai02" id="slikai02" onClick="osvezi02(this.value);">
<script>
    text = "";
    for (i = 1; i<=5; i++){
        text += '<option value="' + i + '">' + i + '</option>';
    }
    document.getElementById("slikai02").innerHTML = text;
</script>
</select>
<label for="slikai03"> | slikai 3. sloja</label>
<select name="slikai03" id="slikai03" onClick="osvezi03(this.value);">
<script>
    text = "";
    for (i = 1; i<=5; i++){
        text += '<option value="' + i + '">' + i + '</option>';
    }
    document.getElementById("slikai03").innerHTML = text;
</script>
</select>
</p>
</body>  
</html>

1 Answers1

0

You can try to use the onchange event instead of the onClick event for your dropdowns.

I rebuilt the environment locally and it runs for me. I tested it with the links to your images on your server so I guess the preloading works.

What I did is that I changed the onClick to the onchange event and added the preloading of all images.

I also split up the source code into three different files and merged the three dropdown event functions to one function and added a parameter instead. But those two changes are not necessary to solve the problem. The first two changes are enough.

Here is the source code:

index.html

<html>
<head>
    <link rel="stylesheet" type="text/css" href="style.css" media="screen" />
    <script src="script.js"></script>
</head>
<body>
<canvas id="my_canvas" width="500" height="300"></canvas>
<p>
<label for="slikai01">slikai 1. sloja</label>
<select name="slikai01" id="slikai01" onchange="redraw(this.value, 1);">
    <script>
        text = "";
        for (i = 1; i<=5; i++){
            text += '<option value="' + i + '">' + i + '</option>';
        }
        document.getElementById("slikai01").innerHTML = text;
    </script>
</select>
<label for="slikai02"> | slikai 2. sloja</label>
<select name="slikai02" id="slikai02" onchange="redraw(this.value, 2);">
    <script>
        text = "";
        for (i = 1; i<=5; i++){
            text += '<option value="' + i + '">' + i + '</option>';
        }
        document.getElementById("slikai02").innerHTML = text;
    </script>
</select>
<label for="slikai03"> | slikai 3. sloja</label>
<select name="slikai03" id="slikai03" onchange="redraw(this.value, 3);">
    <script>
        text = "";
        for (i = 1; i<=5; i++){
            text += '<option value="' + i + '">' + i + '</option>';
        }
        document.getElementById("slikai03").innerHTML = text;
    </script>
</select>
</p>
</body>  

style.css

body {
    margin:40px;
    background:#666;
}

#my_canvas {
    background:#FFF;
    border:#000 1px solid;
}

script.js

new Image().src = "images/sloj01_01.png";
new Image().src = "images/sloj01_02.png";
new Image().src = "images/sloj01_03.png";
new Image().src = "images/sloj01_04.png";
new Image().src = "images/sloj01_05.png";

new Image().src = "images/sloj02_01.png";
new Image().src = "images/sloj02_02.png";
new Image().src = "images/sloj02_03.png";
new Image().src = "images/sloj02_04.png";
new Image().src = "images/sloj02_05.png";

new Image().src = "images/sloj03_01.png";
new Image().src = "images/sloj03_02.png";
new Image().src = "images/sloj03_03.png";
new Image().src = "images/sloj03_04.png";
new Image().src = "images/sloj03_05.png";

var slika01 = new Image();
slika01.src = "images/sloj01_01.png";
var slika02 = new Image();
slika02.src = "images/sloj02_01.png";
var slika03 = new Image();
slika03.src = "images/sloj03_01.png";

function clear() {
    var ctx = document.getElementById('my_canvas').getContext('2d');
    ctx.clearRect(0, 0, 500, 300);
}

function draw(){
    var ctx = document.getElementById('my_canvas').getContext('2d');
    //ctx.clearRect(0, 0, 500, 300);
    ctx.drawImage(slika01, 0, 0, 500, 300); // Positioning, sizing
    ctx.drawImage(slika02, 0, 0, 500, 300); // Positioning, sizing
    ctx.drawImage(slika03, 0, 0, 500, 300); // Positioning, sizing
}

function redraw(vrednost, num){
    switch(num) {
        case 1:
            slika01.src = "images/sloj01_0" + vrednost + ".png";
            break;
        case 2:
            slika02.src = "images/sloj02_0" + vrednost + ".png";
            break;
        case 3:
            slika03.src = "images/sloj03_0" + vrednost + ".png";
            break;
    }
    clear();
    draw();
}

window.onload = draw;
Bee
  • 1,306
  • 2
  • 10
  • 24
  • I try that first but I got worst results than with onClick in google Chrome and FireFox browsers. I make clear() function in order to overcome that problem but without success. Open link I post to see that problem in vivo. – Pedja Ivanovic Dec 28 '15 at 20:37
  • I think I figured something out. Also I don't think it is a cross-browser problem. Just click every item in the dropdown menus once. After clicking all of them there is no more problem when clicking them again. I think the problem there is, that the images need a little bit to load. – Bee Dec 28 '15 at 21:04
  • You are wrong - in IE it work as a charm - when I chose item from dropDown menu it instantly change image, but in Chrome and FireFox I need to click twice on dropDown menu to change image in canvas. – Pedja Ivanovic Dec 28 '15 at 21:12
  • Have you tried to clear your cache in IE? After I did this I got the problem again. - As a solution I would suggest to preload all of the images or draw the rectangles instead of drawing them from pictures. For preloading there is the `onLoad` event for `Image` objects which can be used to check if an image was loaded. – Bee Dec 28 '15 at 21:18
  • I found [THIS](http://stackoverflow.com/questions/8504764/preload-images) where it says you simply can preload images like this `new Image().src='image.png';` – Bee Dec 28 '15 at 21:28
  • I use those rectangles just for testing - instead of them I'll use pictures. I'll try with preload and report. Thanx in any way. – Pedja Ivanovic Dec 28 '15 at 21:35
  • I try with preload images but I got same result. :( – Pedja Ivanovic Dec 28 '15 at 23:07
  • I rebuilt the environment locally and added the results in the answer. – Bee Dec 29 '15 at 00:47
  • It work as a charm. Thanx mate. I hawe one more question - instead of these 5 picture I'm gonna have 500 pictures for every layer (1500 pictures in sum). Can I preload all those pictures in some FOR loop ? – Pedja Ivanovic Dec 29 '15 at 06:40
  • I am glad I could help! – Bee Dec 29 '15 at 10:29
  • i want to do the same thing but change the canvas image on click event. Also using angularjs. Is there any demo or link for reference.? It's your great help to me. Thank you in advance. – Ravi Shrimali Feb 01 '18 at 06:11
  • The following line shows where ```redraw``` gets called: ``` – Bee Feb 02 '18 at 17:30