flow like the river
This commit is contained in:
commit
013fe673f3
42435 changed files with 5764238 additions and 0 deletions
21
VISUALIZACION/node_modules/canvas-color-tracker/LICENSE
generated
vendored
Executable file
21
VISUALIZACION/node_modules/canvas-color-tracker/LICENSE
generated
vendored
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 Vasco Asturiano
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
73
VISUALIZACION/node_modules/canvas-color-tracker/README.md
generated
vendored
Executable file
73
VISUALIZACION/node_modules/canvas-color-tracker/README.md
generated
vendored
Executable file
|
|
@ -0,0 +1,73 @@
|
|||
canvas-color-tracker
|
||||
====================
|
||||
|
||||
[![NPM package][npm-img]][npm-url]
|
||||
[![Build Size][build-size-img]][build-size-url]
|
||||
[![NPM Downloads][npm-downloads-img]][npm-downloads-url]
|
||||
|
||||
A utility to track objects on a canvas by unique px color.
|
||||
|
||||
When using HTML5 canvas to render elements, we don't have the convenience of readily available *mouseover* events per object, which makes interaction difficult.
|
||||
`canvas-color-tracker` provides a system for keeping track of objects in your canvas by indexing them by a unique color, which can be retrieved by determining the *1px* color that is directly under the mouse pointer.
|
||||
|
||||
This is generally done using a spare/shadow canvas which is not attached to the DOM, but is synchronyzed in terms of object positions with the main canvas. On this shadow canvas we render the objects filled with artificial unique colors that are keys to the object's data, so that by attaching *mousemove* events to the whole canvas we can determine which objects are being hovered on.
|
||||
|
||||
`canvas-color-tracker` is just the registry part of this process, which generates unique color keys per object and supports addition and retrieval of objects. It also includes a mechanism for validating the color keys using checksum encoding. This is necessary because of pixel antialiasing/smoothing on the boundary of canvas objects, leading into new color mutations which invalidate the object color key lookup.
|
||||
|
||||
Check out the canvas examples:
|
||||
* [100 objects](https://vasturiano.github.io/canvas-color-tracker/example/canvas-small.html) [[source](https://github.com/vasturiano/canvas-color-tracker/blob/master/example/canvas-small.html)]
|
||||
* [10k objects](https://vasturiano.github.io/canvas-color-tracker/example/canvas-medium.html) [[source](https://github.com/vasturiano/canvas-color-tracker/blob/master/example/canvas-medium.html)]
|
||||
* [1M objects](https://vasturiano.github.io/canvas-color-tracker/example/canvas-huge-1M.html)!! [[source](https://github.com/vasturiano/canvas-color-tracker/blob/master/example/canvas-huge-1M.html)] (please wait until render finishes)
|
||||
|
||||
## Quick start
|
||||
|
||||
```js
|
||||
import ColorTracker from 'canvas-color-tracker';
|
||||
```
|
||||
or using a *script* tag
|
||||
```html
|
||||
<script src="//unpkg.com/canvas-color-tracker"></script>
|
||||
```
|
||||
then
|
||||
```js
|
||||
const myTracker = new ColorTracker();
|
||||
|
||||
const myObject = { ... };
|
||||
const myObjectColor = myTracker.register(myObject);
|
||||
|
||||
// ...
|
||||
|
||||
const hoverColor = context.getImageData(x, y, 1, 1).data;
|
||||
const hoverObject = myTracker.lookup(hoverColor);
|
||||
```
|
||||
|
||||
## API reference
|
||||
|
||||
### Instantiation
|
||||
|
||||
new <b>ColorTracker</b>([<i>checksum_bits</i>])
|
||||
|
||||
Creates a new object registry.
|
||||
|
||||
The parameter `checkum_bits` defines how many bits should be used for storing the checksum of the colors. Higher values produce less chance of collisions introduced by anti-aliasing of pixels on object boundaries, which yield artificial erroneous colors. Each bit used for checksum eats away from the maximum size of the registry, as less bits are available for indexing objects. The maximum number of objects that can be stored in the registry is equal to `2^(24-checksum_bits) - 1` (one position is reserved for background). If not provided, `checksum_bits` takes the default of **6** bits, generating a registry of max size *~262k* objects. Normally, you'll only need to override `checksum_bits` if you wish to store more than this amount of objects.
|
||||
|
||||
### Methods
|
||||
|
||||
<b>register</b>(<i>object</i>)
|
||||
|
||||
Adds an object to the registry, and returns a unique color (hex string) that can be used to retrieve the object in the future. Object can be of any type, even primitive values. The color returned encodes the checksum, and will be checked for validity at retrieval time. In case the registry is full and has reached its limit of objects, a value of `null` is returned, indicating that the object was not stored.
|
||||
|
||||
<b>lookup</b>(<i>string</i> or <i>[r, g, b]</i>)
|
||||
|
||||
Retrieve an object from the registry by its unique color key. The color should be passed either as a plain string such as `#23a69c`, or an array of 3 octet numbers indicating the color's _r_, _g_, _b_ encoding. This array is the same format as returned by the canvas context `getImageData` method. If the color passes the checksum verification and has a registered object in the registry, it is returned. Otherwise the method returns `null`.
|
||||
|
||||
## Giving Back
|
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=L398E7PKP47E8¤cy_code=USD&source=url) If this project has helped you and you'd like to contribute back, you can always [buy me a ☕](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=L398E7PKP47E8¤cy_code=USD&source=url)!
|
||||
|
||||
[npm-img]: https://img.shields.io/npm/v/canvas-color-tracker
|
||||
[npm-url]: https://npmjs.org/package/canvas-color-tracker
|
||||
[build-size-img]: https://img.shields.io/bundlephobia/minzip/canvas-color-tracker
|
||||
[build-size-url]: https://bundlephobia.com/result?p=canvas-color-tracker
|
||||
[npm-downloads-img]: https://img.shields.io/npm/dt/canvas-color-tracker
|
||||
[npm-downloads-url]: https://www.npmtrends.com/canvas-color-tracker
|
||||
10
VISUALIZACION/node_modules/canvas-color-tracker/dist/canvas-color-tracker.d.ts
generated
vendored
Executable file
10
VISUALIZACION/node_modules/canvas-color-tracker/dist/canvas-color-tracker.d.ts
generated
vendored
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
type Obj = any;
|
||||
|
||||
declare class ColorTracker {
|
||||
constructor(bits?: number);
|
||||
|
||||
register(obj: Obj): string | null;
|
||||
lookup(color: string | [number, number, number]): Obj | null;
|
||||
}
|
||||
|
||||
export { ColorTracker as default };
|
||||
1308
VISUALIZACION/node_modules/canvas-color-tracker/dist/canvas-color-tracker.js
generated
vendored
Executable file
1308
VISUALIZACION/node_modules/canvas-color-tracker/dist/canvas-color-tracker.js
generated
vendored
Executable file
File diff suppressed because it is too large
Load diff
1
VISUALIZACION/node_modules/canvas-color-tracker/dist/canvas-color-tracker.js.map
generated
vendored
Executable file
1
VISUALIZACION/node_modules/canvas-color-tracker/dist/canvas-color-tracker.js.map
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
5
VISUALIZACION/node_modules/canvas-color-tracker/dist/canvas-color-tracker.min.js
generated
vendored
Executable file
5
VISUALIZACION/node_modules/canvas-color-tracker/dist/canvas-color-tracker.min.js
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
121
VISUALIZACION/node_modules/canvas-color-tracker/dist/canvas-color-tracker.mjs
generated
vendored
Executable file
121
VISUALIZACION/node_modules/canvas-color-tracker/dist/canvas-color-tracker.mjs
generated
vendored
Executable file
|
|
@ -0,0 +1,121 @@
|
|||
import tinyColor from 'tinycolor2';
|
||||
|
||||
function _classCallCheck(instance, Constructor) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
throw new TypeError("Cannot call a class as a function");
|
||||
}
|
||||
}
|
||||
function _defineProperties(target, props) {
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var descriptor = props[i];
|
||||
descriptor.enumerable = descriptor.enumerable || false;
|
||||
descriptor.configurable = true;
|
||||
if ("value" in descriptor) descriptor.writable = true;
|
||||
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
|
||||
}
|
||||
}
|
||||
function _createClass(Constructor, protoProps, staticProps) {
|
||||
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
||||
if (staticProps) _defineProperties(Constructor, staticProps);
|
||||
Object.defineProperty(Constructor, "prototype", {
|
||||
writable: false
|
||||
});
|
||||
return Constructor;
|
||||
}
|
||||
function _toConsumableArray(arr) {
|
||||
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
|
||||
}
|
||||
function _arrayWithoutHoles(arr) {
|
||||
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
|
||||
}
|
||||
function _iterableToArray(iter) {
|
||||
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
||||
}
|
||||
function _unsupportedIterableToArray(o, minLen) {
|
||||
if (!o) return;
|
||||
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
||||
var n = Object.prototype.toString.call(o).slice(8, -1);
|
||||
if (n === "Object" && o.constructor) n = o.constructor.name;
|
||||
if (n === "Map" || n === "Set") return Array.from(o);
|
||||
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
||||
}
|
||||
function _arrayLikeToArray(arr, len) {
|
||||
if (len == null || len > arr.length) len = arr.length;
|
||||
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
||||
return arr2;
|
||||
}
|
||||
function _nonIterableSpread() {
|
||||
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
||||
}
|
||||
function _toPrimitive(input, hint) {
|
||||
if (typeof input !== "object" || input === null) return input;
|
||||
var prim = input[Symbol.toPrimitive];
|
||||
if (prim !== undefined) {
|
||||
var res = prim.call(input, hint || "default");
|
||||
if (typeof res !== "object") return res;
|
||||
throw new TypeError("@@toPrimitive must return a primitive value.");
|
||||
}
|
||||
return (hint === "string" ? String : Number)(input);
|
||||
}
|
||||
function _toPropertyKey(arg) {
|
||||
var key = _toPrimitive(arg, "string");
|
||||
return typeof key === "symbol" ? key : String(key);
|
||||
}
|
||||
|
||||
var ENTROPY = 123; // Raise numbers to prevent collisions in lower indexes
|
||||
|
||||
var int2HexColor = function int2HexColor(num) {
|
||||
return "#".concat(Math.min(num, Math.pow(2, 24)).toString(16).padStart(6, '0'));
|
||||
};
|
||||
var rgb2Int = function rgb2Int(r, g, b) {
|
||||
return (r << 16) + (g << 8) + b;
|
||||
};
|
||||
var colorStr2Int = function colorStr2Int(str) {
|
||||
var _tinyColor$toRgb = tinyColor(str).toRgb(),
|
||||
r = _tinyColor$toRgb.r,
|
||||
g = _tinyColor$toRgb.g,
|
||||
b = _tinyColor$toRgb.b;
|
||||
return rgb2Int(r, g, b);
|
||||
};
|
||||
var checksum = function checksum(n, csBits) {
|
||||
return n * ENTROPY % Math.pow(2, csBits);
|
||||
};
|
||||
var _default = /*#__PURE__*/function () {
|
||||
function _default() {
|
||||
var csBits = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 6;
|
||||
_classCallCheck(this, _default);
|
||||
this.csBits = csBits; // How many bits to reserve for checksum. Will eat away into the usable size of the registry.
|
||||
this.registry = ['__reserved for background__']; // indexed objects for rgb lookup;
|
||||
}
|
||||
_createClass(_default, [{
|
||||
key: "register",
|
||||
value: function register(obj) {
|
||||
if (this.registry.length >= Math.pow(2, 24 - this.csBits)) {
|
||||
// color has 24 bits (-checksum)
|
||||
return null; // Registry is full
|
||||
}
|
||||
|
||||
var idx = this.registry.length;
|
||||
var cs = checksum(idx, this.csBits);
|
||||
var color = int2HexColor(idx + (cs << 24 - this.csBits));
|
||||
this.registry.push(obj);
|
||||
return color;
|
||||
}
|
||||
}, {
|
||||
key: "lookup",
|
||||
value: function lookup(color) {
|
||||
var n = typeof color === 'string' ? colorStr2Int(color) : rgb2Int.apply(void 0, _toConsumableArray(color));
|
||||
if (!n) return null; // 0 index is reserved for background
|
||||
|
||||
var idx = n & Math.pow(2, 24 - this.csBits) - 1; // registry index
|
||||
var cs = n >> 24 - this.csBits & Math.pow(2, this.csBits) - 1; // extract bits reserved for checksum
|
||||
|
||||
if (checksum(idx, this.csBits) !== cs || idx >= this.registry.length) return null; // failed checksum or registry out of bounds
|
||||
|
||||
return this.registry[idx];
|
||||
}
|
||||
}]);
|
||||
return _default;
|
||||
}();
|
||||
|
||||
export { _default as default };
|
||||
86
VISUALIZACION/node_modules/canvas-color-tracker/example/canvas-huge-1M.html
generated
vendored
Executable file
86
VISUALIZACION/node_modules/canvas-color-tracker/example/canvas-huge-1M.html
generated
vendored
Executable file
|
|
@ -0,0 +1,86 @@
|
|||
<head>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
#tooltip {
|
||||
position: absolute;
|
||||
transform: translate(-50%, 25px);
|
||||
font-family: Sans-serif;
|
||||
font-size: 12px;
|
||||
padding: 3px;
|
||||
border-radius: 3px;
|
||||
color: lavender;
|
||||
background: midnightblue;
|
||||
opacity: 0.7;
|
||||
visibility: hidden; /* by default */
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="//unpkg.com/canvas-color-tracker"></script>
|
||||
<!--<script src="../dist/canvas-color-tracker.js"></script>-->
|
||||
|
||||
<script src="circle-generator.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="my-canvas"></canvas>
|
||||
<div id="tooltip"></div>
|
||||
|
||||
<script>
|
||||
const NUM_CIRCLES = 1e6;
|
||||
|
||||
const colorTracker = new ColorTracker(4); // Reduce checksum to support 2^20 (~1M) objects
|
||||
|
||||
const tooltip = document.getElementById('tooltip');
|
||||
const canvas = document.getElementById('my-canvas');
|
||||
const shadowCanvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const shadowCtx = shadowCanvas.getContext('2d');
|
||||
|
||||
// size canvases
|
||||
[canvas, shadowCanvas].forEach(cv => {
|
||||
cv.width = window.innerWidth;
|
||||
cv.height = window.innerHeight;
|
||||
});
|
||||
|
||||
const circles = genCircles(canvas.width, canvas.height, NUM_CIRCLES);
|
||||
|
||||
circles.forEach(circle => {
|
||||
// Render in main canvas
|
||||
ctx.beginPath();
|
||||
ctx.arc(circle.x, circle.y, circle.r, 0, 2 * Math.PI, false);
|
||||
ctx.fillStyle = 'rgba(197, 42, 27, 0.6)';
|
||||
ctx.fill();
|
||||
|
||||
// Register in colorTracker
|
||||
const shadowColor = colorTracker.register(circle);
|
||||
|
||||
if (!shadowColor) return; // registry is full
|
||||
|
||||
// Paint in shadow canvas (not bound to DOM)
|
||||
shadowCtx.beginPath();
|
||||
shadowCtx.arc(circle.x, circle.y, circle.r, 0, 2 * Math.PI, false);
|
||||
shadowCtx.fillStyle = shadowColor;
|
||||
shadowCtx.fill();
|
||||
});
|
||||
|
||||
canvas.addEventListener('mousemove', ev => {
|
||||
const mousePos = { offsetX: x, offsetY: y } = ev;
|
||||
|
||||
// Move tooltip
|
||||
tooltip.style.left = `${mousePos.x}px`;
|
||||
tooltip.style.top = `${mousePos.y}px`;
|
||||
|
||||
// Get px color of mouse position from shadow canvas
|
||||
const pxColor = shadowCtx.getImageData(mousePos.x, mousePos.y, 1, 1).data;
|
||||
// Retrieve original object by px color
|
||||
const hoverObj = colorTracker.lookup(pxColor);
|
||||
|
||||
tooltip.style.visibility = hoverObj ? 'visible' : 'hidden';
|
||||
tooltip.innerHTML = hoverObj
|
||||
? `Circle id: ${hoverObj.id}<br>Center: ${hoverObj.x},${hoverObj.y}<br>Radius: ${hoverObj.r}`
|
||||
: ''; // no object found
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
86
VISUALIZACION/node_modules/canvas-color-tracker/example/canvas-medium.html
generated
vendored
Executable file
86
VISUALIZACION/node_modules/canvas-color-tracker/example/canvas-medium.html
generated
vendored
Executable file
|
|
@ -0,0 +1,86 @@
|
|||
<head>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
#tooltip {
|
||||
position: absolute;
|
||||
transform: translate(-50%, 25px);
|
||||
font-family: Sans-serif;
|
||||
font-size: 12px;
|
||||
padding: 3px;
|
||||
border-radius: 3px;
|
||||
color: lavender;
|
||||
background: midnightblue;
|
||||
opacity: 0.7;
|
||||
visibility: hidden; /* by default */
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="//unpkg.com/canvas-color-tracker"></script>
|
||||
<!--<script src="../dist/canvas-color-tracker.js"></script>-->
|
||||
|
||||
<script src="circle-generator.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="my-canvas"></canvas>
|
||||
<div id="tooltip"></div>
|
||||
|
||||
<script>
|
||||
const NUM_CIRCLES = 1e4;
|
||||
|
||||
const colorTracker = new ColorTracker();
|
||||
|
||||
const tooltip = document.getElementById('tooltip');
|
||||
const canvas = document.getElementById('my-canvas');
|
||||
const shadowCanvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const shadowCtx = shadowCanvas.getContext('2d');
|
||||
|
||||
// size canvases
|
||||
[canvas, shadowCanvas].forEach(cv => {
|
||||
cv.width = window.innerWidth;
|
||||
cv.height = window.innerHeight;
|
||||
});
|
||||
|
||||
const circles = genCircles(canvas.width, canvas.height, NUM_CIRCLES);
|
||||
|
||||
circles.forEach(circle => {
|
||||
// Render in main canvas
|
||||
ctx.beginPath();
|
||||
ctx.arc(circle.x, circle.y, circle.r, 0, 2 * Math.PI, false);
|
||||
ctx.fillStyle = 'rgba(197, 42, 27, 0.6)';
|
||||
ctx.fill();
|
||||
|
||||
// Register in colorTracker
|
||||
const shadowColor = colorTracker.register(circle);
|
||||
|
||||
if (!shadowColor) return; // registry is full
|
||||
|
||||
// Paint in shadow canvas (not bound to DOM)
|
||||
shadowCtx.beginPath();
|
||||
shadowCtx.arc(circle.x, circle.y, circle.r, 0, 2 * Math.PI, false);
|
||||
shadowCtx.fillStyle = shadowColor;
|
||||
shadowCtx.fill();
|
||||
});
|
||||
|
||||
canvas.addEventListener('mousemove', ev => {
|
||||
const mousePos = { offsetX: x, offsetY: y } = ev;
|
||||
|
||||
// Move tooltip
|
||||
tooltip.style.left = `${mousePos.x}px`;
|
||||
tooltip.style.top = `${mousePos.y}px`;
|
||||
|
||||
// Get px color of mouse position from shadow canvas
|
||||
const pxColor = shadowCtx.getImageData(mousePos.x, mousePos.y, 1, 1).data;
|
||||
// Retrieve original object by px color
|
||||
const hoverObj = colorTracker.lookup(pxColor);
|
||||
|
||||
tooltip.style.visibility = hoverObj ? 'visible' : 'hidden';
|
||||
tooltip.innerHTML = hoverObj
|
||||
? `Circle id: ${hoverObj.id}<br>Center: ${hoverObj.x},${hoverObj.y}<br>Radius: ${hoverObj.r}`
|
||||
: ''; // no object found
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
86
VISUALIZACION/node_modules/canvas-color-tracker/example/canvas-small.html
generated
vendored
Executable file
86
VISUALIZACION/node_modules/canvas-color-tracker/example/canvas-small.html
generated
vendored
Executable file
|
|
@ -0,0 +1,86 @@
|
|||
<head>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
#tooltip {
|
||||
position: absolute;
|
||||
transform: translate(-50%, 25px);
|
||||
font-family: Sans-serif;
|
||||
font-size: 12px;
|
||||
padding: 3px;
|
||||
border-radius: 3px;
|
||||
color: lavender;
|
||||
background: midnightblue;
|
||||
opacity: 0.7;
|
||||
visibility: hidden; /* by default */
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="//unpkg.com/canvas-color-tracker"></script>
|
||||
<!--<script src="../dist/canvas-color-tracker.js"></script>-->
|
||||
|
||||
<script src="circle-generator.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="my-canvas"></canvas>
|
||||
<div id="tooltip"></div>
|
||||
|
||||
<script>
|
||||
const NUM_CIRCLES = 1e2;
|
||||
|
||||
const colorTracker = new ColorTracker();
|
||||
|
||||
const tooltip = document.getElementById('tooltip');
|
||||
const canvas = document.getElementById('my-canvas');
|
||||
const shadowCanvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const shadowCtx = shadowCanvas.getContext('2d');
|
||||
|
||||
// size canvases
|
||||
[canvas, shadowCanvas].forEach(cv => {
|
||||
cv.width = window.innerWidth;
|
||||
cv.height = window.innerHeight;
|
||||
});
|
||||
|
||||
const circles = genCircles(canvas.width, canvas.height, NUM_CIRCLES);
|
||||
|
||||
circles.forEach(circle => {
|
||||
// Render in main canvas
|
||||
ctx.beginPath();
|
||||
ctx.arc(circle.x, circle.y, circle.r, 0, 2 * Math.PI, false);
|
||||
ctx.fillStyle = 'rgba(197, 42, 27, 0.6)';
|
||||
ctx.fill();
|
||||
|
||||
// Register in colorTracker
|
||||
const shadowColor = colorTracker.register(circle);
|
||||
|
||||
if (!shadowColor) return; // registry is full
|
||||
|
||||
// Paint in shadow canvas (not bound to DOM)
|
||||
shadowCtx.beginPath();
|
||||
shadowCtx.arc(circle.x, circle.y, circle.r, 0, 2 * Math.PI, false);
|
||||
shadowCtx.fillStyle = shadowColor;
|
||||
shadowCtx.fill();
|
||||
});
|
||||
|
||||
canvas.addEventListener('mousemove', ev => {
|
||||
const mousePos = { offsetX: x, offsetY: y } = ev;
|
||||
|
||||
// Move tooltip
|
||||
tooltip.style.left = `${mousePos.x}px`;
|
||||
tooltip.style.top = `${mousePos.y}px`;
|
||||
|
||||
// Get px color of mouse position from shadow canvas
|
||||
const pxColor = shadowCtx.getImageData(mousePos.x, mousePos.y, 1, 1).data;
|
||||
// Retrieve original object by px color
|
||||
const hoverObj = colorTracker.lookup(pxColor);
|
||||
|
||||
tooltip.style.visibility = hoverObj ? 'visible' : 'hidden';
|
||||
tooltip.innerHTML = hoverObj
|
||||
? `Circle id: ${hoverObj.id}<br>Center: ${hoverObj.x},${hoverObj.y}<br>Radius: ${hoverObj.r}`
|
||||
: ''; // no object found
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
12
VISUALIZACION/node_modules/canvas-color-tracker/example/circle-generator.js
generated
vendored
Executable file
12
VISUALIZACION/node_modules/canvas-color-tracker/example/circle-generator.js
generated
vendored
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
// Generate random circles
|
||||
function genCircles(width, height, N = 500) {
|
||||
const minR = 1;
|
||||
const maxR = Math.sqrt(width * height / N) * 0.5;
|
||||
|
||||
return [...Array(N)].map((_, idx) => ({
|
||||
id: idx,
|
||||
x: Math.round(Math.random() * width),
|
||||
y: Math.round(Math.random() * height),
|
||||
r: Math.max(minR, Math.round(Math.random() * maxR))
|
||||
}));
|
||||
}
|
||||
63
VISUALIZACION/node_modules/canvas-color-tracker/package.json
generated
vendored
Executable file
63
VISUALIZACION/node_modules/canvas-color-tracker/package.json
generated
vendored
Executable file
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "canvas-color-tracker",
|
||||
"version": "1.2.1",
|
||||
"description": "A utility to track objects on a canvas by unique px color",
|
||||
"type": "module",
|
||||
"unpkg": "dist/canvas-color-tracker.min.js",
|
||||
"main": "dist/canvas-color-tracker.mjs",
|
||||
"module": "dist/canvas-color-tracker.mjs",
|
||||
"types": "dist/canvas-color-tracker.d.ts",
|
||||
"exports": {
|
||||
"umd": "./dist/canvas-color-tracker.min.js",
|
||||
"default": "./dist/canvas-color-tracker.mjs"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/vasturiano/canvas-color-tracker.git"
|
||||
},
|
||||
"keywords": [
|
||||
"canvas",
|
||||
"color",
|
||||
"tracker",
|
||||
"interaction",
|
||||
"hover",
|
||||
"hidden"
|
||||
],
|
||||
"author": {
|
||||
"name": "Vasco Asturiano",
|
||||
"url": "https://github.com/vasturiano"
|
||||
},
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vasturiano/canvas-color-tracker/issues"
|
||||
},
|
||||
"homepage": "https://github.com/vasturiano/canvas-color-tracker",
|
||||
"files": [
|
||||
"dist/**/*",
|
||||
"example/**/*"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "rimraf dist && rollup -c",
|
||||
"dev": "rollup -w -c",
|
||||
"prepare": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"tinycolor2": "^1.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.12",
|
||||
"@babel/preset-env": "^7.20.2",
|
||||
"@rollup/plugin-babel": "^6.0.3",
|
||||
"@rollup/plugin-commonjs": "^24.0.1",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@rollup/plugin-terser": "^0.4.0",
|
||||
"rimraf": "^4.1.2",
|
||||
"rollup": "^3.14.0",
|
||||
"rollup-plugin-dts": "^5.1.1",
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue