2

I am trying to recreate a scratch-to-reveal-image effect with 3 images in an array triggered by 3 buttons. My event listener is not working, as you can see, it shows the same revealed images no matter the button. The event listener syntax has confused me a bit and I would like some help on that specifically.

The sketch image overlay is the same throughout. Can you guide me as to where I'm going wrong?

It's a lot of code, sorry about that, but I thought it best to just put all the detail in. Thank you in advance!

const imgArr = [{
    sketch: 'https://trellidor.co.za/wp-content/uploads/2020/12/Sketch.png',
    background1: 'https://images.pexels.com/photos/1666012/pexels-photo-1666012.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500'
  },
  {
    sketch: 'https://trellidor.co.za/wp-content/uploads/2020/12/Sketch.png',
    background2: 'https://images.pexels.com/photos/572897/pexels-photo-572897.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500'
  },
  {
    sketch: 'https://trellidor.co.za/wp-content/uploads/2020/12/Sketch.png',
    background3: 'https://images.pexels.com/photos/2365457/pexels-photo-2365457.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500'
  },
]

const btn = document.querySelector('#special'),
  bridge = document.querySelector("#bridge"),
  bridgeCanvas = bridge.getContext('2d'),
  brushRadius = (bridge.width / 100) * 7;

// default image
img = new Image();
img.onload = function() {
  bridgeCanvas.drawImage(img, 0, 0, bridge.width, bridge.height);
}
img.src = 'https://trellidor.co.za/wp-content/uploads/2020/12/Sketch.png'


btn.addEventListener('click', () => {
  img.src = imgArr[background1].sketch
  bridge.style.background1 = `url(${imgArr[background1].background1})`;
  bridge.style.backgroundSize = 'cover';
  bridgeCanvas.clearRect(0, 0, bridge.width, bridge.height);
  bridgeCanvas.globalCompositeOperation = "destination-over";
})

btn.addEventListener('click', () => {
  img.src = imgArr[background2].sketch
  bridge.style.background2 = `url(${imgArr[background2].background2})`;
  bridge.style.backgroundSize = 'cover';
  bridgeCanvas.clearRect(0, 0, bridge.width, bridge.height);
  bridgeCanvas.globalCompositeOperation = "destination-over";
})

function getBrushPos(xRef, yRef) {
  const bridgeRect = bridge.getBoundingClientRect();
  return {
    x: Math.floor((xRef - bridgeRect.left) / (bridgeRect.right - bridgeRect.left) * bridge.width),
    y: Math.floor((yRef - bridgeRect.top) / (bridgeRect.bottom - bridgeRect.top) * bridge.height)
  };
}

function drawDot(mouseX, mouseY) {
  bridgeCanvas.beginPath();
  bridgeCanvas.arc(mouseX, mouseY, brushRadius, 0, 2 * Math.PI, true);
  bridgeCanvas.globalCompositeOperation = "destination-out";
  bridgeCanvas.fill();
}


bridge.addEventListener("mousemove", (e) => {
  let brushPos = getBrushPos(e.clientX, e.clientY);
  if (e.which === 1) {
    drawDot(brushPos.x, brushPos.y);
  }
}, false);

bridge.addEventListener("touchmove", function(e) {
  let touch = e.targetTouches[0];
  if (touch) {
    let brushPos = getBrushPos(touch.pageX, touch.pageY);
    drawDot(brushPos.x, brushPos.y);
  }
}, false);
body {
  margin: 0;
}

#bridge {
  margin: 0 auto;
  background-image: url('https://trellidor.co.za/wp-content/uploads/2020/12/Colour.png');
  background-image: -webkit-image-set(url('https://trellidor.co.za/wp-content/uploads/2020/12/Colour.png') 2x);
  background-size: cover;
  width: 100%;
  max-width: 750px;
  height: auto;
  cursor: crosshair;
  cursor: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/circular-cursor.png') 53 53, crosshair;
}

#bridgeContainer {
  text-align: center;
  font-family: Avenir, sans-serif;
}

#bridgeContainer figcaption {
  margin-top: 2rem;
}

#special {
  background-color: blue;
  color: white;
  border: none;
  outline: none;
  border-radius: 1.5rem;
  font-size: larger;
  padding: .5rem 1rem;
}

#special2 {
  background-color: blue;
  color: white;
  border: none;
  outline: none;
  border-radius: 1.5rem;
  font-size: larger;
  padding: .5rem 1rem;
}

#special3 {
  background-color: blue;
  color: white;
  border: none;
  outline: none;
  border-radius: 1.5rem;
  font-size: larger;
  padding: .5rem 1rem;
}
<figure id="bridgeContainer">
  <canvas id="bridge" width="750" height="465"></canvas>
</figure>
<button id="special">Color1</button>
<button id="special2">Color2</button>
<button id="special3">Color3</button>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Esme June
  • 67
  • 5

2 Answers2

2

Look at the change I have made in the EventListener.

The changes I made are: Added class on the buttons so that they can be selected together. When placing the listener for the loop also puts "date" information on the buttons. This information is a serial number that corresponds to the Array record

const imgArr = [{
    sketch: 'https://trellidor.co.za/wp-content/uploads/2020/12/Sketch.png',
    background: 'https://images.pexels.com/photos/1666012/pexels-photo-1666012.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500'
},
{
    sketch: 'https://trellidor.co.za/wp-content/uploads/2020/12/Sketch.png',
    background: 'https://images.pexels.com/photos/572897/pexels-photo-572897.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500'
},
{
    sketch: 'https://trellidor.co.za/wp-content/uploads/2020/12/Sketch.png',
    background: 'https://images.pexels.com/photos/2365457/pexels-photo-2365457.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500'
},
]

const btn = document.querySelectorAll('.special'),
    bridge = document.querySelector("#bridge"),
    bridgeCanvas = bridge.getContext('2d'),
    brushRadius = (bridge.width / 100) * 7;

// default image
img = new Image();
img.onload = function () {
    bridgeCanvas.drawImage(img, 0, 0, bridge.width, bridge.height);
}
img.src = 'https://trellidor.co.za/wp-content/uploads/2020/12/Sketch.png'


for (var i = 0; i < imgArr.length; i++) {
    btn[i].setAttribute('data', i);
    btn[i].addEventListener("click", function () {
        myFunc(this);
    });
}

function myFunc(x) {
    var arr = x.getAttribute('data');
    img.src = imgArr[arr].sketch
    bridge.style.background = `url(${imgArr[arr].background})`;
    bridge.style.backgroundSize = 'cover';
    bridgeCanvas.clearRect(0, 0, bridge.width, bridge.height);
    bridgeCanvas.globalCompositeOperation = "destination-over";
}

function getBrushPos(xRef, yRef) {
    const bridgeRect = bridge.getBoundingClientRect();
    return {
        x: Math.floor((xRef - bridgeRect.left) / (bridgeRect.right - bridgeRect.left) * bridge.width),
        y: Math.floor((yRef - bridgeRect.top) / (bridgeRect.bottom - bridgeRect.top) * bridge.height)
    };
}

function drawDot(mouseX, mouseY) {
    bridgeCanvas.beginPath();
    bridgeCanvas.arc(mouseX, mouseY, brushRadius, 0, 2 * Math.PI, true);
    bridgeCanvas.globalCompositeOperation = "destination-out";
    bridgeCanvas.fill();
}


bridge.addEventListener("mousemove", (e) => {
    let brushPos = getBrushPos(e.clientX, e.clientY);
    if (e.which === 1) {
        drawDot(brushPos.x, brushPos.y);
    }
}, false);

bridge.addEventListener("touchmove", function (e) {
    let touch = e.targetTouches[0];
    if (touch) {
        let brushPos = getBrushPos(touch.pageX, touch.pageY);
        drawDot(brushPos.x, brushPos.y);
    }
}, false);
body {
    margin: 0;
}

#bridge {
    margin: 0 auto;
    background-image: url('https://trellidor.co.za/wp-content/uploads/2020/12/Colour.png');
    background-image: -webkit-image-set(url('https://trellidor.co.za/wp-content/uploads/2020/12/Colour.png') 2x);
    background-size: cover;
    width: 100%;
    max-width: 750px;
    height: auto;
    cursor: crosshair;
    cursor: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/circular-cursor.png') 53 53, crosshair;
}

#bridgeContainer {
    text-align: center;
    font-family: Avenir, sans-serif;
}

#bridgeContainer figcaption {
    margin-top: 2rem;
}

#special {
    background-color: blue;
    color: white;
    border: none;
    outline: none;
    border-radius: 1.5rem;
    font-size: larger;
    padding: .5rem 1rem;
}

#special2 {
    background-color: blue;
    color: white;
    border: none;
    outline: none;
    border-radius: 1.5rem;
    font-size: larger;
    padding: .5rem 1rem;
}

#special3 {
    background-color: blue;
    color: white;
    border: none;
    outline: none;
    border-radius: 1.5rem;
    font-size: larger;
    padding: .5rem 1rem;
}
<figure id="bridgeContainer">
    <canvas id="bridge" width="750" height="465"></canvas>
</figure>
<button id="special" class="special">Color1</button>
<button id="special2" class="special">Color2</button>
<button id="special3" class="special">Color3</button>
54ka
  • 3,501
  • 2
  • 9
  • 24
0

There are multiple errors in your code. First of all you are trying to access imgArr[background1] where background1 is not defined. Instead you should try accessing by index like 0,1,2. You didn't have any event listener for the other 2 buttons. The last thing is instead of assigning new images to bridge.style.background1 you should assign them to bridge.style.background. Your sketch image is same because in the imgArr all the sketch images are same which is sketch: 'https://trellidor.co.za/wp-content/uploads/2020/12/Sketch.png'. Try the below snippet.

const imgArr = [{
    sketch: 'https://trellidor.co.za/wp-content/uploads/2020/12/Sketch.png',
    background1: 'https://images.pexels.com/photos/1666012/pexels-photo-1666012.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500'
  },
  {
    sketch: 'https://trellidor.co.za/wp-content/uploads/2020/12/Sketch.png',
    background2: 'https://images.pexels.com/photos/572897/pexels-photo-572897.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500'
  },
  {
    sketch: 'https://trellidor.co.za/wp-content/uploads/2020/12/Sketch.png',
    background3: 'https://images.pexels.com/photos/2365457/pexels-photo-2365457.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500'
  },
]

const btn = document.querySelector('#special'),
btn1 = document.querySelector('#special2'),
btn2 = document.querySelector('#special3')
  bridge = document.querySelector("#bridge"),
  bridgeCanvas = bridge.getContext('2d'),
  brushRadius = (bridge.width / 100) * 7;

// default image
img = new Image();
img.onload = function() {
  bridgeCanvas.drawImage(img, 0, 0, bridge.width, bridge.height);
}
img.src = 'https://trellidor.co.za/wp-content/uploads/2020/12/Sketch.png'


btn.addEventListener('click', () => {
  img.src = imgArr[0].sketch
  bridge.style.background = `url(${imgArr[0].background1})`;
  bridge.style.backgroundSize = 'cover';
  bridgeCanvas.clearRect(0, 0, bridge.width, bridge.height);
  bridgeCanvas.globalCompositeOperation = "destination-over";
})

btn1.addEventListener('click', () => {
  img.src = imgArr[1].sketch
  bridge.style.background = `url(${imgArr[1].background2})`;
  bridge.style.backgroundSize = 'cover';
  bridgeCanvas.clearRect(0, 0, bridge.width, bridge.height);
  bridgeCanvas.globalCompositeOperation = "destination-over";
})

btn2.addEventListener('click', () => {
  img.src = imgArr[2].sketch
  bridge.style.background = `url(${imgArr[2].background3})`;
  bridge.style.backgroundSize = 'cover';
  bridgeCanvas.clearRect(0, 0, bridge.width, bridge.height);
  bridgeCanvas.globalCompositeOperation = "destination-over";
})

function getBrushPos(xRef, yRef) {
  const bridgeRect = bridge.getBoundingClientRect();
  return {
    x: Math.floor((xRef - bridgeRect.left) / (bridgeRect.right - bridgeRect.left) * bridge.width),
    y: Math.floor((yRef - bridgeRect.top) / (bridgeRect.bottom - bridgeRect.top) * bridge.height)
  };
}

function drawDot(mouseX, mouseY) {
  bridgeCanvas.beginPath();
  bridgeCanvas.arc(mouseX, mouseY, brushRadius, 0, 2 * Math.PI, true);
  bridgeCanvas.globalCompositeOperation = "destination-out";
  bridgeCanvas.fill();
}


bridge.addEventListener("mousemove", (e) => {
  let brushPos = getBrushPos(e.clientX, e.clientY);
  if (e.which === 1) {
    drawDot(brushPos.x, brushPos.y);
  }
}, false);

bridge.addEventListener("touchmove", function(e) {
  let touch = e.targetTouches[0];
  if (touch) {
    let brushPos = getBrushPos(touch.pageX, touch.pageY);
    drawDot(brushPos.x, brushPos.y);
  }
}, false);
body {
  margin: 0;
}

#bridge {
  margin: 0 auto;
  background-image: url('https://trellidor.co.za/wp-content/uploads/2020/12/Colour.png');
  background-image: -webkit-image-set(url('https://trellidor.co.za/wp-content/uploads/2020/12/Colour.png') 2x);
  background-size: cover;
  width: 100%;
  max-width: 750px;
  height: auto;
  cursor: crosshair;
  cursor: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/circular-cursor.png') 53 53, crosshair;
}

#bridgeContainer {
  text-align: center;
  font-family: Avenir, sans-serif;
}

#bridgeContainer figcaption {
  margin-top: 2rem;
}

#special {
  background-color: blue;
  color: white;
  border: none;
  outline: none;
  border-radius: 1.5rem;
  font-size: larger;
  padding: .5rem 1rem;
}

#special2 {
  background-color: blue;
  color: white;
  border: none;
  outline: none;
  border-radius: 1.5rem;
  font-size: larger;
  padding: .5rem 1rem;
}

#special3 {
  background-color: blue;
  color: white;
  border: none;
  outline: none;
  border-radius: 1.5rem;
  font-size: larger;
  padding: .5rem 1rem;
}
<figure id="bridgeContainer">
  <canvas id="bridge" width="750" height="465"></canvas>
</figure>
<button id="special">Color1</button>
<button id="special2">Color2</button>
<button id="special3">Color3</button>
Md Sabbir Alam
  • 4,937
  • 3
  • 15
  • 30