当它以 ionic 连接时,我试图在线条之间填充颜色。当四线相互接触时,我想在线之间填充颜色。为此,我使用触摸事件创建了一个 Canvas 演示。请帮助解决我的问题。
我们在 Canvas 框中有 4 条线,我们将拖动它们并连接每条线并给出一个形状线框。这意味着我们的线已连接,现在在线之间填充颜色,因此框被颜色填充。
html file:
<canvas #canvasDraw width="300" height="300" (touchstart)="handleTouchStart($event)"
(touchmove)="handleTouchmove($event)"
(touchend)="handleTouchEnd($event)">
You need a browser that supports HTML5!
</canvas>
ts file:
import { Component, ElementRef, ViewChild } from '@angular/core';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
@ViewChild('canvasDraw', { static: false }) canvas: ElementRef;
canvasElement: any;
lines: any[];
isDown: boolean = false;
startX: number;
startY: number;
nearest: any;
offsetX: any;
offsetY: any;
constructor() {
}
ngAfterViewInit() {
this.canvasElement = this.canvas.nativeElement;
this.lines = [];
this.lines.push({ x0: 75, y0: 25, x1: 125, y1: 25 });
this.lines.push({ x0: 75, y0: 100, x1: 125, y1: 100 });
this.lines.push({ x0: 50, y0: 35, x1: 50, y1: 85 });
this.lines.push({ x0: 150, y0: 35, x1: 150, y1: 85 });
this.draw();
//this.reOffset();
requestAnimationFrame(() => {
this.reOffset()
})
}
reOffset() {
let BB = this.canvasElement.getBoundingClientRect();
this.offsetX = BB.left;
this.offsetY = BB.top;
}
// select the this.nearest line to the mouse
closestLine(mx, my) {
let dist = 100000000;
let index, pt;
for (let i = 0; i < this.lines.length; i++) {
//
let xy = this.closestXY(this.lines[i], mx, my);
//
let dx = mx - xy.x;
let dy = my - xy.y;
let thisDist = dx * dx + dy * dy;
if (thisDist < dist) {
dist = thisDist;
pt = xy;
index = i;
}
}
let line = this.lines[index];
return ({ pt: pt, line: line, originalLine: { x0: line.x0, y0: line.y0, x1: line.x1, y1: line.y1 } });
}
// linear interpolation -- needed in setClosestLine()
lerp(a, b, x) {
return (a + x * (b - a));
}
// find closest XY on line to mouse XY
closestXY(line, mx, my) {
let x0 = line.x0;
let y0 = line.y0;
let x1 = line.x1;
let y1 = line.y1;
let dx = x1 - x0;
let dy = y1 - y0;
let t = ((mx - x0) * dx + (my - y0) * dy) / (dx * dx + dy * dy);
t = Math.max(0, Math.min(1, t));
let x = this.lerp(x0, x1, t);
let y = this.lerp(y0, y1, t);
return ({ x: x, y: y });
}
// draw the scene
draw() {
let ctx = this.canvasElement.getContext('2d');
let cw = this.canvasElement.width;
let ch = this.canvasElement.height;
ctx.clearRect(0, 0, cw, ch);
// draw all lines at their current positions
for (let i = 0; i < this.lines.length; i++) {
this.drawLine(this.lines[i], 'black');
}
// draw markers if a line is being dragged
if (this.nearest) {
// point on line this.nearest to mouse
ctx.beginPath();
ctx.arc(this.nearest.pt.x, this.nearest.pt.y, 5, 0, Math.PI * 2);
ctx.strokeStyle = 'red';
ctx.stroke();
// marker for original line before dragging
this.drawLine(this.nearest.originalLine, 'red');
// hightlight the line as its dragged
this.drawLine(this.nearest.line, 'red');
}
}
drawLine(line, color) {
let ctx = this.canvasElement.getContext('2d');
ctx.beginPath();
ctx.moveTo(line.x0, line.y0);
ctx.lineTo(line.x1, line.y1);
ctx.strokeStyle = color;
ctx.stroke();
}
handleTouchStart(e) {
// tell the browser we're handling this event
let tch = e.touches[0];
// tch.preventDefault();
// tch.stopPropagation();
// mouse position
this.startX = tch.clientX - this.offsetX;
this.startY = tch.clientY - this.offsetY;
// find this.nearest line to mouse
this.nearest = this.closestLine(this.startX, this.startY);
this.draw();
// set dragging flag
this.isDown = true;
}
handleTouchEnd(e) {
// tell the browser we're handling this event
let tch = e.touches[0];
// tch.preventDefault();
// tch.stopPropagation();
// clear dragging flag
this.isDown = false;
this.nearest = null;
this.draw();
}
handleTouchmove(e) {
if (!this.isDown) { return; }
// tell the browser we're handling this event
let tch = e.touches[0];
// tch.preventDefault();
// tch.stopPropagation();
// mouse position
const mouseX = tch.clientX - this.offsetX;
const mouseY = tch.clientY - this.offsetY;
// calc how far mouse has moved since last mousemove event
let dx = mouseX - this.startX;
let dy = mouseY - this.startY;
this.startX = mouseX;
this.startY = mouseY;
// change this.nearest line vertices by distance moved
let line = this.nearest.line;
line.x0 += dx;
line.y0 += dy;
line.x1 += dx;
line.y1 += dy;
// redraw
this.draw();
let ctx = this.canvasElement.getContext('2d');
ctx.beginPath();
ctx.rect(line.x0, line.y0, line.x1, line.y1);
ctx.fillStyle = "red";
ctx.fill();
}
}
四线接触或连接时如何填充颜色?
最佳答案
如何获取像素的颜色
基本上,当您进行触摸事件时,像素会改变颜色。您可以找出事件影响了哪些像素。将像素作为输入,您可以找出像素的颜色:https://jsfiddle.net/ourcodeworld/8swevoxo/
var canvas = document.getElementById("canvas");
function getPosition(obj) {
var curleft = 0, curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return { x: curleft, y: curtop };
}
return undefined;
}
function rgbToHex(r, g, b) {
if (r > 255 || g > 255 || b > 255)
throw "Invalid color component";
return ((r << 16) | (g << 8) | b).toString(16);
}
function drawImageFromWebUrl(sourceurl){
var img = new Image();
img.addEventListener("load", function () {
// The image can be drawn from any source
canvas.getContext("2d").drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
});
img.setAttribute("src", sourceurl);
}
// Draw a base64 image because this is a fiddle, and if we try with an image from URL we'll get tainted canvas error
// Read more about here : http://ourcodeworld.com/articles/read/182/the-canvas-has-been-tainted-by-cross-origin-data-and-tainted-canvases-may-not-be-exported
drawImageFromWebUrl("data:image/gif;base64,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");
canvas.addEventListener("mousemove",function(e){
var pos = getPosition(this);
var x = e.pageX - pos.x;
var y = e.pageY - pos.y;
var coord = "x=" + x + ", y=" + y;
var c = this.getContext('2d');
var p = c.getImageData(x, y, 1, 1).data;
// If transparency on the image
if((p[0] == 0) && (p[1] == 0) && (p[2] == 0) && (p[3] == 0)){
coord += " (Transparent color detected, cannot be converted to HEX)";
}
var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
document.getElementById("status").innerHTML = coord;
document.getElementById("color").style.backgroundColor = hex;
},false);
<canvas id="canvas" width="150" height="150"></canvas>
<div id="status"></div><br>
<div id="color" style="width:30px;height:30px;"></div>
<p>
Move the mouse over the BUS !
</p>
这段代码不是我写的。
理解问题
既然我们知道如何逐个像素地获取颜色,我们需要将我们的问题转换为等价的东西,但它更容易计算。我将问题定义如下:
Traverse pixels starting from a given point in a continuous manner in order to find out whether a cycle can be formed, which contains pixels of a certain (default) color inside the boundary, which should change their color to some fill color.
如何解决
关于javascript - 当它在 Canvas 中连接时,如何在 4 行之间填充颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64554645/