1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 计算机图形学Web前端笔记-定位并移动到指定坐标点(two.js理论及实现)

计算机图形学Web前端笔记-定位并移动到指定坐标点(two.js理论及实现)

时间:2020-01-29 02:25:53

相关推荐

计算机图形学Web前端笔记-定位并移动到指定坐标点(two.js理论及实现)

这里先演示下效果笔记毕竟这是给理论及实践的博文。

当按下回车后

会到场景600,600中画个圆并且浏览器会移动到场景600,600的位置,并且这个位置将会是圆心。

同样,滑动滚轮进行放缩后,还是能进行定位的:

这里来说下代码以及算法:

这里的dot值存储了当前浏览器屏幕中心点对应在场景坐标点,参数x,y即为要定位的点,也就是屏幕中心会移动到的地方。

等会说下getScreenOriginal()这个函数是怎么实现的。

得到点后,把dot.x-x及dot.y-y乘以对应的水平放缩和垂直放缩,最后使用graphicMove()变化矩阵,使得x,y变为中心点。

graphicMove()这个函数在以前的博文说过了,再次不在重复说明。

这里提下getScreenOriginal()函数:

通过two.width以及two.height可以获取到当前浏览器的长宽。

其中original为屏幕的中点;

其中cirX为(中心点-水平位移)/(水平放缩)

其中cirY为(中心点-垂直位移)/(垂直放缩)

关键源码如下:

