0 / 0 / 0
Регистрация: 01.08.2018
Сообщений: 14
1

Аналог z-index для канваса

13.12.2018, 21:25. Показов 5271. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здраствуйте, каким образом можно регулировать слои канваса? Я знаю, что тот что отрисуешь раньше элемент, тот и будет "сзади", а вот можно ли где то дернуть свойство, чтобы просто написать -9999 и оно было что-то типа всегда на самом бэке. Типа как z-index
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.12.2018, 21:25
Ответы с готовыми решениями:

Ресайз канваса
Столкнулся с такой проблемой: Загружаю в канвас изображение; Теперь, если задавать ширину/высоту...

Три файла,(index.coo, index.doc, index.lex) а что за БД не знаю
Мне дали файловую БД(о-очень много файлов) и три файла: index.coo, index.doc и index.lex. ни doc,...

index.html на index.aspx (index.php...)
Вот, собственно, мучаясь с проблемой вылета сайта из топа 1000 (до этого было более 10 топовых (#1)...

Очистка канваса в матплотлиб
Добрый вечер, форумчане!Подскажите,пожалуйста, как можно очистить (обновить) канвас в матплоте...

4
the hardway first
Эксперт JS
2461 / 1836 / 906
Регистрация: 05.06.2015
Сообщений: 3,603
14.12.2018, 08:29 2
Лучший ответ Сообщение было отмечено 8Observer8 как решение

Решение

Цитата Сообщение от NoobFindAnswer Посмотреть сообщение
а вот можно ли где то дернуть свойство
Нет
0
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
18.12.2018, 00:48 3
Цитата Сообщение от NoobFindAnswer Посмотреть сообщение
Типа как z-index
Я всегда рисую в "2d" на <canvas> в контексте "webgl" в ортографической проекции. На WebGL больше возможностей для работы с графикой. В WebGL для объектов есть координата "z", с помощью которой можно расположить объекты по слоям. Но при этом нужно включить проверку глубины:
Javascript
1
gl.enable(gl.DEPTH_TEST);
И вместе с очисткой экрана (буфера цвета) вызывать очистку буфера глубины:
Javascript
1
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
Немного более подробнее об ортографической проекции можно почитать здесь: learnopengl. Урок 1.8 — Системы координат. Я изучаю оригинал тутора на английском: https://learnopengl.com Лучше начать с книги: WebGL. Программирование трехмерной графики

Я сделал пример с двумя треугольниками. В файле Scene помощью координаты "z" можно задавать какой треугольник будет поверх какого.

Песочница: https://plnkr.co/edit/mLvqt6w6... ?p=preview

Исходники

Команды для консоли:
npm install
tsc
http-server
index.html
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Z-coord. Triangles</title>
    <script data-main="RequireConfig" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
</head>
 
<body>
    <canvas id="renderCanvas" width="256" height="256"></canvas>
 
    <script type="x-shader/x-vertex" id="VertexShader">
        attribute vec3 aPosition;
        uniform mat4 uModelMatrix;
        
        void main()
        {
            gl_Position = uModelMatrix * vec4(aPosition, 1.0);
        }
    </script>
 
    <script type="x-shader/x-fragment" id="FragmentShader">
        precision mediump float;
 
        uniform vec3 uColor;
 
        void main()
        {
            gl_FragColor = vec4(uColor, 1.0);
        }
    </script>
</body>
 
</html>
package.json
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
    "name": "z-coord-triangles",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "@types/gl-matrix": "^2.4.4",
        "@types/requirejs": "^2.1.31"
    }
}
Program.ts
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
// Playground: https://plnkr.co/edit/mLvqt6w625JmUjlTrHJF?p=preview
 
import { Scene } from "Scene";
 
class Program
{
    public static Main()
    {
        let scene = new Scene("renderCanvas");
    }
}
Program.Main();
RequireConfig.ts
Javascript
1
2
3
4
5
6
7
8
9
10
11
requirejs.config({
    baseUrl: ".",
    paths: {
        "gl-matrix": "https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min"
    }
});
 
requirejs(["Program"], (Program) =>
{
 
});
Scene.ts
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import { VertexBuffers } from "./VertexBuffers";
import { ShaderProgram } from "./ShaderProgram";
import { Triangle } from "./Triangle";
import { glMatrix } from "gl-matrix";
 
export class Scene
{
    private _canvas: HTMLCanvasElement;
    private _gl: WebGLRenderingContext;
    private _program: WebGLShader;
    private _triangle1: Triangle;
    private _triangle2: Triangle;
 
    /**
     * Create a scene
     * @param { string } canvasName - Canvas name
     */
    public constructor(canvasName: string)
    {
        this._canvas = <HTMLCanvasElement>document.getElementById(canvasName);
        if (this._canvas == null)
        {
            console.log(`Failed to get the canvas element: ${canvasName}`);
            return;
        }
        
        this._gl = this._canvas.getContext("webgl");
 
        this._program = ShaderProgram.GetProgram(this._gl);
 
        VertexBuffers.InitVertexBuffers(this._gl, this._program);
 
        this._triangle1 = new Triangle(this._gl, this._program);
        this._triangle1.color = [0.529, 0.745, 0.098]; // Green
        this._triangle1.x = 0.5;
        this._triangle1.y = 0.5;
        this._triangle1.z = 0;
 
        this._triangle2 = new Triangle(this._gl, this._program);
        this._triangle2.color = [0.270, 0.419, 0.870];  // Blue
        this._triangle2.SetRotationInDegree(180.0);
        this._triangle2.x = 0.5;
        this._triangle2.y = 0.5;
        this._triangle2.z = -1;
 
        this._gl.enable(this._gl.DEPTH_TEST);
 
        this.Draw();
    }
 
    private Draw()
    {
        this._gl.clear(this._gl.COLOR_BUFFER_BIT | this._gl.DEPTH_BUFFER_BIT);
        this._triangle1.Draw();
        this._triangle2.Draw();
    }
}
ShaderProgram.ts
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
export class ShaderProgram
{
    /**
     * Returns a shader program
     * @returns { WebGLProgram }
     */
    public static GetProgram(gl: WebGLRenderingContext): WebGLProgram
    {
        let vShaderName = "VertexShader";
        let fShaderName = "FragmentShader";
        let vShaderElement = document.getElementById(vShaderName);
        let fShaderElement = document.getElementById(fShaderName);
        if (vShaderElement == null || fShaderElement == null)
        {
            console.log("Failed to get a shader HTML element with the name: " + vShaderName);
            return;
        }
 
        let vShaderSource = vShaderElement.firstChild.textContent;
        let fShaderSource = fShaderElement.firstChild.textContent;
 
        let vShader = this.GetShader(gl, vShaderSource, gl.VERTEX_SHADER);
        let fShader = this.GetShader(gl, fShaderSource, gl.FRAGMENT_SHADER);
 
        let program = gl.createProgram();
        gl.attachShader(program, vShader);
        gl.attachShader(program, fShader);
        gl.linkProgram(program);
        gl.useProgram(program);
 
        return program;
    }
 
    private static GetShader(
        gl: WebGLRenderingContext,
        shaderSource: string,
        shaderType: number): WebGLShader
    {
        // Create the shader object
        var shader = gl.createShader(shaderType);
 
        // Set the shader source code.
        gl.shaderSource(shader, shaderSource);
 
        // Compile the shader
        gl.compileShader(shader);
 
        // Check if it compiled
        var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
        if (!success)
        {
            // Something went wrong during compilation; get the error
            console.log("Could not compile shader:" + gl.getShaderInfoLog(shader));
            return null;
        }
 
        return shader;
    }
}
Triangle.ts
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import { mat4, vec3 } from "gl-matrix";
 
export class Triangle
{
    public color = [0.5, 0.5, 0.5];
    public x = 0.0;
    public y = 0.0;
    public z = 0.0;
    private _gl: WebGLRenderingContext;
    private _uColor: WebGLUniformLocation;
    private _uModelMatrix: WebGLUniformLocation;
    private _rotationInRad = 0.0;
 
    public constructor(gl: WebGLRenderingContext, program: WebGLProgram)
    {
        this._gl = gl;
 
        this._uColor = this.GetUniformLocation(program, "uColor");
        this._uModelMatrix = this.GetUniformLocation(program, "uModelMatrix");
    }
 
    private GetUniformLocation(
        program: WebGLProgram,
        name: string): WebGLUniformLocation
    {
        let uniformLocation = this._gl.getUniformLocation(program, name);
        if (uniformLocation == null)
        {
            console.log(`Failed to get ${name} variable`);
        }
        return uniformLocation;
    }
 
    public Draw(): void
    {
        let modelMatrix = mat4.create();
        mat4.translate(modelMatrix, modelMatrix, vec3.fromValues(this.x, this.y, this.z));
        mat4.rotateZ(modelMatrix, modelMatrix, this.GetRotationInRad());
        this._gl.uniformMatrix4fv(this._uModelMatrix, false, modelMatrix);
        this._gl.uniform3f(this._uColor, this.color[0], this.color[1], this.color[2]);
        this._gl.drawArrays(this._gl.TRIANGLES, 0, 3);
    }
 
    public GetRotationInRad(): number
    {
        return this._rotationInRad;
    }
 
    public SetRotationInDegree(rotationInDegree: number): void
    {
        this.SetRotationInRad(rotationInDegree * Math.PI / 180.0);
    }
 
    public SetRotationInRad(rotationInRad: number): void
    {
        this._rotationInRad = rotationInRad;
    }
}
VertexBuffers.ts
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
export class VertexBuffers
{
    public static InitVertexBuffers(gl: WebGLRenderingContext, program: WebGLProgram)
    {
        let vertices = new Float32Array([
            0.0, 0.5, 0.0,
            -0.5, -0.5, 0.0,
            0.5, -0.5, 0.0
        ]);
 
        let vbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
 
        let aPosition = gl.getAttribLocation(program, "aPosition");
        if (aPosition < 0)
        {
            console.log("Failed to get aPosition variable");
            return;
        }
 
        gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(aPosition);
    }
}
tsconfig.json
JSON
1
2
3
4
5
6
7
{
    "compilerOptions": {
        "module": "amd",
        "target": "es5",
        "sourceMap": true
    }
}
1
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
19.12.2018, 13:23 4
Цитата Сообщение от j2FunOnly Посмотреть сообщение
Нет
Это ответ на вопрос темы.

Цитата Сообщение от 8Observer8 Посмотреть сообщение
<canvas> в контексте "webgl"
Цитата Сообщение от 8Observer8 Посмотреть сообщение
можно расположить объекты по слоям
Я предложил альтернативу в виде WebGL.

Будет считать, что тема исчерпана и эти два ответа являются решениями темы.
0
56 / 50 / 22
Регистрация: 17.03.2014
Сообщений: 142
16.11.2022, 10:50 5
Лучший ответ Сообщение было отмечено 8Observer8 как решение

Решение

Некропостинг, конечно, но сейчас сам столкнулся с подобным вопросом, а это первая выдаваемая ссылка на русском языке, так что вдруг кому еще пригодится.
Существует свойство контекста канвы globalCompositeOperation, которая позволяет указать позиционирование рисуемого элемента.
Javascript
1
2
3
4
5
6
7
8
9
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// новый элемент будет нарисован поверх существующего контента, это дефолтное значение
ctx.globalCompositeOperation = "source-over"; 
 
....
 
// новый элемент будет нарисован позади существующего контента
ctx.globalCompositeOperation = "destination-over";
А вообще там около 20 значений этого свойства, позволяющего делать разную композицию нового элемента с уже существующими, но в разрезе разговора о z-index эти два самые полезные.
4
16.11.2022, 10:50
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.11.2022, 10:50
Помогаю со студенческими работами здесь

Правильные настройки канваса
Доброго времени суток, всегда при создании канваса выставлял такие настройки, верно ли они сделаны...

Как индексировать элементы канваса?
Очень надо, помогите! Я хочу динамически мышкой нарисовать три точки, у каждой из них при создании...

Сохранение канваса как картинки
Доброе время суток, у меня есть не большая проблема когда я пытаюсь сохранить канвас, он...

Скролл без обновления канваса
Проблема в следующем - имеется достаточно большой канвас, на отрисовку которого уходит около 0.1...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru