Такой вопрос: допустим у нас есть некоторая локация, в которой сможет передвигаться игрок, она большая, но заранее известно, какие объекты в каких местах на ней находятся. Есть игрок, мы видим вокруг игрока в определенном радиусе, а то что за радиусом видимости мы не видим. Вопрос в том, как это реализовать на canvas. До этого, как я раньше делал, все видимые объекты сразу же рисовались на видимом поле.
Простейший способ - считать bounding box
объекта и перед отрисовкой проверять попал ли он на экран, попробуйте поиграть с количеством точек в этом примере, чтобы найти предел производительности Вашего компьютера, тогда можно будет понять как эта оптимизация влияет на производительность
var width, height;
var canvas = d3.select("canvas").call(d3.zoom().on("zoom", zoom));
resize();
var context = canvas.node().getContext("2d");
var randomX = d3.randomNormal(width / 2, 80);
var randomY = d3.randomNormal(height / 2, 80);
var data = d3.range(1e4).map(function() {
return [randomX(), randomY()];
});
let r1 = 1;
var transform = {x:0, y:0, k:1};
draw();
function zoom() {
transform = d3.event.transform;
context.save();
context.clearRect(0, 0, width, height);
context.translate(transform.x, transform.y);
context.scale(transform.k, transform.k);
draw();
context.restore();
}
function draw() {
var i = -1, n = data.length, d, c=0;
context.beginPath();
let rect = visibleRect();
context.beginPath()
context.fillStyle = 'red';
while (++i < n) {
d = data[i];
if (inScreen(d, rect)) {
c++;
context.moveTo(d[0], d[1]);
context.arc(d[0], d[1], r1, 0, 2 * Math.PI);
}
}
context.fill();
log.textContent = 'кругов нарисовано: ' + c + ', используйте drag и wheel'
}
function resize() {
width = canvas.node().width = window.innerWidth;
height = canvas.node().height = window.innerHeight-22;
}
function visibleRect() {
let pad = 50;
let x = transform.x-pad,
y = transform.y-pad,
k = transform.k,
w = width-pad*2,
h = height-pad*2;
context.beginPath()
context.fillStyle = 'rgba(0,0,0,0.1)';
context.rect(-x/k, -y/k, w/k, h/k);
context.fill();
return [-x/k, -y/k, w/k-x/k, h/k-y/k]
}
function inScreen(d, r) {
return d[0] > r[0]-r1 && d[1] > r[1]-r1 && d[0]<r[2]+r1 && d[1]<r[3]+r1
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<body style="margin:0;overflow:hidden">
<canvas></canvas>
<div id="log"></div>
</body>
Недостаток такого подхода - перебор всех элементов, чтобы этого избежать придется использовать структуры данных - например квадродерево
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Подскажите пожалуйста каким образом можно сделать такой семи круг с пунктами?
Итак, всем привет, возникли сложности в разработке системы лайков, видимо что-то недопонимаюВот моя модель постов
Я пытаюсь добавить событие click на div, который находится внутри a, Я не хочу, чтобы событие a href срабатывало при запуске события щелчка