画布放居中 鼠标错位应该怎么解决

图片说明

在网上学javaScript(Canvas)做了个画板,现在想把这画布放在中间,用CSS调到中间之后就画不了(鼠标错位),

网上找不着什么教程,希望那位大佬教教

HTML

<body>

<canvas id="drawing-board" width="500" height="500"></canvas>

<div class="color-group">

<ul>

<li id="black" class="color-item active"></li>

<li id="red" class="color-item"></li>

<li id="blue" class="color-item"></li>

<li id="yellow" class="color-item"></li>

<li id="green" class="color-item"></li>

<li id="gray" class="color-item"></li>

<li id="fuchsia" class="color-item"></li>

<li id="aqua" class="color-item"></li>

<li id="purple" class="color-item"></li>

<li id="maroon" class="color-item"></li>

</ul>

</div>

<div id="range-wrap"><input type="range" id="range" min="1" max="8" value="5" title=""></div>

<div class="tools">

<button id="brush" class="active" title=""><i class="iconfont icon-qianbi">笔</i></button>

<button id="eraser" title="" text=""><i class="iconfont icon-xiangpi">橡皮</i></button>

<button id="clear" title=""><i class="iconfont icon-qingchu">清除</i></button>

<button id="undo" title=""><i class="iconfont icon-chexiao">返回</i></button>

<button id="save" title=""><i class="iconfont icon-fuzhi">保存</i></button>

</div>

</body>

CSS

*{margin:0; padding: 0;user-select: none;}

body{overflow:hidden}

#drawing-board{background: white;position:fixed; display: block;cursor: crosshair; width:500px height:500px;border: solid 2px gray;}

.tools{position: fixed;left:0;bottom: 50px; width:100%;display: flex;justify-content: center;text-align: center}

