<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>HTML5 Canvas 化学材料分子结构图</title>
<style>
html {
overflow: hidden;
-ms-touch-action: none;
-ms-content-zooming: none;
}
body {
position: absolute;
margin: 0;
padding: 0;
background: #222;
width: 100%;
height: 100%;
}
#mycanvas {
position: absolute;
width: 100%;
height: 100%;
background: #000;
cursor: pointer;
}
</style>
</head>
<body>
<canvas id="mycanvas"></canvas>
<script>
/**
* Adapted from WebGL framework by Florian Boesch - @pyalot
* https://github.com/pyalot/soft-shadow-mapping/blob/master/framework.coffee
*/
class Canvas {
constructor(container) {
this.elem = document.getElementById(container);
this.width = 0;
this.height = 0;
}
enableFullscreen(style) {
if (
document.fullscreenEnabled ||
document.webkitFullscreenEnabled ||
document.mozFullScreenEnabled ||
document.msFullscreenEnabled
) {
this.bfs = document.createElement("button");
this.bfs.appendChild(document.createTextNode("Fullscreen"));
this.elem.parentElement.appendChild(this.bfs);
for (let s in style) this.bfs.style[s] = style[s];
this.bfs.addEventListener('click', e => {
e.preventDefault();
this.requestFullscreen();
});
}
}
requestFullscreen() {
if (this.elem.requestFullscreen) {
this.elem.requestFullscreen();
} else if (this.elem.webkitRequestFullscreen) {
this.elem.webkitRequestFullscreen();
} else if (this.elem.mozRequestFullScreen) {
this.elem.mozRequestFullScreen();
} else if (this.elem.msRequestFullscreen) {
this.elem.msRequestFullscreen();
}
}
}
class Pointer {
constructor(canvas) {
this.x = 0;
this.y = 0;
this.z = 0;
this.xold = 0;
this.yold = 0;
this.zold = 0;
this.isDown = false;
this.canvas = canvas;
window.addEventListener('mousemove', e => this.move(e), false);
canvas.elem.addEventListener('touchmove', e => this.move(e), false);
window.addEventListener('mousedown', e => this.down(e), false);
window.addEventListener('touchstart', e => this.down(e), false);
window.addEventListener('mouseup', e => this.up(e), false);
window.addEventListener('touchend', e => this.up(e), false);
window.addEventListener('wheel', e => this.wheel(e), false);
}
down(e) {
if (e.target !== this.canvas.elem) return;
this.move(e);
this.xold = this.x;
this.yold = this.y;
this.isDown = true;
}
up(e) {
this.isDown = false;
}
move(e) {
const touchMode = e.targetTouches;
let pointer = null;
if (touchMode) {
e.preventDefault();
if (touchMode.length > 1) {
const dx = touchMode[0].clientX - touchMode[1].clientX;
const dy = touchMode[0].clientY - touchMode[1].clientY;
const d = dx * dx + dy * dy;
this.z += (d > this.zold) ? -0.2 : 0.2;
this.zold = d;
return;
}
pointer = touchMode[0];
} else pointer = e;
this.x = pointer.clientX;
this.y = pointer.clientY;
}
wheel(e) {
e.preventDefault();
this.z += e.deltaY > 0 ? -1 : 1;
}
}
class WebGL {
constructor(canvas, options) {
this.canvas = canvas;
this.gl = this.canvas.elem.getContext("webgl", options);
if (!this.gl) this.gl = this.canvas.elem.getContext("experimental-webgl", options);
if (!this.gl) throw new Error('This browser does not support WebGL');
this.width = 0;
this.height = 0;
this.aspect = 0;
this.textureUnits = [];
for (let i = 0; i < 16; ++i) {
this.textureUnits.push(null);
}
this.vertexUnits = [];
for (let i = 0; i < 16; ++i) {
this.vertexUnits.push({
enabled: false,
drawable: null,
idx: null
});
}
this.currentShader = null;
}
getExtension(name) {
const ext = this.gl.getExtension(name);
if (!ext) {
throw new Error('WebGL Extension not supported: ' + name);
}
return ext;
}
adjustSize() {
const canvasWidth = (this.canvas.elem.offsetWidth * 1) || 2;
const canvasHeight = (this.canvas.elem.offsetHeight * 1) || 2;
if (this.width !== canvasWidth || this.height !== canvasHeight) {
this.width = this.canvas.width = this.canvas.elem.width = canvasWidth;
this.height = this.canvas.height = this.canvas.elem.height = canvasHeight;
this.aspect = this.width / this.height;
}
return this;
}
viewport(left = 0, top = 0, width = this.width, height = this.height) {
this.gl.viewport(left, top, width, height);
return this;
}
cullFace(value = true) {
if (value) {
this.gl.enable(this.gl.CULL_FACE);
} else {
this.gl.disable(this.gl.CULL_FACE);
}
return this;
}
clearColor(r = 0, g = 0, b = 0, a = 1) {
this.gl.clearColor(r, g, b, a);
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
return this;
}
clearDepth(depth = 1) {
this.gl.clearDepth(depth);
this.gl.clear(this.gl.DEPTH_BUFFER_BIT);
return this;
}
depthTest(value = true) {
if (value) {
this.gl.enable(this.gl.DEPTH_TEST);
} else {
this.gl.disable(this.gl.DEPTH_TEST);
}
return this;
}
texture(params) {
return new Texture(this, params);
}
framebuffer() {
return new Framebuffer(this);
}
depthbuffer() {
return new Depthbuffer(this);
}
shader(params) {
return new Shader(this, params);
}
drawable(params) {
return new Drawable(this, params);
}
filter(size, filter) {
return new Filter(this, size, filter);
}
vec3(x = 0, y = 0, z = 0) {
return new Vec3(x, y, z);
}
mat3(data) {
return new Mat3(data);
}
mat4(data) {
return new Mat4(data);
}
meshesPointers() {
return [
{
name: 'position',
size: 3,
offset: 0,
stride: 6
}, {
name: 'normal',
size: 3,
offset: 3,
stride: 6
}
];
}
quad() {
return {
pointers: [{
name: 'position',
size: 2,
offset: 0,
stride: 2
}],
vertexSize: 2,
vertices: [
-1, -1, 1, -1, 1, 1,
-1, 1, -1, -1, 1, 1
]
};
}
plane(s) {
return {
pointers: this.meshesPointers(),
vertexSize: 6,
vertices: [
-s, 0, -s, 0, 1, 0,
-s, 0, s, 0, 1, 0,
s, 0, s, 0, 1, 0,
s, 0, -s, 0, 1, 0,
-s, 0, -s, 0, 1, 0,
s, 0, s, 0, 1, 0
]
};
}
cube(x = 1, y = 1, z = 1) {
return {
pointers: this.meshesPointers(),
vertexSize: 6,
vertices: [
-x, -y, -z, 0, 0, -1,
-x, y, -z, 0, 0, -1,
x, y, -z, 0, 0, -1,
x, -y, -z, 0, 0, -1,
-x, -y, -z, 0, 0, -1,
x, y, -z, 0, 0, -1,
x, y, z, 0, 0, 1,
-x, y, z, 0, 0, 1,
-x, -y, z, 0, 0, 1,
x, y, z, 0, 0, 1,
-x, -y, z, 0, 0, 1,
x, -y, z, 0, 0, 1,
-x, y, -z, 0, 1, 0,
-x, y, z, 0, 1, 0,
x, y, z, 0, 1, 0,
x, y, -z, 0, 1, 0,
-x, y, -z, 0, 1, 0,
x, y, z, 0, 1, 0,
x, -y, z, 0, -1, 0,
-x, -y, z, 0, -1, 0,
-x, -y, -z, 0, -1, 0,
x, -y, z, 0, -1, 0,
-x, -y, -z, 0, -1, 0,
x, -y, -z, 0, -1, 0,
-x, -y, -z, -1, 0, 0,
-x, -y, z, -1, 0, 0,
-x, y, z, -1, 0, 0,
-x, y, -z, -1, 0, 0,
-x, -y, -z, -1, 0, 0,
-x, y, z, -1, 0, 0,
x, y, z, 1, 0, 0,
x, -y, z, 1, 0, 0,
x, -y, -z, 1, 0, 0,
x, y, z, 1, 0, 0,
x, -y, -z, 1, 0, 0,
x, y, -z, 1, 0, 0
]
};
}
sphere(radius = 1, res = 36) {
const nx = [];
const ny = [];
const nz = [];
const vertices = [];
for (let i = 0; i <= res; i++) {
毕业_设计
- 粉丝: 1992
- 资源: 1万+
最新资源
- 通过C#实现冒泡排序示例代码(含代码解释)
- 保险交叉销售预测数据集.zip
- StartAllBack-3.6.3-setup, win不同风格的开始菜单
- c语言实现希尔排序基础
- emoji表情使用趋势数据集.zip
- 抖音 douyin 视频评论 spider
- Beyond.Compare.v3.1.10
- 2016年年度培训计划及跟踪表.xls
- 2016年公司员工年度培训计划表.xls
- 《如何设计年度培训计划与预算方案》.ppt
- 公司培训规划之一--员工素养培训(PPT 63页).ppt
- 麦肯锡:进度安排培训.ppt
- 北大讲义《如何设计年度培训计划与预算方案》.ppt
- 美的校园招聘面试官培训方案(ppt 14页).ppt
- 培训与发展.ppt
- 培训管理.ppt
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