Add a constant for the hit-detection resolution

This commit is contained in:
Maximilian Krög
2021-02-09 22:33:08 +01:00
parent 261bba8359
commit 5a7e4dfaf6
3 changed files with 27 additions and 23 deletions

View File

@@ -11,6 +11,8 @@ import {createCanvasContext2D} from '../../dom.js';
import {intersects} from '../../extent.js'; import {intersects} from '../../extent.js';
import {numberSafeCompareFunction} from '../../array.js'; import {numberSafeCompareFunction} from '../../array.js';
export const HIT_DETECT_RESOLUTION = 0.5;
/** /**
* @param {import("../../size.js").Size} size Canvas size in css pixels. * @param {import("../../size.js").Size} size Canvas size in css pixels.
* @param {Array<import("../../transform.js").Transform>} transforms Transforms * @param {Array<import("../../transform.js").Transform>} transforms Transforms
@@ -34,14 +36,14 @@ export function createHitDetectionImageData(
resolution, resolution,
rotation rotation
) { ) {
const width = size[0] / 2; const width = size[0] * HIT_DETECT_RESOLUTION;
const height = size[1] / 2; const height = size[1] * HIT_DETECT_RESOLUTION;
const context = createCanvasContext2D(width, height); const context = createCanvasContext2D(width, height);
context.imageSmoothingEnabled = false; context.imageSmoothingEnabled = false;
const canvas = context.canvas; const canvas = context.canvas;
const renderer = new CanvasImmediateRenderer( const renderer = new CanvasImmediateRenderer(
context, context,
0.5, HIT_DETECT_RESOLUTION,
extent, extent,
null, null,
rotation rotation
@@ -163,13 +165,14 @@ export function createHitDetectionImageData(
export function hitDetect(pixel, features, imageData) { export function hitDetect(pixel, features, imageData) {
const resultFeatures = []; const resultFeatures = [];
if (imageData) { if (imageData) {
const x = Math.floor(Math.round(pixel[0]) * HIT_DETECT_RESOLUTION);
const y = Math.floor(Math.round(pixel[1]) * HIT_DETECT_RESOLUTION);
// The pixel coordinate is clamped down to the hit-detect canvas' size to account // The pixel coordinate is clamped down to the hit-detect canvas' size to account
// for browsers returning coordinates slightly larger than the actual canvas size // for browsers returning coordinates slightly larger than the actual canvas size
// due to a non-integer pixel ratio. // due to a non-integer pixel ratio.
const index = const index =
(clamp(Math.floor(Math.round(pixel[0]) / 2), 0, imageData.width - 1) + (clamp(x, 0, imageData.width - 1) +
clamp(Math.floor(Math.round(pixel[1]) / 2), 0, imageData.height - 1) * clamp(y, 0, imageData.height - 1) * imageData.width) *
imageData.width) *
4; 4;
const r = imageData.data[index]; const r = imageData.data[index];
const g = imageData.data[index + 1]; const g = imageData.data[index + 1];

View File

@@ -5,6 +5,11 @@ import CanvasBuilderGroup from '../../render/canvas/BuilderGroup.js';
import CanvasLayerRenderer from './Layer.js'; import CanvasLayerRenderer from './Layer.js';
import ExecutorGroup from '../../render/canvas/ExecutorGroup.js'; import ExecutorGroup from '../../render/canvas/ExecutorGroup.js';
import ViewHint from '../../ViewHint.js'; import ViewHint from '../../ViewHint.js';
import {
HIT_DETECT_RESOLUTION,
createHitDetectionImageData,
hitDetect,
} from '../../render/canvas/hitdetect.js';
import { import {
apply, apply,
makeInverse, makeInverse,
@@ -19,10 +24,6 @@ import {
intersects as intersectsExtent, intersects as intersectsExtent,
wrapX as wrapExtentX, wrapX as wrapExtentX,
} from '../../extent.js'; } from '../../extent.js';
import {
createHitDetectionImageData,
hitDetect,
} from '../../render/canvas/hitdetect.js';
import { import {
defaultOrder as defaultRenderOrder, defaultOrder as defaultRenderOrder,
getTolerance as getRenderTolerance, getTolerance as getRenderTolerance,
@@ -325,14 +326,14 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
const extent = this.renderedExtent_; const extent = this.renderedExtent_;
const layer = this.getLayer(); const layer = this.getLayer();
const transforms = []; const transforms = [];
const width = size[0] / 2; const width = size[0] * HIT_DETECT_RESOLUTION;
const height = size[1] / 2; const height = size[1] * HIT_DETECT_RESOLUTION;
transforms.push( transforms.push(
this.getRenderTransform( this.getRenderTransform(
center, center,
resolution, resolution,
rotation, rotation,
0.5, HIT_DETECT_RESOLUTION,
width, width,
height, height,
0 0
@@ -357,7 +358,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
center, center,
resolution, resolution,
rotation, rotation,
0.5, HIT_DETECT_RESOLUTION,
width, width,
height, height,
offsetX offsetX
@@ -375,7 +376,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
center, center,
resolution, resolution,
rotation, rotation,
0.5, HIT_DETECT_RESOLUTION,
width, width,
height, height,
offsetX offsetX

View File

@@ -9,6 +9,11 @@ import ReplayType from '../../render/canvas/BuilderType.js';
import TileState from '../../TileState.js'; import TileState from '../../TileState.js';
import VectorTileRenderType from '../../layer/VectorTileRenderType.js'; import VectorTileRenderType from '../../layer/VectorTileRenderType.js';
import ViewHint from '../../ViewHint.js'; import ViewHint from '../../ViewHint.js';
import {
HIT_DETECT_RESOLUTION,
createHitDetectionImageData,
hitDetect,
} from '../../render/canvas/hitdetect.js';
import { import {
apply as applyTransform, apply as applyTransform,
create as createTransform, create as createTransform,
@@ -28,10 +33,6 @@ import {
intersects, intersects,
} from '../../extent.js'; } from '../../extent.js';
import {clear} from '../../obj.js'; import {clear} from '../../obj.js';
import {
createHitDetectionImageData,
hitDetect,
} from '../../render/canvas/hitdetect.js';
import { import {
getSquaredTolerance as getSquaredRenderTolerance, getSquaredTolerance as getSquaredRenderTolerance,
renderFeature, renderFeature,
@@ -549,16 +550,15 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
const tileSize = toSize( const tileSize = toSize(
tileGrid.getTileSize(tileGrid.getZForResolution(resolution)) tileGrid.getTileSize(tileGrid.getZForResolution(resolution))
); );
const size = [tileSize[0] / 2, tileSize[1] / 2];
const rotation = this.renderedRotation_; const rotation = this.renderedRotation_;
const transforms = [ const transforms = [
this.getRenderTransform( this.getRenderTransform(
tileGrid.getTileCoordCenter(tile.wrappedTileCoord), tileGrid.getTileCoordCenter(tile.wrappedTileCoord),
resolution, resolution,
0, 0,
0.5, HIT_DETECT_RESOLUTION,
size[0], tileSize[0] * HIT_DETECT_RESOLUTION,
size[1], tileSize[1] * HIT_DETECT_RESOLUTION,
0 0
), ),
]; ];