;import * as Two from "JS/two";import * as $ from "JS/jquery";let two;let mouse;let isPressed = false;let originalPositionX = 0;let originalPositionY = 0;let map = new Map();let rect;export function drawGraphic(){let elem = document.getElementById("draw-shapes");let params = {type: Two.Types['webgl'],fullscreen: true,autostart: true};two = new Two(params).appendTo(elem);mouse = new Two.ZUI(two.scene);mouse.addLimits(0.1, 10);let $stage = $(two.renderer.domElement);$stage.bind('mousewheel wheel', function(event){let e = event.originalEvent;e.stopPropagation();e.preventDefault();let dy = (e.wheelDeltaY || -e.deltaY) / 1000;mouse.zoomBy(dy, e.clientX, e.clientY);});$stage.bind('mouseup', function(event){isPressed = false;});$stage.bind('mouseout', function(event){isPressed = false;});$stage.bind('mousedown', function(event){isPressed = true;originalPositionX = event.clientX;originalPositionY = event.clientY;let x = event.clientX;let y = event.clientY;for(let value of map){let xOffset = value[0]._width / 2;let yOffset = value[0]._height / 2;let letX = ((value[0]._translation._x - xOffset) * (two.scene._matrix.elements[0]) + two.scene._matrix.elements[2]);let letY = ((value[0]._translation._y - yOffset) * (two.scene._matrix.elements[4]) + two.scene._matrix.elements[5]);let letWidth = value[0]._width * two.scene._matrix.elements[0];let letHeight = value[0]._height * two.scene._matrix.elements[4];if(x > letX &&y > letY &&x < letX + letWidth &&y < letY + letHeight){let r = Math.round(Math.random() * 255);let g = Math.round(Math.random() * 255);let b = Math.round(Math.random() * 255);let rgbStr = "rgb(" + r + "," + g + "," + b + ")";value[0].fill = rgbStr;break;}}});$stage.bind('mousemove', function(event){if(isPressed){let boolX = event.clientX - originalPositionX;let boolY = event.clientY - originalPositionY;// console.log(boolX + " " + boolY);mouse.graphicMove(boolX, boolY);originalPositionX = event.clientX;originalPositionY = event.clientY;}});createBtn(1001, 200, 200, 500, "red");createBtn(1002, 400, 400, 500, "green");createBtn(1003, 600, 600, 500, "blue");createBtn(1004, 800, 800, 500, "black");createBtn(1005, 1000, 1000, 500, "yellow");createBtn(1006, 400, 800, 500, "purple");}function createBtn(id, x, y, weight, color) {rect = two.makeRectangle(x, y, 200, 200);rect.noStroke();rect.fill = color;rect.myId = id;map.set(rect, weight);}//计算当前屏幕圆心 对应的 图形坐标function getScreenOriginal(){let original = {x: 0,y: 0};original.x = two.width / 2;original.y = two.height / 2;// console.log(two.scene._matrix.elements)//获取水平位移及垂直位移//将浏览器上界面坐标转换为two.js的场景坐标,也就是 cirX和cirY为当前界面中点的场景坐标let cirX = (original.x - two.scene._matrix.elements[2]) / two.scene._matrix.elements[0];let cirY = (original.y - two.scene._matrix.elements[5]) / two.scene._matrix.elements[4];console.log("当前圆心 cirX:" + cirX + " cirY:" + cirY);original.x = cirX;original.y = cirY;return original;}export function flyToPosition(x, y){//当前屏幕中点 对应的 场景坐标let dot = getScreenOriginal();// console.log(dot);let c = two.makeCircle(x, y, 10);c.fill = "red";let differenceValueX = (dot.x - x) * two.scene._matrix.elements[0];let differenceValueY = (dot.y - y) * two.scene._matrix.elements[4];console.log(two.scene._matrix.elements);console.log("差值:"+ differenceValueX + " " + differenceValueY);//飞到对应x,y坐标点,这个x, y将会变成新的屏幕中心点mouse.graphicMove(differenceValueX, differenceValueY);originalPositionX = differenceValueX;originalPositionY = differenceValueY;}

鼠标滚动放缩源码:

(function(Two){let _ = Two.Utils;let Surface = function(object) {this.object = object;};_.extend(Surface.prototype, {limits: function(min, max) {let min_exists = !_.isUndefined(min);let max_exists = !_.isUndefined(max);if (!max_exists && !min_exists) {return { min: this.min, max: this.max };}this.min = min_exists ? min : this.min;this.max = max_exists ? max : this.max;return this;},apply: function(px, py, s) {this.object.translation.set(px, py);this.object.scale = s;return this;}});let ZUI = Two.ZUI = function(group, domElement) {this.limits = {scale: ZUI.Limit.clone(),x: ZUI.Limit.clone(),y: ZUI.Limit.clone()};this.viewport = domElement || document.body;this.viewportOffset = {matrix: new Two.Matrix()};this.surfaceMatrix = new Two.Matrix();this.surfaces = [];this.reset();this.updateSurface();this.add(new Surface(group));};_.extend(ZUI, {Surface: Surface,Clamp: function(v, min, max) {return Math.min(Math.max(v, min), max);},Limit: {min: -Infinity,max: Infinity,clone: function() {let result = {};for (let k in this) {result[k] = this[k];}return result;}},TranslateMatrix: function(m, x, y) {m.elements[2] += x;m.elements[5] += y;return m;},PositionToScale: function(pos){return Math.exp(pos);},ScaleToPosition: function(scale){return Math.log(scale);}});_.extend(ZUI.prototype, {constructor: ZUI,add: function(surface){this.surfaces.push(surface);let limits = surface.limits();this.addLimits(limits.min, limits.max);return this;},addLimits: function(min, max, type) {type = type || 'scale';if (!_.isUndefined(min)){if(this.limits[type].min){this.limits[type].min = Math.max(min, this.limits[type].min);}else{this.limits[type].min = min;}}if(_.isUndefined(max)){return this;}if(this.limits[type].max){this.limits[type].max = Math.min(max, this.limits[type].max);}else{this.limits[type].max = max;}return this;},clientToSurface: function(x, y) {this.updateOffset();let m = this.surfaceMatrix.inverse();let n = this.viewportOffset.matrix.inverse().multiply(x, y, 1);return m.multiply.apply(m, _.toArray(n));},surfaceToClient: function(v) {this.updateOffset();let vo = this.viewportOffset.matrix.clone();let sm = this.surfaceMatrix.multiply.apply(this.surfaceMatrix, _.toArray(v));return vo.multiply.apply(vo, _.toArray(sm));},graphicMove: function(clientX, clientY){let dx = clientX;let dy = clientY;this.translateSurface(dx, dy);return this;},zoomBy: function(byF, clientX, clientY){let s = ZUI.PositionToScale(this.zoom + byF);this.zoomSet(s, clientX, clientY);return this;},zoomSet: function(zoom, clientX, clientY) {let newScale = this.fitToLimits(zoom);this.zoom = ZUI.ScaleToPosition(newScale);if (newScale === this.scale) {return this;}let sf = this.clientToSurface(clientX, clientY);let scaleBy = newScale / this.scale;this.surfaceMatrix.scale(scaleBy);this.scale = newScale;let c = this.surfaceToClient(sf);let dx = clientX - c.x;let dy = clientY - c.y;this.translateSurface(dx, dy);return this;},translateSurface: function(x, y) {ZUI.TranslateMatrix(this.surfaceMatrix, x, y);this.updateSurface();return this;},updateOffset: function() {let rect = this.viewport.getBoundingClientRect();_.extend(this.viewportOffset, rect);this.viewportOffset.left -= document.body.scrollLeft;this.viewportOffset.top -= document.body.scrollTop;this.viewportOffset.matrix.identity().translate(this.viewportOffset.left, this.viewportOffset.top);return this;},updateSurface: function() {let e = this.surfaceMatrix.elements;for(let i = 0; i < this.surfaces.length; i++){this.surfaces[i].apply(e[2], e[5], e[0]);}return this;},reset: function() {this.zoom = 0;this.scale = 1.0;this.surfaceMatrix.identity();return this;},fitToLimits: function(s) {return ZUI.Clamp(s, this.limits.scale.min, this.limits.scale.max);}});})((typeof global !== 'undefined' ? global : (this || window)).Two);

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。