From da6ca9cf5b3e7a073d6b008fd44a15708c24bbad Mon Sep 17 00:00:00 2001 From: Nugzar Gaguliya Date: Thu, 14 Jan 2016 12:58:25 +0500 Subject: [PATCH] copy from pc --- .gitignore | 2 + Perspective.js | 79 ++++++++++++++++ Settings.js | 9 ++ cycle | 7 ++ distanceXYZ.js | 31 +++++++ fullscreen.css | 28 ++++++ index.html | 65 +++++++++++++ index.js | 243 +++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 8 ++ 9 files changed, 472 insertions(+) create mode 100644 .gitignore create mode 100644 Perspective.js create mode 100644 Settings.js create mode 100644 cycle create mode 100644 distanceXYZ.js create mode 100644 fullscreen.css create mode 100644 index.html create mode 100644 index.js create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9d86a3d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +idea/ +node_modules/ \ No newline at end of file diff --git a/Perspective.js b/Perspective.js new file mode 100644 index 0000000..2fa510a --- /dev/null +++ b/Perspective.js @@ -0,0 +1,79 @@ +function Solid() { + +} + +Solid.distanceY = function (distance) { + var X = distance + Settings.pd; + var x = distance; + var Y = Settings.canvasHeight - Settings.horizonY; + return Y * x / X; +}; + +Solid.distanceX = function (distance, distanceY) { + var y = distanceY; + var Y = Settings.canvasHeight - Settings.horizonY; + var X = distance - Settings.horizonX; + return y / Y * X; +}; + +Solid.distanceZ = function (H, distanceY) { + var Y = Settings.canvasHeight - Settings.horizonY; + var y = Y - distanceY; + return y / Y * H; +}; + +function Point(x, y, z, options) { + this._x = x || 0; + this._y = y || 0; + this._z = z || 0; + this.options = options || {}; + this.options.color = this.options.color || 'gold'; + + var Y = Point.distanceY(y); + var X = Point.distanceX(x, Y); + + var Z = Point.distanceZ(z, Y); + + this.x = X; + this.y = Y; + this.z = Z; + + this.X = x - X; + this.Y = Settings.canvasHeight - Y; + this.Z = Settings.canvasHeight - Y - Z; +} + +for (var key in Solid) { + if (Solid.hasOwnProperty(key)) Point[key] = Solid[key] +} + +Point.prototype.draw = function () { + ctx.fillStyle = 'gold'; + ctx.beginPath(); + ctx.arc(this.X, this.Z, 3, 0, Math.PI * 2, true); + ctx.fill(); +}; + +Point.prototype.drawProjection = function () { + ctx.strokeStyle = this.options.color; + ctx.beginPath(); + ctx.moveTo(this.X, this.Y); + ctx.lineTo(this.X, this.Z); + ctx.stroke(); +}; + +function Segment(A, B, options) { + this._A = A; + this._B = B; + + this.options = options || {}; + this.options.color = this.options.color || 'gold'; +} + +Segment.prototype.draw = function () { + ctx.strokeStyle = this.options.color; + ctx.beginPath(); + ctx.moveTo(this._A.x, this._B.z); + ctx.lineTo(this._B.x, this._B.z); + ctx.stroke(); +}; \ No newline at end of file diff --git a/Settings.js b/Settings.js new file mode 100644 index 0000000..5f447d1 --- /dev/null +++ b/Settings.js @@ -0,0 +1,9 @@ +var Settings = { + horizonY: 250, + horizonX: 640, + frameCount: 300, + pd: 300, + mostDistanceX: 3, + mostDistanceY: 5, + scale: 5 +}; \ No newline at end of file diff --git a/cycle b/cycle new file mode 100644 index 0000000..cd2312a --- /dev/null +++ b/cycle @@ -0,0 +1,7 @@ +Scale 0 1 2 3 ... n-1 n + +frame0 0.0 1.0 2.0 3.0 ... n-1 + 0.0 n.0 +frame1 0.3 1.3 2.3 3.3 ... n-1 + 0.3 n.0 +frame2 0.6 1.6 2.6 3.6 ... n-1 + 0.6 n.0 + +frameK 0.0 1.0 2.0 3.0 ... n-1 + 0.0 n.0 \ No newline at end of file diff --git a/distanceXYZ.js b/distanceXYZ.js new file mode 100644 index 0000000..fa9e625 --- /dev/null +++ b/distanceXYZ.js @@ -0,0 +1,31 @@ +ctx.beginPath(); +ctx.strokeStyle = 'red'; +// +//// Y +// ctx.moveTo(A._y, Settings.canvasHeight); +// ctx.lineTo(Settings.horizonX, Settings.horizonY); +// +//// Y +// ctx.moveTo(0, Settings.canvasHeight); +// ctx.lineTo(Settings.horizonX + Settings.pd, Settings.horizonY); + +//// X +//ctx.moveTo(0, A.Y); +//ctx.lineTo(Settings.canvasWidth, A.Y); +//// X +//ctx.moveTo(Settings.horizonX, Settings.canvasHeight); +//ctx.lineTo(Settings.horizonX, Settings.horizonY); +// +//// X & Z +//ctx.moveTo(A._x, Settings.canvasHeight); +//ctx.lineTo(Settings.horizonX, Settings.horizonY); +// +//// Z +// ctx.moveTo(A._x, canvasHeight - A._z); +// ctx.lineTo(horizonX, horizonY); +// +//// Z +// ctx.moveTo(A._x, canvasHeight); +// ctx.lineTo(A._x, canvasHeight - A._z); + +ctx.stroke(); \ No newline at end of file diff --git a/fullscreen.css b/fullscreen.css new file mode 100644 index 0000000..de37c12 --- /dev/null +++ b/fullscreen.css @@ -0,0 +1,28 @@ +html { + min-height: 100%; + position: relative; +} + +body { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + overflow: hidden; + margin: 0; +} + +body canvas { + display: block; + margin: auto auto; + background: rgb(0,128,128); +} + +#settings { + position: absolute; + right:0; + top: 0; + z-index: 1; + color: white; +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..c9aa687 --- /dev/null +++ b/index.html @@ -0,0 +1,65 @@ + + + + + Perspective + + + + + + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ + + + + + + + *canvas clickable +
+ + \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..fb291ee --- /dev/null +++ b/index.js @@ -0,0 +1,243 @@ +CanvasRenderingContext2D.prototype.clear = + CanvasRenderingContext2D.prototype.clear || function (preserveTransform) { + if (preserveTransform) { + this.save(); + this.setTransform(1, 0, 0, 1, 0, 0); + } + + this.clearRect(0, 0, this.canvas.width, this.canvas.height); + + if (preserveTransform) { + this.restore(); + } + }; + + +Settings.canvasWidth = window.innerWidth; +Settings.canvasHeight = window.innerHeight; +Settings.step = Settings.canvasWidth / Settings.scale; +Settings.globalZ = 0; + + +var canvas = document.createElement('canvas'); +canvas.width = Settings.canvasWidth; +canvas.height = Settings.canvasHeight; + +var ctx = Settings.ctx = canvas.getContext("2d"); +var form; + +document.addEventListener("DOMContentLoaded", function () { + var body = document.body; + + body.appendChild(canvas); + + form = document.getElementById('settings'); + form.addEventListener('submit', function (event) { + event.preventDefault(); + }); + + var $pd = form.pd; + $pd.value = Settings.pd; + $pd.addEventListener('change', function () { + var value = +this.value; + if (value > 0) { + Settings.pd = value; + } + }); + + var $frameCount = form['frame-count']; + $frameCount.value = Settings.frameCount; + $frameCount.addEventListener('change', function () { + var value = +this.value; + if (value > 0) { + Settings.frameCount = value; + } + }); + + var $distanceX = form['distance-x']; + $distanceX.value = Settings.mostDistanceX; + $distanceX.addEventListener('change', function () { + var value = +this.value; + if (value > 0) { + Settings.mostDistanceX = value; + } + }); + + var $distanceY = form['distance-y']; + $distanceY.value = Settings.mostDistanceY; + $distanceY.addEventListener('change', function () { + var value = +this.value; + if (value >= 0) { + Settings.mostDistanceY = value; + } + }); + + var $scale = form['scale']; + $scale.value = Settings.mostDistanceY; + $scale.addEventListener('change', function () { + var value = +this.value; + if (value >= 0) { + Settings.scale = value; + Settings.step = Settings.canvasWidth / Settings.scale; + } + }); + + var $horizonX = form['horizon-x']; + $horizonX.value = Settings.horizonX; + $horizonX.addEventListener('change', function () { + Settings.horizonX = +this.value; + }); + + var $horizonY = form['horizon-y']; + $horizonY.value = Settings.horizonY; + $horizonY.addEventListener('change', function () { + Settings.horizonY = +this.value; + }); + + var $globalZ = form['global-z']; + $globalZ.value = Settings.globalZ; + $globalZ.addEventListener('change', function () { + Settings.globalZ = +this.value; + }); + + +}); + +canvas.addEventListener('click', function (event) { + Settings.horizonY = event.layerY; + Settings.horizonX = event.layerX; + + var $horizonX = form['horizon-x']; + $horizonX.value = Settings.horizonX; + + var $horizonY = form['horizon-y']; + $horizonY.value = Settings.horizonY; + + console.log(Settings.horizonX, Settings.horizonY); +}); + +canvas.addEventListener('wheel', function (event) { + var delta = event.deltaY > 0 ? 10 : -10; + var cpd = Settings.pd + delta; + if (cpd > 0) { + Settings.pd = cpd; + } + var $pd = form.pd; + $pd.value = Settings.pd; +}); + +function draw(time) { + ctx.clear(); + + //var horizon = new Point(Settings.canvasWidth/2, Settings.canvasWidth*Settings.mostDistanceX, 0 - Settings.globalZ); + //Settings.horizonX = horizon.X; + //Settings.horizonY = horizon.Z; + + var frame = (time) % Settings.frameCount; + var maxDistance = Settings.canvasWidth * Settings.mostDistanceX; + var count = Settings.scale * Settings.mostDistanceX; + + var leftEnd = 0 - (Settings.mostDistanceY - 1) / 2 * Settings.canvasWidth; + var rightEnd = Settings.canvasWidth + (Settings.mostDistanceY - 1) / 2 * Settings.canvasWidth; + + function getDistance(index) { + if (index == count) return maxDistance; + var order = maxDistance * index / count; + + var step = (1 - frame / Settings.frameCount) * Settings.step; + return order + step; + } + + (function drawHorizonLines() { + ctx.beginPath(); + ctx.strokeStyle = 'white'; + for (var i = 0; i <= count; i++) { + var distance = getDistance(i); + + var A = new Point(leftEnd, distance, 0 - Settings.globalZ); + var B = new Point(rightEnd, distance, 0 - Settings.globalZ); + ctx.moveTo(A.X, A.Z); + ctx.lineTo(B.X, B.Z); + } + ctx.stroke(); + })(); + + (function drawVerticalLines() { + ctx.beginPath(); + ctx.strokeStyle = 'white'; + for (var c = leftEnd; c <= rightEnd; c += Settings.step) { + var A = new Point(c, 0, 0 - Settings.globalZ); + var B = new Point(c, Settings.mostDistanceX*Settings.canvasWidth, 0 - Settings.globalZ); + ctx.moveTo(A.X, A.Z); + ctx.lineTo(B.X, B.Y); + } + ctx.stroke(); + })(); + + + (function drawTunnel() { + ctx.strokeStyle = 'white'; + + var alpha = Math.PI / 180 * 59.2; + var height = Settings.canvasHeight * 2; + var left = Settings.canvasWidth / 2; + + + ctx.beginPath(); + + var A = new Point(left - height * Math.cos(alpha), Settings.mostDistanceX*Settings.canvasWidth, 0 - Settings.globalZ); + var B = new Point(left + height * Math.cos(alpha), Settings.mostDistanceX*Settings.canvasWidth, 0 - Settings.globalZ); + // rails + ctx.moveTo(left - height * Math.cos(alpha), Settings.canvasHeight); + ctx.lineTo(A.X, A.Y); + + ctx.moveTo(left + height * Math.cos(alpha), Settings.canvasHeight); + ctx.lineTo(B.X, B.Y); + + ctx.stroke(); + + ctx.beginPath(); + for (var y = 0; y <= count; y++) { + var O = new Point(left, getDistance(y), height - Settings.globalZ); + + var X = O.X; + var Y = O.Z; + var R = O.z; + var sagitta = R - R * Math.sin(alpha); + ctx.moveTo(X + R * Math.cos(alpha), Y + R * Math.sin(alpha) + sagitta); + ctx.arc(X, Y + sagitta, R, Math.PI - alpha, alpha, false); + } + + ctx.stroke(); + + })(); + +} + +requestAnimationFrame = requestAnimationFrame || mozRequestAnimationFrame || webkitRequestAnimationFrame || msRequestAnimationFrame; + +//draw(0); +// +var stop; +var time = 0; +loop(); +function loop() { + if (!stop) { + time++; + draw(time); + + } + + requestAnimationFrame(loop); +} + + + + +function deg(rad) { + return rad / Math.PI * 180; +} + +//document.body.addEventListener('click', function () { +// stop = !stop; +//}); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..ad0585a --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "name": "perspective", + "version": "0.0.1", + "description": "3D simulation on 2D canvas", + "main": "index.html", + "author": "Gaguliya Nugzar", + "repository": "https://github.com/NugzarGaguliya/perspective.git" +}