Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/453.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何创建低内存消耗的快照到网格画布系统HTML+;JS?_Javascript_Html_Css_Canvas - Fatal编程技术网

Javascript 如何创建低内存消耗的快照到网格画布系统HTML+;JS?

Javascript 如何创建低内存消耗的快照到网格画布系统HTML+;JS?,javascript,html,css,canvas,Javascript,Html,Css,Canvas,我试图做的(我已经能够完成,但性能很差)是在画布上应用一种网格,以便能够从用户那里获取关于原点位置的输入。收到输入后,通过键盘提供“绘制”坐标 这几天我所做的就是计算画布的宽度和高度,然后除以一个标准的20x20正方形的面积(用px表示)。通过这种方式,我可以在结果上循环并创建n个正方形,我将在网格元素内的display flex中渲染这些正方形。然后这个网格元素被应用到画布上 一切正常,但是有很多div,如果用户选择将div缩小到10x10,那么,这将对性能产生很大影响。。。所以我想找到一个更

我试图做的(我已经能够完成,但性能很差)是在画布上应用一种网格,以便能够从用户那里获取关于原点位置的输入。收到输入后,通过键盘提供“绘制”坐标

这几天我所做的就是计算画布的宽度和高度,然后除以一个标准的20x20正方形的面积(用px表示)。通过这种方式,我可以在结果上循环并创建n个正方形,我将在网格元素内的display flex中渲染这些正方形。然后这个网格元素被应用到画布上

一切正常,但是有很多div,如果用户选择将div缩小到10x10,那么,这将对性能产生很大影响。。。所以我想找到一个更轻松的方法来做这件事

我考虑过在两个div中使用HR元素,这两个div将应用于画布上。一个div在列中显示元素,另一个在行中显示元素。这样我应该获得网格,但是快照呢?我如何检测两个HR元素的交点,并使用该确切点作为位置

我无法在画布上直接绘制网格的原因是,这应该尽可能保持“纯净”。仅包含用户的最终绘图

以下是“非优化”代码: 我使用Angular 5作为框架

<div class="draw-zone" #drawZone>
    <div class="grid" #grid [ngClass]="{'activated': activateDrawZones}">
        <div *ngFor="let block of gridBlocks" class="grid-block" [ngClass]="{'show': showGrid, 'ten-x-ten': blockSize === 10, 'twe-x-twe': blockSize === 20, 'thr-x-thr': blockSize === 30, 'fou-x-fou': blockSize === 40}"
            #gridBlock (click)="draw($event, gridBlock)"></div>
    </div>
    <canvas #canvas [height]="canvasSize.y" [width]="canvasSize.x"></canvas>
</div>
将组件方法用于校准:
如您所见,我正在画布元素上应用“.grid”元素。网格元素包含以灵活模式显示的所有块。如您所见,网格容器具有display:flex和flex wrap:wrap属性。这样,当用户在块上单击时,我可以通过获取其相对于父块的位置来猜测x,y坐标。与画布具有相同的尺寸。一旦有了x,y坐标,我就可以在画布上画图了。

是的,创建大量DOM元素并尝试使用javascript动态定位和调整它们的大小不会特别有效。我认为
hr
元素不会为您解决这个问题

首先,您是否考虑过直接在画布上绘制网格

另一个选择是在画布后面有一个背景图像,上面有网格。这将自动调整大小,性能与网页的任何其他方面一样


现在是“捕捉”部分。看起来您已经知道了如何在画布上绘制所需内容,一旦您获得了所需的网格信息。您需要的是一个方法来获取用户单击的网格。我猜这就是为什么你要覆盖所有的div

相反,画布本机跟踪鼠标单击。使用一些列出的技术应该能够获得您正在寻找的网格交互信息


编辑:生成和查找网格的方法:

