webgl+canvas实现交互式城市顶部鸟瞰俯视效果代码
代码语言:html
所属分类:其他
代码描述:webgl+canvas实现交互式城市顶部鸟瞰俯视效果代码
代码标签: webgl canvas 交互式 城市 顶部 鸟瞰 俯视
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<style>
*, *::before, *::after {
margin: 0;
padding: 0;
border: 0;
box-sizing: border-box;
}
*:focus {
outline: none;
}
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background-color: rgb( 0, 0, 0 );
}
canvas {
touch-action: none;
}
</style>
</head>
<body translate="no">
<script >
'use strict';
//---
console.clear();
//---
let w = 0;
let h = 0;
let initialWidth = w;
let initialHeight = h;
let animationFrame = null;
let isTouchDevice = false;
const fov = 600;
const lightVector = { x: -fov * 0.25, y: 0, z: -fov * 0.5 };
const cameraVector = { x: 0, y: 0, z: -fov };
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2') || canvas.getContext('experimental-webgl2');
const center = { x: w / 2, y: h / 2 };
const border = { left: 1, top: 1, right: w, bottom: h };
const borderDistance = 0;
const pointerDistance = 25;
let pointer = { x: 0, y: 0 };
let pointerInitialPos = { x: 0, y: 0 };
let pointerPos = { x: center.x, y: center.y };
let pointerDownButton = -1;
let pointerActive = false;
//---
let shaderProgram = null;
let webgl_vertices = [];
let webgl_faces = [];
let webgl_uvs = [];
let webgl_layers = [];
const buffers = {};
//---
const vertexCode = `#version 300 es
in vec2 a_position;
in vec2 a_texcoord;
in float a_layer;
uniform vec2 u_resolution;
out vec2 v_texcoord;
out float v_layer;
void main(void) {
v_texcoord = a_texcoord;
v_layer = a_layer;
vec2 pos2d = a_position.xy;
vec2 zeroToOne = pos2d / u_resolution;
vec2 zeroToTwo = zeroToOne * 2.0;
vec2 clipSpace = zeroToTwo - 1.0;
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
}
`;
const fragmentCode = `#version 300 es
precision lowp float;
precision lowp sampler2DArray;
in vec2 v_texcoord;
in float v_layer;
uniform sampler2DArray u_textureArray;
out vec4 fragColor;
void main(void) {
fragColor = texture(u_textureArray, vec3(v_texcoord, v_layer));
}
`;
//---
let gridTileSize = 0;
let gridTileSizeHalf = 0;
let gridStartPositionX = 0;
let gridStartPositionY = 0;
let gridEndPositionX = 0;
let gridEndPositionY = 0;
let gridDotsPerRow = 0;
let gridDotsPerColumn = 0;
let gridWidth = 0;
let gridHeight = 0;
let gridMaxTileSize = 4;
let gridBuildingTileSizes = [{ x: 4, y: 4 }, { x: 3, y: 4 }, { x: 2, y: 4 }, { x: 4, y: 3 }, { x: 4, y: 2 }, { x: 3, y: 3 }, { x: 2, y: 3 }, { x: 3, y: 2 }, { x: 1, y: 3 }, { x: 3, y: 1 }, { x: 2, y: 2 }, { x: 1, y: 2 }, { x: 2, y: 1 }, { x: 1, y: 1 }];
let gridStreetTileTypes = ['empty', '1x1_vertical', '1x1_horizontal', '1x1_crossing', '2x1l_vertical', '2x1r_vertical', '1x2t_horizontal', '1x2b_horizontal', '1x2r_crossing', '1x2l_crossing', '2x1t_crossing', '2x1b_crossing', '2x2tl_crossing', '2x2tr_crossing', '2x2bl_crossing', '2x2br_crossing', '1x1l_horizontal_crosswalk', '1x1r_horizontal_crosswalk', '1x1b_vertical_crosswalk', '1x1t_vertical_crosswalk', '1x2lt_horizontal_crosswalk', '1x2lb_horizontal_crosswalk', '1x2rt_horizontal_crosswalk', '1x2rb_horizontal_crosswalk', '2x1tl_vertical_crosswalk', '2x1tr_vertical_crosswalk', '2x1bl_vertical_crosswalk', '2x1br_vertical_crosswalk'];
let gridTileHolder = [];
let gridCubeHolder = [];
let gridStreetHolder = [];
let gridMovementSaveXPos = 0;
let gridMovementSaveYPos = 0;
const dotsRadius = 1;
const dotsDistance = 10;
const dotsDiameter = dotsRadius * 2;
let dotsHolder = [];
let streetsCountVertical = 0;
let streetsCountHorizontal = 0;
let debugBorderElement = null;
let debugBorderElementColor = 'transparent';
//---
const texturesBuildingsCount = 64;
const textureWidth = 64;
const textureHeight = 64;
let textureHolder = [];
let promiseHolder = [];
let textureAtlas = {};
let textureArray = null;
let texture = null;
const texturesBuildingRoofsTiles = 9;
let texturesCountBuildingRoofs = 0;
let texturesCountBuildingWalls = 0;
let texturesCountStreets = 0;
const textureCubeNormals = [
{ x: 0, y: 0, z: -1 }, // front
{ x: -1, y: 0, z: 0 }, // left
{ x: 0, y: -1, z: 0 }, // top
{ x: 1, y: 0, z: 0 }, // right
{ x: 0, y: 1, z: 0 } // bottom
];
const textureBuildingColors = [
{ cWa: { r: 254, g: 236, b: 214 }, cWi: { r: 67, g: 49, b: 37 } },
{ cWa: { r: 244, g: 250, b: 240 }, cWi: { r: 13, g: 39, b: 52 } },
{ cWa: { r: 244, g: 250, b: 240 }, cWi: { r: 26, g: 36, b: 48 } },
{ cWa: { r: 228, g: 231, b: 222 }, cWi: { r: 73, g: 79, b: 79 } },
{ cWa: { r: 228, g: 231, b: 222 }, cWi: { r: 103, g: 93, b: 94 } },
{ cWa: { r: 184, g: 187, b: 196 }, cWi: { r: 38, g: 56, b: 66 } },
{ cWa: { r: 219, g: 226, b: 230 }, cWi: { r: 32, g: 45, b: 54 } },
{ cWa: { r: 249, g: 244, b: 225 }, cWi: { r: 63, g: 53, b: 61 } },
{ cWa: { r: 240, g: 243, b: 234 }, cWi: { r: 19, g: 36, b: 46 } },
{ cWa: { r: 255, g: 255, b: 255 }, cWi: { r: 22, g: 34, b: 40 } },
{ cWa: { r: 230, g: 214, b: 201 }, cWi: { r: 63, g: 68, b: 74 } },
{ cWa: { r: 213, g: 212, b: 202 }, cWi: { r: 59, g: 75, b: 72 } },
{ cWa: { r: 243, g: 237, b: 237 }, cWi: { r: 94, g: 92, b: 81 } },
{ cWa: { r: 228, g: 228, b: 203 }, cWi: { r: 63, g: 52, b: 44 } },
{ cWa: { r: 233, g: 222, b: 216 }, cWi: { r: 39, g: 46, b: 54 } },
{ cWa: { r: 238, g: 219, b: 192 }, cWi: { r: 77, g: 87, b: 88 } },
{ cWa: { r: 238, g: 230, b: 225 }, cWi: { r: 55, g: 71, b: 84 } },
{ cWa: { r: 239, g: 211, b: 196 }, cWi: { r: 95, g: 87, b: 85 } },
{ cWa: { r: 243, g: 242, b: 238 }, cWi: { r: 32, g: 42, b: 51 } },
{ cWa: { r: 243, g: 233, b: 223 }, cWi: { r: 61, g: 72, b: 74 } },
{ cWa: { r: 230, g: 228, b: 225 }, cWi: { r: 30, g: 47, b: 55 } },
{ cWa: { r: 218, g: 226, b: 230 }, cWi: { r: 15, g: 29, b: 38 } },
{ cWa: { r: 244, g: 238, b: 224 }, cWi: { r: 99, g: 92, b: 89 } },
{ cWa: { r: 242, g: 219, b: 191 }, cWi: { r: 120, g: 111, b: 73 } },
{ cWa: { r: 233, g: 239, b: 245 }, cWi: { r: 80, g: 82, b: 91 } },
{ cWa: { r: 237, g: 225, b: 211 }, cWi: { r: 47, g: 40, b: 32 } },
{ cWa: { r: 211, g: 207, b: 198 }, cWi: { r: 55, g: 46, b: 39 } },
{ cWa: { r: 223, g: 222, b: 213 }, cWi: { r: 41, g: 41, b: 39 } }];
//---
function init() {
gl.enable(gl.SCISSOR_TEST);
shaderProgram = createShaderProgram(gl, vertexCode, fragmentCode);
//---
isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
if (isTouchDevice === true) {
canvas.addEventListener('touchmove', cursorMoveHandler, false);
canvas.addEventListener('touchend', cursorLeaveHandler, false);
canvas.addEventListener('touchcancel ', cursorLeaveHandler, false);
} else {
canvas.addEventListener('pointermove', cursorMoveHandler, false);
canvas.addEventListener('pointerdown', cursorDownHandler, false);
canvas.addEventListener('pointerup', cursorUpHandler, false);
canvas.addEventListener('pointerleave', cursorLeaveHandler, false);
}
//---
document.body.appendChild(canvas);
//---
debugBorderElement = document.createElement('div');
debugBorderElement.style.border = '1px solid ' + debugBorderElementColor;
debugBorderElement.style.position = 'absolute';
debugBorderElement.style.margin = 'auto';
debugBorderElement.style.pointerEvents = 'none';
document.body.appendChild(debugBorderElement);
//---
createTextures().then(() => {
window.addEventListener('resize', onResize, false);
restart();
});
}
function onResiz.........完整代码请登录后点击上方下载按钮下载查看
















网友评论0