#javascript #html #css #canvas #mouse
#javascript #HTML #css #холст #мышь
Вопрос:
Мои координаты мыши совершенно сбились с курса с тех пор, как я разработал свой HTML canvas для адаптивного дизайна. Он работал отлично, когда у него не было стиля и он находился в левом верхнем углу экрана. Однако теперь, когда у меня уменьшено окно borwser, или при использовании на мобильном устройстве курсор не будет отображаться там, где он должен быть, т. е. точно на пути рисования, вместо этого он либо на несколько пикселей выше, либо под ним. Ниже приведен мой код, любая помощь была бы высоко оценена
function init() {
// Get the specific canvas element from the HTML document
canvas = document.getElementById('c');
}
function midPointBtw(p1, p2) {
return {
x: p1.x (p2.x - p1.x) / 2,
y: p1.y (p2.y - p1.y) / 2
};
}
function getPattern() {
return ctx.createPattern(img, 'repeat');
}
var el = document.getElementById('c');
var ctx = el.getContext('2d');
ctx.lineWidth = 30;
ctx.lineJoin = ctx.lineCap = 'round';
var img = new Image;
img.onload = function() {
ctx.strokeStyle = getPattern();
};
img.src = "https://i.postimg.cc/rF2R0GRY/dick2.png";
var isDrawing, points = [];
var getXY = function(e) {
var source = e.touches ? e.touches[0] : e;
return {
x: source.clientX,
y: source.clientY
};
};
var startDrawing = function(e) {
isDrawing = true;
points.push(getXY(e));
event.preventDefault();
};
var keepDrawing = function(e) {
if (!isDrawing) return;
points.push(getXY(e));
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
var p1 = points[0];
var p2 = points[1];
ctx.moveTo(p1.x, p1.y);
for (var i = 1, len = points.length; i < len; i ) {
var midPoint = midPointBtw(p1, p2);
ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
p1 = points[i];
p2 = points[i 1];
}
ctx.lineTo(p1.x, p1.y);
ctx.stroke();
event.preventDefault();
};
var stopDrawing = function() {
isDrawing = false;
points = [];
};
el.addEventListener('touchstart', startDrawing);
el.addEventListener('mousedown', startDrawing);
el.addEventListener('touchmove', keepDrawing);
el.addEventListener('mousemove', keepDrawing);
el.addEventListener('touchend', stopDrawing);
el.addEventListener('mouseup', stopDrawing);
function clearCanvas(canvas, ctx) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath()
}
@import url('https://fonts.googleapis.com/css?family=Montserrat Alternates');
@media screen and (max-width: 425px) {
html,
body {
overflow-x: hidden;
width: 100%;
margin: 0;
}
#logo {
margin: 0 auto;
display: block;
margin-bottom: 15px;
margin-top: 15px;
}
.container1 {
background-color: #313131;
border-radius: 20px;
border: 3px solid #0BF446;
height: 250px;
}
#grphc1 {
margin: 0 auto;
display: block;
margin-top: 35px;
}
#canvasintro {
border-radius: 20px 0px 20px 0px;
border: 3px solid #0BF446;
color: white;
background-color: #0BF446;
font-size: 16px;
text-align: left;
font-family: 'Montserrat Alternates', sans-serif;
margin-left: 15px;
margin-right: 15px;
margin-top: 35px;
padding: 20px;
}
canvas {
border: 3px solid #0BF446;
border-radius: 15px 0px 15px 0px;
display: block;
margin: 0 auto;
margin-top: 35px;
background-color: #313131;
position: relative;
}
#download {
background-color: #04A12B;
border-radius: 0 15px 0 15px;
padding: 20px 40px;
margin: 0 auto;
display: block;
font-size: 14px;
margin-top: 35px;
color: white;
font-family: 'Montserrat Alternates', sans-serif;
}
#clearbutton {
background-color: #04A12B;
border-radius: 0 15px 0 15px;
padding: 20px;
margin: 0 auto;
display: block;
font-size: 14px;
color: white;
font-family: 'Montserrat Alternates', sans-serif;
margin-top: 35px;
}
#footer1 {
background-color: #00671A;
border-radius: 30px 30px 0px 0px;
text-align: center;
padding: 30px;
margin-top: 35px;
}
#about {
color: white;
font-size: 16px;
font-family: 'Montserrat Alternates', sans-serif;
}
}
<!DOCTYPE html>
<html>
<head>
<title>Elemental</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body onload="init()">
<a href="../homepage.html"><img src="minilogo.png" id="logo"></a>
<div class="container1">
<img src="leaf.png" id="grphc1">
</div>
<div id="canvasintro">Feel free to draw or doodle down below with this natural element of design</div>
<canvas id="c" width="350px" height="350px"></canvas>
<button id="download">Download</button>
<input type="submit" value="Clear Sketchpad" id="clearbutton" onclick="clearCanvas(canvas,ctx);">
<footer id="footer1">
<a href="../about.html" id="about">About Elemental</a>
</footer>
</body>
</html>
Ответ №1:
Во-первых, в вашем новом конструкторе изображений отсутствуют скобки для вызова:
var img = new Img();
Но в вашей getXY()
функции возвращайте offsetX
и offsetY
вместо clientX
и clientY
:
var getXY = function(e) {
var source = e.touches ? e.touches[0] : e;
return {
x: source.offsetX,
y: source.offsetY
};
};
Здесь ‘client’ относится к области просмотра, тогда как ‘offset’ — это ссылка на край заполнения целевого узла или на сам холст.
Вам также следует добавить обработчики событий mouseout
и touchcancel
:
el.addEventListener('mouseout', stopDrawing);
el.addEventListener('touchcancel', stopDrawing);
Комментарии:
1. конструкторы без параметров не обязаны иметь круглые скобки с
new
оператором.2. Ты прав, Кайидо. Я предполагаю, что это мое предпочтение, возможно, из-за линтеров.
3. Спасибо, что ответили на мой пост, я понимаю, что вы говорите, это имеет смысл. Однако я протестировал значения
offsetX
иoffsetY
, но когда я перехожу к рисованию, ничего не отображается. просто банк? Я что-то упускаю, например, какой-то стиль или, возможно, другую функцию?4. Я сделал завершающий макет из предоставленного вами кода, и у меня это работает codepen.io/denmch/pen/6ea6b1cdaa87566cf4631f59f2953a94