所以我使用 html canvas 制作了一堆正方形網格。我正在實作拖動機制,我只想允許用戶以矩形形狀拖動。現在,根據用戶的拖動方式,他們可以制作另一個形狀,如下所示。這是一個附帶問題,我正在使用 html canvas 和它的小延遲制作一個非常大的網格,有什么提示嗎?

這是我的 html 和 javascript 代碼
function getSquare(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: 1 (evt.clientX - rect.left) - (evt.clientX - rect.left)%10,
y: 1 (evt.clientY - rect.top) - (evt.clientY - rect.top)%10
};
}
function emptySquare(context) {
context.rect(0, 0, canvas.width, canvas.height);
context.fillStyle = "#ffffff"
context.fill();
context.strokeStyle = "#ddd";
context.stroke();
}
function range(start, end) {
var ans = [];
if (end > start) {
for (let i = start; i <= end; i = 10) {
ans.push(i);
}
} else {
emptySquare(context);
for (let i = start; i >= end; i -= 10) {
ans.push(i);
}}
return ans;
}
function drawBoard(context) {
for (var x = 0.5; x < 20001; x = 10) {
context.moveTo(x, 0);
context.lineTo(x,20000);
}
for (var y = 0.5; y < 20001; y = 10) {
context.moveTo(0, y);
context.lineTo(20000, y);
}
context.strokeStyle = "#ddd";
context.stroke();
}
function fillSquare(context, x, y){
context.fillStyle = "#70B7B5";
context.fillRect(x,y,9,9);
}
var canvas = document.getElementById('myBoard');
var context = canvas.getContext('2d');
var A;
drawBoard(context);
var isDrag= false;
// drawBoard(context);
canvas.addEventListener('mousedown', function(evt) {
var mousePos = getSquare(canvas, evt);
isDrag=true;
fillSquare(context, mousePos.x, mousePos.y);
previousPos = mousePos;
}, false);
canvas.addEventListener('mousemove', function(evt) {
if (isDrag) {
var mousePos = getSquare(canvas, evt);
var x_dist = range(previousPos.x, mousePos.x);
var y_dist = range(previousPos.y, mousePos.y);
for (x in x_dist) {
for (y in y_dist) {
fillSquare(context, x_dist[x], y_dist[y]);
}
}
}
}, false);
canvas.addEventListener('mouseup', function(evt) {
if (isDrag){
isDrag = false;
}
}, false);
// const p = context.lineWidth / 2; //padding
// const x = 30;
// const y = 30;
// const img = new Image();
// img.src = `snsd.jpg`;
// img.onload = function() {
// A = context.drawImage(img, 0, 0,200,200);
// context.strokeRect(0, 0, 200, 200);
// };
// img2 = new Image();
// img2.src = `ive.jpg`;
// img2.onload = function() {
// A = context.drawImage(img2, 200, 200,200,200);
// };
// img3 = new Image();
// img3.src = `twice.jpg`;
// img3.onload = function() {
// A = context.drawImage(img3, 0, 200,200,200);
// };
// img4 = new Image();
// img4.src = `blackpink.jpg`;
// img4.onload = function() {
// A = context.drawImage(img4, 200, 0,200,200);
// };
// img5 = new Image();
// img5.src = `promis9.jpg`;
// img5.onload = function() {
// A = context.drawImage(img5, 400, 0,400,400);
// };
// for (let xCell = 0; xCell < 10; xCell ) {
// for (let yCell = 0; yCell < 10; yCell ) {
// const x = xCell * 30;
// const y = yCell * 30;
// const img = new Image();
// img.onload = function() {
// context.drawImage(img, x p, y p, 60-p*2, 60-p*2);
// };
// img.src = `https://dummyimage.com/60x60/000/fff&text=${xCell},${yCell}`;
// }
// }
var canvas = document.getElementById('myBoard');
var context = canvas.getContext('2d');
// drawBoard(context);
var isDrag=false;
canvas.addEventListener('mousedown', function(evt) {
var mousePos = getSquare(canvas, evt);
isDrag=true;
fillSquare(context, mousePos.x, mousePos.y);
previousPos = mousePos;
}, false);
canvas.addEventListener('mousemove', function(evt) {
if (isDrag) {
var mousePos = getSquare(canvas, evt);
var x_dist = range(previousPos.x, mousePos.x);
var y_dist = range(previousPos.y, mousePos.y);
for (x in x_dist) {
for (y in y_dist) {
fillSquare(context, x_dist[x], y_dist[y]);
}
}
}
}, false);
canvas.addEventListener('mouseup', function(evt) {
if (isDrag){
isDrag = false;
}
}, false);
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="./assets/css/style.css">
<meta charset="utf-8">
</head>
<body>
<!-- <div class='container'>
<nav >
<div >
<a href="#">Navbar</a>
<button type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span ></span>
</button>
<div id="navbarNavAltMarkup">
<div >
<a aria-current="page" href="#">Home</a>
<a href="#">Features</a>
<a href="#">Pricing</a>
<a href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</div>
</div>
</div>
-->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="index.html">t</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-link" aria-current="page" href="index.html">Home</a>
<a class="nav-link" href="#">About Us</a>
<a class="nav-link" href="Myblock.html">Mk</a>
</div>
<div class="navbar-nav ms-auto mb-2 mb-lg-0">
<a class="nav-link" href="login.html">Login</a>
</div>
</div>
</div>
</nav>
<div>
<div class="modal fade bd-example-modal-lg" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">?? ??</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="" method="POST" enctype="multipart/form-data">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<div class="preview-zone hidden">
<div class="box box-solid">
<div class="box-header with-border">
<div><b>????</b></div>
<!-- <div >
<button type="button" >
<i ></i> ???
</button>
</div> -->
</div>
<div class="box-body"></div>
</div>
</div>
<div class="dropzone-wrapper">
<div class="dropzone-desc">
<i class="glyphicon glyphicon-download-alt"></i>
<p>?? ??? ?? or ???? ?? ???.</p>
</div>
<input type="file" name="img_logo" class="dropzone">
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<label for="exampleInputEmail1">???/??</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="???/??">
<label for="exampleInputEmail1">???</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="??? ??">
<label for="exampleInputEmail1">???? ??</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="ex) 10 x 10 OR 100x100 ">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">??</button>
<button type="submit" class="btn btn-dark">????</button>
</div>
</div>
</div>
</div>
<div>
<canvas id="myBoard" width="1440" height="1200"></canvas>
</div>
</hr>
<footer>
<p>? 2021 Nune Project</p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script type="text/javascript" src="./assets/js/mainBoard.js"></script>
<script type="text/javascript" src="./assets/js/drag_field.js"></script>
</body>
uj5u.com熱心網友回復:
這個問題正在被看到,因為range函式在end > start. 清除這兩種情況下的方塊可以解決問題。
這是解決問題的片段。
function range(start, end) {
var ans = [];
emptySquare(context);
if (end > start) {
for (let i = start; i <= end; i = 10) {
ans.push(i);
}
} else {
for (let i = start; i >= end; i -= 10) {
ans.push(i);
}
}
return ans;
}
滯后問題
附加到的回呼函式mousemove在每次呼叫時清除和繪制正方形 - 一個耗時的操作。鑒于 JavaScript 是單執行緒的,并且此函式的呼叫率非常高,這可能是導致延遲的原因。
防抖動的mousemove回呼可以幫助減少滯后。
uj5u.com熱心網友回復:
解決滯后問題的另一種方法是制作兩個畫布:一個用于背景網格線,另一個用于繪制綠色矩形。
<div>
<canvas id="bg" width="1440" height="1200"></canvas>
<canvas id="myBoard" width="1440" height="1200"></canvas>
</div>
設定#bg畫布,使其#myBoard位于其前面:
#bg {
position: absolute;
z-index: -1;
}
然后在#bg畫布上繪制網格線:
const bg = document.getElementById('bg')
const bgContext = bg.getContext('2d')
drawBoard(bgContext)
最后,將emptySquare(context)函式移動到mousemove事件回呼中并按如下方式編輯:
function emptySquare(context) {
context.clearRect(0, 0, canvas.width, canvas.height)
}
所以它只會清除#myBoard畫布而#bg保持不變,而無需每次重新繪制它。
例子:
const bg = document.getElementById('bg')
const bgContext = bg.getContext('2d')
drawBoard(bgContext)
function getSquare(canvas, evt) {
var rect = canvas.getBoundingClientRect()
return {
x: 1 (evt.clientX - rect.left) - ((evt.clientX - rect.left) % 10),
y: 1 (evt.clientY - rect.top) - ((evt.clientY - rect.top) % 10),
}
}
function emptySquare(context) {
context.clearRect(0, 0, canvas.width, canvas.height)
}
function range(start, end) {
var ans = []
if (end > start) {
for (let i = start; i <= end; i = 10) {
ans.push(i)
}
} else {
for (let i = start; i >= end; i -= 10) {
ans.push(i)
}
}
return ans
}
function drawBoard(context) {
for (var x = 0.5; x < 20001; x = 10) {
context.moveTo(x, 0)
context.lineTo(x, 20000)
}
for (var y = 0.5; y < 20001; y = 10) {
context.moveTo(0, y)
context.lineTo(20000, y)
}
context.strokeStyle = '#ddd'
context.stroke()
}
function fillSquare(context, x, y) {
context.fillStyle = '#70B7B5'
context.fillRect(x, y, 9, 9)
}
var canvas = document.getElementById('myBoard')
var context = canvas.getContext('2d')
var isDrag = false
canvas.addEventListener('mousedown', function(evt) {
var mousePos = getSquare(canvas, evt)
isDrag = true
fillSquare(context, mousePos.x, mousePos.y)
previousPos = mousePos
}, false)
canvas.addEventListener('mousemove', function(evt) {
if (isDrag) {
var mousePos = getSquare(canvas, evt)
var x_dist = range(previousPos.x, mousePos.x)
var y_dist = range(previousPos.y, mousePos.y)
emptySquare(context)
for (x in x_dist) {
for (y in y_dist) {
fillSquare(context, x_dist[x], y_dist[y])
}
}
}
}, false)
canvas.addEventListener('mouseup', function(evt) {
if (isDrag) {
isDrag = false
}
}, false)
#bg {
position: absolute;
z-index: -1;
}
<div>
<canvas id="bg" width="1440" height="1200"></canvas>
<canvas id="myBoard" width="1440" height="1200"></canvas>
</div>
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/396439.html
標籤:javascript html 网络 拖 bootstrap-5
