Как стереть холст с помощью курсора

Я хочу добавить адаптивный холст на веб-страницу. Это просто черный div, который можно стирать курсором.

Div 1 (холст) поверх div 2 (текст). Курсор должен стереть div 1 и показать div 2.

Обновить

Я использую этот код, но он не работает.

var canvas = document.getElementById("canvasTop");
var ctx = canvas.getContext("2d");
    ctx.lineWidth = 10;
    ctx.lineCap = "round";
    ctx.lineJoin = "round";
    ctx.fillStyle = "skyblue";
    ctx.fillRect(0, 0, canvas.width, canvas.height);

var canvasOffset = $("#canvasTop").offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;

var startX;
var startY;
var isDown = false;

function handleMouseDown(e) {
    e.preventDefault();
    startX = parseInt(e.clientX - offsetX);
    startY = parseInt(e.clientY - offsetY);
    isDown = true;
}

function handleMouseUp(e) {
    e.preventDefault();
    isDown = false;
}

function handleMouseOut(e) {
    e.preventDefault();
    isDown = false;
}

function handleMouseMove(e) {
    if (!isDown) {
        return;
    }
    mouseX = parseInt(e.clientX - offsetX);
    mouseY = parseInt(e.clientY - offsetY);

    // Put your mousemove stuff here
    ctx.save();
    ctx.globalCompositeOperation = "destination-out";
    ctx.beginPath();
    ctx.moveTo(startX, startY);
    ctx.lineTo(mouseX, mouseY);
    ctx.stroke();
    startX = mouseX;
    startY = mouseY;
}

$("#canvasTop").mousedown(function (e) {
    handleMouseDown(e);
});
$("#canvasTop").mousemove(function (e) {
    handleMouseMove(e);
});
$("#canvasTop").mouseup(function (e) {
    handleMouseUp(e);
});
$("#canvasTop").mouseout(function (e) {
    handleMouseOut(e);
});
html, body {height:100%}
body {
  margin:0; padding:0;
}
#wrapper {
  position:relative; 
  margin:auto; 
  width:100%; 
  height:100%; 
  background-color:#ffffff
}
#canvasTop {
  position:absolute; 
  top:0px; 
  left:0px; 
  width:100%; 
  height:100%;
}
#text {
  position:absolute; 
  left:0; 
  right:0; 
  margin-left:auto; 
  margin-right:auto; 
  width:400px; 
  height:200px; 
  text-align:center; 
  top: 50%; 
  transform:translateY(-50%); 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
    <canvas id="canvasTop" width=100% height=100%></canvas>
    <div id="text">
    <p> Text Text Text Text Text Text Text Text Text</p>
    <p> Text Text Text Text Text Text</p>
    <p> Text Text Text Text Text Text</p>
    <p> Text Text Text Text Text Text Text Text Text</p>
   </div>
</div>

Надеюсь, кто-нибудь может помочь!

Спасибо


person F.S.    schedule 06.07.2016    source источник
comment
Ваш вопрос не ясен. Возможно, проверьте этот пример откровения.   -  person markE    schedule 06.07.2016
comment
Спасибо @marke! Это именно то, что я искал. Однако я хотел бы использовать эту анимацию поверх div с текстом вместо изображения. Как я могу это сделать?   -  person F.S.    schedule 06.07.2016
comment
Точно так же ... просто поместите текст div + под стираемый холст. Попробуйте его закодировать. :-)   -  person markE    schedule 07.07.2016
comment
Я новичок в Javascript и холсте. Я не знаю, как заменить изображение на div, который содержит некоторый текст.   -  person F.S.    schedule 07.07.2016
comment
Используйте HTML, чтобы добавить свой текстовый div. Используйте CSS position:absolute, чтобы поместить холст поверх этого div.   -  person markE    schedule 07.07.2016
comment
@markE Я поменял «canvasBottom» на свой текстовый элемент div в HTML, но я не понимаю, что делать с Javascript. Я удалил код изображения, и анимация больше не работает. Я добавил фрагмент к своему вопросу.   -  person F.S.    schedule 07.07.2016
comment
Я опубликовал ответ с рабочим кодом и пояснениями необходимых изменений. Удачи с вашим проектом! :-)   -  person markE    schedule 07.07.2016
comment
Благодарю вас! Он работает отлично! @markE   -  person F.S.    schedule 08.07.2016
comment
Привет, есть ли способ перерисовать эту анимацию при изменении размера окна?   -  person F.S.    schedule 02.04.2017