.tools button{border-radius: 50%;width: 50px;height: 50px; background-color: rgba(255,255,255,0.7);border: 1px solid #eee;outline: none;cursor: pointer;box-sizing: border-box;margin: 0 10px;text-align: center;color:#ccc;line-height: 50px;box-shadow:0 0 8px rgba(0,0,0,0.1); transition: 0.3s;}

.tools button.active,.tools button:active{box-shadow: 0 0 15px #00CCFF; color:#00CCFF;}

.tools button i{font-size: 14px;}

.color-group{position:fixed;width: 30px;left: 30px;top:30%;transform: translate(0,-150px)}

.color-group ul{list-style: none;}

.color-group ul li{width: 30px;height: 30px;margin: 10px 0;border-radius: 50%;box-sizing: border-box;border:3px solid white;box-shadow: 0 0 8px rgba(0,0,0,0.2);cursor: pointer;transition: 0.3s;}

.color-group ul li.active{box-shadow:0 0 15px #00CCFF;}

#range-wrap{position: fixed;top: 50%;right:30px;width: 30px;height: 150px;margin-top: -75px;}

#range-wrap input{transform: rotate(-90deg);width: 150px;height: 20px;margin: 0;transform-origin: 75px 75px; border-radius: 15px;-webkit-appearance: none;outline: none;position: relative;}

#range-wrap input::after{display: block;content:"";width:0;height: 0;border:5px solid transparent;

border-right:150px solid #00CCFF;border-left-width:0;position: absolute;left: 0;top: 5px;border-radius:15px; z-index: 0; }

#range-wrap input[type=range]::-webkit-slider-thumb,#range-wrap input[type=range]::-moz-range-thumb{-webkit-appearance: none;}

#range-wrap input[type=range]::-webkit-slider-runnable-track,#range-wrap input[type=range]::-moz-range-track {height: 10px;border-radius: 10px;box-shadow: none;}

#range-wrap input[type=range]::-webkit-slider-thumb{-webkit-appearance: none;height: 20px;width: 20px;margin-top: -1px;background: #ffffff;border-radius: 50%;box-shadow: 0 0 8px #00CCFF;position: relative;z-index: 999;}

@media screen and (max-width: 868px) {

.tools{bottom:auto;top:20px;}

.tools button{width: 50px;height: 50px;line-height: 50px;margin-bottom: 50px;box-shadow:0 0 5px rgba(0,0,0,0.1);}

.tools button.active,.tools button:active{box-shadow: 0 0 5px #00CCFF;}

.tools button i{font-size: 30px;}

.tools #swatches{display: none}

.color-group{left: 0;top:auto;bottom: 40px;display: flex;width:100%;justify-content: center;text-align: center;transform: translate(0,0)}

.color-group ul li{display: inline-block;margin:0 5px;}

.color-group ul li.active{box-shadow:0 0 10px ;}

#range-wrap{right:auto;left: 20px;}

}

JS

let canvas = document.getElementById("drawing-board");

let ctx = canvas.getContext("2d");

let eraser = document.getElementById("eraser");

let brush = document.getElementById("brush");

let reSetCanvas = document.getElementById("clear");

let aColorBtn = document.getElementsByClassName("color-item");

let save = document.getElementById("save");

let undo = document.getElementById("undo");

let range = document.getElementById("range");

let clear = false;

let activeColor = 'black';

let lWidth = 4;

autoSetSize(canvas);

setCanvasBg('white');

listenToUser(canvas);

getColor();

window.onbeforeunload = function(){

return "Reload site?";

};

function autoSetSize(canvas) {

canvasSetSize();

function canvasSetSize() {

let pageWidth = document.documentElement.clientWidth;

let pageHeight = document.documentElement.clientHeight;

canvas.width = 500;

canvas.height = 500;

}

window.onresize = function () {

canvasSetSize();

}

}

function setCanvasBg(color) {

ctx.fillStyle = color;

ctx.fillRect(0, 0, canvas.width, canvas.height);

ctx.fillStyle = "black";

}

function listenToUser(canvas) {

let painting = false;

let lastPoint = {x: undefined, y: undefined};

if (document.body.ontouchstart !== undefined) {

canvas.ontouchstart = function (e) {

this.firstDot = ctx.getImageData(0, 0, canvas.width, canvas.height);

saveData(this.firstDot);

painting = true;

let x = e.touches[0].clientX;

let y = e.touches[0].clientY;

lastPoint = {"x": x, "y": y};

ctx.save();

drawCircle(x, y, 0);

};

canvas.ontouchmove = function (e) {

if (painting) {

let x = e.touches[0].clientX;

let y = e.touches[0].clientY;

let newPoint = {"x": x, "y": y};

drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y);

lastPoint = newPoint;

}

};

canvas.ontouchend = function () {

painting = false;

}

} else {

canvas.onmousedown = function (e) {

this.firstDot = ctx.getImageData(0, 0, canvas.width, canvas.height);

saveData(this.firstDot);

painting = true;

let x = e.clientX;

let y = e.clientY;

lastPoint = {"x": x, "y": y};

ctx.save();

drawCircle(x, y, 0);

};

canvas.onmousemove = function (e) {

if (painting) {

let x = e.clientX;

let y = e.clientY;

let newPoint = {"x": x, "y": y};

drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y,clear);

lastPoint = newPoint;

}

};

canvas.onmouseup = function () {

painting = false;

};

canvas.mouseleave = function () {

painting = false;

}

}

}

function drawCircle(x, y, radius) {

ctx.save();

ctx.beginPath();

ctx.arc(x, y, radius, 0, Math.PI * 2);

ctx.fill();

if (clear) {

ctx.clip();

ctx.clearRect(0,0,canvas.width,canvas.height);

ctx.restore();

}

}

function drawLine(x1, y1, x2, y2) {

ctx.lineWidth = lWidth;

ctx.lineCap = "round";

ctx.lineJoin = "round";

if (clear) {

ctx.save();

ctx.globalCompositeOperation = "destination-out";

ctx.moveTo(x1, y1);

ctx.lineTo(x2, y2);

ctx.stroke();

ctx.closePath();

ctx.clip();

ctx.clearRect(0,0,canvas.width,canvas.height);

ctx.restore();

}else{

ctx.moveTo(x1, y1);

ctx.lineTo(x2, y2);

ctx.stroke();

ctx.closePath();

}

}

range.onchange = function(){

lWidth = this.value;

};

eraser.onclick = function () {

clear = true;

this.classList.add("active");

brush.classList.remove("active");

};

brush.onclick = function () {

clear = false;

this.classList.add("active");

eraser.classList.remove("active");

};

reSetCanvas.onclick = function () {

ctx.clearRect(0, 0, canvas.width, canvas.height);

setCanvasBg('white');

};

save.onclick = function () {

let imgUrl = canvas.toDataURL("image/png");

let saveA = document.createElement("a");

document.body.appendChild(saveA);

saveA.href = imgUrl;

saveA.download = "zspic" + (new Date).getTime();

saveA.target = "_blank";

saveA.click();

};

function getColor(){

for (let i = 0; i < aColorBtn.length; i++) {

aColorBtn[i].onclick = function () {

for (let i = 0; i < aColorBtn.length; i++) {

aColorBtn[i].classList.remove("active");

this.classList.add("active");

activeColor = this.style.backgroundColor;

ctx.fillStyle = activeColor;

ctx.strokeStyle = activeColor;

}

}

}

}

let historyDeta = [];

function saveData (data) {

(historyDeta.length === 10) && (historyDeta.shift());

historyDeta.push(data);

}

undo.onclick = function(){

if(historyDeta.length < 1) return false;

ctx.putImageData(historyDeta[historyDeta.length - 1], 0, 0);

historyDeta.pop()

};

回答

你要重新计算,画布上的画点。就是说,画布起点与鼠标起点不同了。你要计算画布到视口的left与top,然后画到画布上,鼠标的坐标都减掉对应的left与top。我帮你改了。代码如下:图片说明

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport"

content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no">

<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>Document</title>

<style>

* {

margin: 0;

padding: 0;

user-select: none;

}

body {

/* overflow: hidden */

position: relative;

width: 500px;

margin: 0 auto;

height: 500px;

}

#drawing-board {

background: white;

/* position: fixed; */

display: block;

cursor: crosshair;

width: 500px;

height:500px;

border: solid 2px gray;

position: absolute;

left: 0;

top: 0;

}

.tools {

position: fixed;

left: 0;

bottom: 50px;

width: 100%;

display: flex;

justify-content: center;

text-align: center

}

.tools button {

border-radius: 50%;

width: 50px;

height: 50px;

background-color: rgba(255, 255, 255, 0.7);

border: 1px solid #eee;

outline: none;

cursor: pointer;

box-sizing: border-box;

margin: 0 10px;

text-align: center;

color: #ccc;

line-height: 50px;

box-shadow: 0 0 8px rgba(0, 0, 0, 0.1);

transition: 0.3s;

}

.tools button.active,

.tools button:active {

box-shadow: 0 0 15px #00CCFF;

color: #00CCFF;

}

.tools button i {

font-size: 14px;

}

.color-group {

position: fixed;

width: 30px;

left: 30px;

top: 30%;

transform: translate(0, -150px)

}

.color-group ul {

list-style: none;

}

.color-group ul li {

width: 30px;

height: 30px;

margin: 10px 0;

border-radius: 50%;

box-sizing: border-box;

border: 3px solid white;

box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);

cursor: pointer;

transition: 0.3s;

}

.color-group ul li.active {

box-shadow: 0 0 15px #00CCFF;

}

#range-wrap {

position: fixed;

top: 50%;

right: 30px;

width: 30px;

height: 150px;

margin-top: -75px;

}

#range-wrap input {

transform: rotate(-90deg);

width: 150px;

height: 20px;

margin: 0;

transform-origin: 75px 75px;

border-radius: 15px;

-webkit-appearance: none;

outline: none;

position: relative;

}

#range-wrap input::after {

display: block;

content: "";

width: 0;

height: 0;

border: 5px solid transparent;

border-right: 150px solid #00CCFF;

border-left-width: 0;

position: absolute;

left: 0;

top: 5px;

border-radius: 15px;

z-index: 0;

}

#range-wrap input[type=range]::-webkit-slider-thumb,

#range-wrap input[type=range]::-moz-range-thumb {

-webkit-appearance: none;

}

#range-wrap input[type=range]::-webkit-slider-runnable-track,

#range-wrap input[type=range]::-moz-range-track {

height: 10px;

border-radius: 10px;

box-shadow: none;

}

#range-wrap input[type=range]::-webkit-slider-thumb {

-webkit-appearance: none;

height: 20px;

width: 20px;

margin-top: -1px;

background: #ffffff;

border-radius: 50%;