var高度=100;
var宽度=200;
var水平网格=8;
垂直网格=4;
函数边界网格(长度、网格、x){
var部门=[];
可变网格宽度=长度/网格;
对于(i=0;i x){
分区推送((i-1)*网格宽度);
分区。推送(i*网格宽度);
打破
}
否则如果(i*网格宽度==x){
分区。推送(i*网格宽度);
打破
}
}
否则{
分区。推送(i*网格宽度);
}
}
返回分区;
}
log(“获取所有x和y网格线位置”);
console.log(边界网格(宽度、水平网格));
控制台日志(边界网格1d(高度、垂直网格));
log(“获取坐标(60,30)周围的x和y网格线位置”);
console.log(边界网格1d(宽度,水平网格,60));

控制台日志(边界网格1d(高度,垂直网格,30))一些代码对于理解您要做的事情很有用。另外,您所说的“在网格元素内的display flex中渲染”是什么意思?渲染的确切含义是什么?你只是想画网格线吗?有什么原因不能直接在画布上绘制它吗?对不起,我已经试着更好地解释了,还提供了一些代码:)正如你所说,我正在尝试绘制一个网格,我可以在用户光标单击时使用它来“捕捉”用户光标。然后使用单击的块数据计算相对于父对象的x、y坐标。然后在画布上画画。正如我在编辑中所说的,画布应该尽可能保持干净。那么除了检查div是否被单击之外,您对div做了其他任何事情吗?您也可以在画布上添加一个单击侦听器,并使用一些基本的数学计算所需的位置,而无需重新填充div。感谢您的建议,我已经在阅读:)我有一个问题,让我们假设在画布上绘制此网格,并将绘制坐标保留在一个单独的对象中。然后,我可以使用该网格来检测对每个单独的“网格正方形”的点击,我倾向于动态生成我的坐标。然后我可以动态地确定需要多少网格。编写函数应该很容易,因为它可以返回坐标序列,或者返回给定坐标的最近网格坐标。让我在回答中给你举个例子。。。
.draw-zone{
    flex-grow: 2;   
    height: 100%;
    position: relative;

    canvas{
        z-index: 10;
    }

    .grid{
        top: 0;
        left: 0;
        z-index: 11;
        width: 100%;
        display: flex;
        flex-wrap: wrap;
        overflow: hidden;
        position: absolute;
        margin-left: -.1rem;
        border-radius: .5rem;
        align-content: stretch;
        border: 1px solid transparent;

        &.activated{
            border-color: #3f51b5;
        }

        .grid-block{
            opacity: 0;
            border-right: 1px solid #3f51b5;
            border-bottom: 1px solid #3f51b5;

            &.show{
                opacity: .1;
            }

            &:hover{
                opacity: 1;
                border-radius: 50%;
                background-color: #3f51b5;
                transform: scale(1.2);
            }

            &.ten-x-ten{
                width: 10px;
                height: 10px;
            }
            &.twe-x-twe{
                width: 20px;
                height: 20px;
            }
            &.thr-x-thr{
                width: 30px;
                height: 30px;
            }
            &.fou-x-fou{
                width: 40px;
                height: 40px;
            }
        }
    }
private calculateGrid() {
    this.activateDrawZones = false;

    this.canvasSize.x = this._drawZone.nativeElement.clientWidth;
    this.canvasSize.y = this._drawZone.nativeElement.clientHeight;
    const blocksCount = (this.canvasSize.x * this.canvasSize.y) / (this.blockSize * this.blockSize);

    this.gridBlocks = [];
    for (let i = 0; i < blocksCount; i++) {
        this.gridBlocks.push({ size: this.blockSize });
    }

    this.activateDrawZones = true;
}
public draw(e: MouseEvent, block: HTMLDivElement, returnOnFail?: boolean) {
    const x = block.offsetLeft + (this.blockSize / 2);
    const y = block.offsetTop + (this.blockSize / 2);

    if (this.firstClick) {
        this.ctx.beginPath();
        this.ctx.moveTo(x, y);
        this.setCrosshair(x, y);
        this.firstClick = false;
        this.addPathToDrawSequence(x, y);
        return;
    }

    if (this.isNotOnTheSameAxisAsTheLastInsert(x, y)) {
        if (returnOnFail) { return; }

        this.toggleDrawDirection();
        this.draw(e, block, true);
        return;
    }

    this.ctx.lineTo(x, y);

    this.ctx.stroke();
    this.setCrosshair(x, y);
    this.addPathToDrawSequence(x, y);
}