Ответы (2)


Эти изменения в вашем коде должны создать эффект «стирания»:

  • Переместите #text перед #canvasTop
  • Не используйте CSS для изменения размера холста. Это приведет к искажению холста.
  • Установите ширину и высоту элемента холста равными ширине и высоте #wrapper.

Вот рефакторинг кода с аннотациями изменений:

var canvas = document.getElementById("canvasTop");
// set the canvas element's width/height to cover #wrapper
var wrapper=document.getElementById('wrapper');
var wrapperStyle=window.getComputedStyle(wrapper,null);
canvas.width=parseInt(wrapperStyle.getPropertyValue("width"));
canvas.height=parseInt(wrapperStyle.getPropertyValue("height"));
//
var ctx = canvas.getContext("2d");
    ctx.lineWidth = 10;
    ctx.lineCap = "round";
    ctx.lineJoin = "round";
    ctx.fillStyle = "skyblue";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    // set "erase" compositing once at start of app for better performance
    ctx.globalCompositeOperation = "destination-out";

var canvasOffset = $("#canvasTop").offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;

var startX;
var startY;
var isDown = false;

function handleMouseDown(e) {
    e.preventDefault();
    startX = parseInt(e.clientX - offsetX);
    startY = parseInt(e.clientY - offsetY);
    isDown = true;
}

function handleMouseUp(e) {
    e.preventDefault();
    isDown = false;
}

function handleMouseOut(e) {
    e.preventDefault();
    isDown = false;
}

function handleMouseMove(e) {
    if (!isDown) {
        return;
    }
    mouseX = parseInt(e.clientX - offsetX);
    mouseY = parseInt(e.clientY - offsetY);

    // Put your mousemove stuff here
    ctx.beginPath();
    ctx.moveTo(startX, startY);
    ctx.lineTo(mouseX, mouseY);
    ctx.stroke();
    startX = mouseX;
    startY = mouseY;
}

$("#canvasTop").mousedown(function (e) {
    handleMouseDown(e);
});
$("#canvasTop").mousemove(function (e) {
    handleMouseMove(e);
});
$("#canvasTop").mouseup(function (e) {
    handleMouseUp(e);
});
$("#canvasTop").mouseout(function (e) {
    handleMouseOut(e);
});
html, body {height:100%}
body { margin:0; padding:0; }
#wrapper {
  position:relative; 
  margin:auto; 
  width:100%; 
  height:100%; 
  background-color:#ffffff;
}
#canvasTop {
  position:absolute; 
  top:0px; 
  left:0px; 
}
#text {
  position:absolute; 
  left:0; 
  right:0; 
  margin-left:auto; 
  margin-right:auto; 
  width:400px; 
  height:200px; 
  text-align:center; 
  top: 50%; 
  transform:translateY(-50%); 
}
#canvas{border:1px solid red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Drag the mouse over center to "scratch-off" reveal</h4>
<div id="wrapper">
  <!-- move #text before #canvasTop -->
  <div id="text">
    <p> Text Text Text Text Text Text Text Text Text</p>
    <p> Text Text Text Text Text Text</p>
    <p> Text Text Text Text Text Text</p>
    <p> Text Text Text Text Text Text Text Text Text</p>
  </div>
  <canvas id="canvasTop" width=512 height=512></canvas>
</div>

person markE    schedule 07.07.2016
comment
Большое спасибо! Я изучу каждую строчку, чтобы понять, как это работает! :-) - person F.S.; 08.07.2016

Вы имеете в виду это?

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, 100, 100);
ctx.canvas.addEventListener('mousedown', function(evt) { 
  document.getElementById('canvas').remove();
}, false);

https://jsfiddle.net/mansim/krzpc1wd/

person mansim    schedule 06.07.2016
comment
Привет @mansim, я имею в виду что-то вроде этой ссылки, но с текстом внутри div вместо изображения. - person F.S.; 06.07.2016