box-shadow: 0 0 8px #00CCFF;

position: relative;

z-index: 999;

}

@media screen and (max-width: 868px) {

.tools {

bottom: auto;

top: 20px;

}

.tools button {

width: 50px;

height: 50px;

line-height: 50px;

margin-bottom: 50px;

box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);

}

.tools button.active,

.tools button:active {

box-shadow: 0 0 5px #00CCFF;

}

.tools button i {

font-size: 30px;

}

.tools #swatches {

display: none

}

.color-group {

left: 0;

top: auto;

bottom: 40px;

display: flex;

width: 100%;

justify-content: center;

text-align: center;

transform: translate(0, 0)

}

.color-group ul li {

display: inline-block;

margin: 0 5px;

}

.color-group ul li.active {

box-shadow: 0 0 10px;

}

#range-wrap {

right: auto;

left: 20px;

}

}

</style>

</head>

<body>

<canvas id="drawing-board" width="500" height="500"></canvas>

<div class="color-group">

<ul>

<li id="black" class="color-item active" style="background-color: black;"></li>

<li id="red" class="color-item" style="background-color: #FF3333;"></li>

<li id="blue" class="color-item" style="background-color: #0066FF;"></li>

<li id="yellow" class="color-item" style="background-color: #FFFF33;"></li>

<li id="green" class="color-item" style="background-color: #33CC66;"></li>

<li id="gray" class="color-item" style="background-color: gray;"></li>

<li id="fuchsia" class="color-item" style="background-color: fuchsia;"></li>

<li id="aqua" class="color-item" style="background-color: aqua;"></li>

<li id="purple" class="color-item" style="background-color: purple;"></li>

<li id="maroon" class="color-item" style="background-color: maroon;"></li>

</ul>

</div>

<div id="range-wrap"><input type="range" id="range" min="1" max="8" value="5" title=""></div>

<div class="tools">

<button id="brush" class="active" title=""><i class="iconfont icon-qianbi">笔</i></button>

<button id="eraser" title="" text=""><i class="iconfont icon-xiangpi">橡皮</i></button>

<button id="clear" title=""><i class="iconfont icon-qingchu">清除</i></button>

<button id="undo" title=""><i class="iconfont icon-chexiao">返回</i></button>

<button id="save" title=""><i class="iconfont icon-fuzhi">保存</i></button>

</div>

</body>

</html>

<script>

let canvas = document.getElementById("drawing-board");

let ctx = canvas.getContext("2d");

let eraser = document.getElementById("eraser");

let brush = document.getElementById("brush");

let reSetCanvas = document.getElementById("clear");

let aColorBtn = document.getElementsByClassName("color-item");

let save = document.getElementById("save");

let undo = document.getElementById("undo");

let range = document.getElementById("range");

let clear = false;

let activeColor = 'black';

let lWidth = 4;

let offsetLeft = canvas.getBoundingClientRect().left

let offsetTop = canvas.getBoundingClientRect().top

autoSetSize(canvas);

setCanvasBg('white');

listenToUser(canvas);

getColor();

window.onbeforeunload = function () {

return "Reload site?";

};

function autoSetSize(canvas) {

canvasSetSize();

function canvasSetSize() {

let pageWidth = document.documentElement.clientWidth;

let pageHeight = document.documentElement.clientHeight;

canvas.width = 500;

canvas.height = 500;

}

window.onresize = function () {

canvasSetSize();

}

}

function setCanvasBg(color) {

ctx.fillStyle = color;

ctx.fillRect(0, 0, canvas.width, canvas.height);

ctx.fillStyle = "black";

}

function listenToUser(canvas) {

let painting = false;

let lastPoint = { x: undefined, y: undefined };

if (document.body.ontouchstart !== undefined) {

canvas.ontouchstart = function (e) {

let x = e.touches[0].clientX;

let y = e.touches[0].clientY;

this.firstDot = ctx.getImageData(0, 0, canvas.width, canvas.height);

saveData(this.firstDot);

painting = true;

lastPoint = { "x": x, "y": y };

ctx.save();

drawCircle(x - offsetLeft, y - offsetTop, 0);

};

canvas.ontouchmove = function (e) {

if (painting) {

let x = e.touches[0].clientX;

let y = e.touches[0].clientY;

let newPoint = { "x": x, "y": y };

drawLine(lastPoint.x - offsetLeft, lastPoint.y - offsetTop, newPoint.x - offsetLeft, newPoint.y - offsetTop, clear);

lastPoint = newPoint;

}

};

canvas.ontouchend = function () {

painting = false;

}

} else {

canvas.onmousedown = function (e) {

this.firstDot = ctx.getImageData(0, 0, canvas.width, canvas.height);

saveData(this.firstDot);

painting = true;

let x = e.clientX;

let y = e.clientY;

lastPoint = { "x": x, "y": y };

ctx.save();

drawCircle(x - offsetLeft, y - offsetTop, 0);

};

canvas.onmousemove = function (e) {

if (painting) {

let x = e.clientX;

let y = e.clientY;

let newPoint = { "x": x, "y": y };

drawLine(lastPoint.x - offsetLeft, lastPoint.y - offsetTop, newPoint.x - offsetLeft, newPoint.y - offsetTop, clear);

lastPoint = newPoint;

}

};

canvas.onmouseup = function () {

painting = false;

};

canvas.mouseleave = function () {

painting = false;

}

}

}

function drawCircle(x, y, radius) {

ctx.save();

ctx.beginPath();

ctx.arc(x, y, radius, 0, Math.PI * 2);

ctx.fill();

if (clear) {

ctx.clip();

ctx.clearRect(0, 0, canvas.width, canvas.height);

ctx.restore();

}

}

function drawLine(x1, y1, x2, y2) {

ctx.lineWidth = lWidth;

ctx.lineCap = "round";

ctx.lineJoin = "round";

if (clear) {

ctx.save();

ctx.globalCompositeOperation = "destination-out";

ctx.moveTo(x1, y1);

ctx.lineTo(x2, y2);

ctx.stroke();

ctx.closePath();

ctx.clip();

ctx.clearRect(0, 0, canvas.width, canvas.height);

ctx.restore();

} else {

ctx.moveTo(x1, y1);

ctx.lineTo(x2, y2);

ctx.stroke();

ctx.closePath();

}

}

range.onchange = function () {

lWidth = this.value;

};

eraser.onclick = function () {

clear = true;

this.classList.add("active");

brush.classList.remove("active");

};

brush.onclick = function () {

clear = false;

this.classList.add("active");

eraser.classList.remove("active");

};

reSetCanvas.onclick = function () {

ctx.clearRect(0, 0, canvas.width, canvas.height);

setCanvasBg('white');

};

save.onclick = function () {

let imgUrl = canvas.toDataURL("image/png");

let saveA = document.createElement("a");

document.body.appendChild(saveA);

saveA.href = imgUrl;

saveA.download = "zspic" + (new Date).getTime();

saveA.target = "_blank";

saveA.click();

};

function getColor() {

for (let i = 0; i < aColorBtn.length; i++) {

aColorBtn[i].onclick = function () {

for (let i = 0; i < aColorBtn.length; i++) {

aColorBtn[i].classList.remove("active");

this.classList.add("active");

activeColor = this.style.backgroundColor;

ctx.fillStyle = activeColor;

ctx.strokeStyle = activeColor;

}

}

}

}

let historyDeta = [];

function saveData(data) {

(historyDeta.length === 10) && (historyDeta.shift());

historyDeta.push(data);

}

undo.onclick = function () {

if (historyDeta.length < 1) return false;

ctx.putImageData(historyDeta[historyDeta.length - 1], 0, 0);

historyDeta.pop()

};

</script>

以上是 画布放居中 鼠标错位应该怎么解决 的全部内容, 来源链接: utcz.com/a/35220.html

回到顶部