UNPKG

molstar

Version:

A comprehensive macromolecular library.

195 lines 9.27 kB
/** * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import { __assign } from "tslib"; import { Representation } from '../../mol-repr/representation'; import { ModifiersKeys, ButtonsType } from '../../mol-util/input/input-observer'; import { RxEventHelper } from '../../mol-util/rx-event-helper'; import { Vec2, Vec3 } from '../../mol-math/linear-algebra'; import { ParamDefinition as PD } from '../../mol-util/param-definition'; import { Bond } from '../../mol-model/structure'; var tmpPosA = Vec3(); var tmpPos = Vec3(); var tmpNorm = Vec3(); export var Canvas3dInteractionHelperParams = { maxFps: PD.Numeric(30, { min: 10, max: 60, step: 10 }), preferAtomPixelPadding: PD.Numeric(3, { min: 0, max: 20, step: 1 }, { description: 'Number of extra pixels at which to prefer atoms over bonds.' }), }; var Canvas3dInteractionHelper = /** @class */ (function () { function Canvas3dInteractionHelper(canvasIdentify, lociGetter, input, camera, props) { var _this = this; if (props === void 0) { props = {}; } this.canvasIdentify = canvasIdentify; this.lociGetter = lociGetter; this.input = input; this.camera = camera; this.ev = RxEventHelper.create(); this.events = { hover: this.ev(), drag: this.ev(), click: this.ev(), }; this.startX = -1; this.startY = -1; this.endX = -1; this.endY = -1; this.id = void 0; this.position = void 0; this.currentIdentifyT = 0; this.isInteracting = false; this.prevLoci = Representation.Loci.Empty; this.prevT = 0; this.inside = false; this.buttons = ButtonsType.create(0); this.button = ButtonsType.create(0); this.modifiers = ModifiersKeys.None; this.props = __assign(__assign({}, PD.getDefaultValues(Canvas3dInteractionHelperParams)), props); input.drag.subscribe(function (_a) { var x = _a.x, y = _a.y, buttons = _a.buttons, button = _a.button, modifiers = _a.modifiers; _this.isInteracting = true; // console.log('drag'); _this.drag(x, y, buttons, button, modifiers); }); input.move.subscribe(function (_a) { var x = _a.x, y = _a.y, inside = _a.inside, buttons = _a.buttons, button = _a.button, modifiers = _a.modifiers; if (!inside || _this.isInteracting) return; // console.log('move'); _this.move(x, y, buttons, button, modifiers); }); input.leave.subscribe(function () { // console.log('leave'); _this.leave(); }); input.click.subscribe(function (_a) { var x = _a.x, y = _a.y, buttons = _a.buttons, button = _a.button, modifiers = _a.modifiers; if (_this.outsideViewport(x, y)) return; // console.log('click'); _this.click(x, y, buttons, button, modifiers); }); input.interactionEnd.subscribe(function () { // console.log('interactionEnd'); _this.isInteracting = false; }); input.modifiers.subscribe(function (modifiers) { // console.log('modifiers'); _this.modify(modifiers); }); } Canvas3dInteractionHelper.prototype.setProps = function (props) { Object.assign(this.props, props); }; Canvas3dInteractionHelper.prototype.identify = function (e, t) { var xyChanged = this.startX !== this.endX || this.startY !== this.endY; if (e === 2 /* Drag */) { if (xyChanged && !Representation.Loci.isEmpty(this.prevLoci)) { this.events.drag.next({ current: this.prevLoci, buttons: this.buttons, button: this.button, modifiers: this.modifiers, pageStart: Vec2.create(this.startX, this.startY), pageEnd: Vec2.create(this.endX, this.endY) }); this.startX = this.endX; this.startY = this.endY; } return; } if (xyChanged) { var pickData = this.canvasIdentify(this.endX, this.endY); this.id = pickData === null || pickData === void 0 ? void 0 : pickData.id; this.position = pickData === null || pickData === void 0 ? void 0 : pickData.position; this.startX = this.endX; this.startY = this.endY; } if (e === 1 /* Click */) { var loci_1 = this.getLoci(this.id, this.position); this.events.click.next({ current: loci_1, buttons: this.buttons, button: this.button, modifiers: this.modifiers, page: Vec2.create(this.endX, this.endY), position: this.position }); this.prevLoci = loci_1; return; } if (!this.inside || this.currentIdentifyT !== t || !xyChanged || this.outsideViewport(this.endX, this.endY)) return; var loci = this.getLoci(this.id, this.position); this.events.hover.next({ current: loci, buttons: this.buttons, button: this.button, modifiers: this.modifiers, page: Vec2.create(this.endX, this.endY), position: this.position }); this.prevLoci = loci; }; Canvas3dInteractionHelper.prototype.tick = function (t) { if (this.inside && t - this.prevT > 1000 / this.props.maxFps) { this.prevT = t; this.currentIdentifyT = t; this.identify(this.isInteracting ? 2 /* Drag */ : 0 /* Move */, t); } }; Canvas3dInteractionHelper.prototype.leave = function () { this.inside = false; if (!Representation.Loci.isEmpty(this.prevLoci)) { this.prevLoci = Representation.Loci.Empty; this.events.hover.next({ current: this.prevLoci, buttons: this.buttons, button: this.button, modifiers: this.modifiers }); } }; Canvas3dInteractionHelper.prototype.move = function (x, y, buttons, button, modifiers) { this.inside = true; this.buttons = buttons; this.button = button; this.modifiers = modifiers; this.endX = x; this.endY = y; }; Canvas3dInteractionHelper.prototype.click = function (x, y, buttons, button, modifiers) { this.endX = x; this.endY = y; this.buttons = buttons; this.button = button; this.modifiers = modifiers; this.identify(1 /* Click */, 0); }; Canvas3dInteractionHelper.prototype.drag = function (x, y, buttons, button, modifiers) { this.endX = x; this.endY = y; this.buttons = buttons; this.button = button; this.modifiers = modifiers; this.identify(2 /* Drag */, 0); }; Canvas3dInteractionHelper.prototype.modify = function (modifiers) { if (ModifiersKeys.areEqual(modifiers, this.modifiers)) return; this.modifiers = modifiers; this.events.hover.next({ current: this.prevLoci, buttons: this.buttons, button: this.button, modifiers: this.modifiers, page: Vec2.create(this.endX, this.endY), position: this.position }); }; Canvas3dInteractionHelper.prototype.outsideViewport = function (x, y) { var _a = this, input = _a.input, viewport = _a.camera.viewport; x *= input.pixelRatio; y *= input.pixelRatio; return (x > viewport.x + viewport.width || input.height - y > viewport.y + viewport.height || x < viewport.x || input.height - y < viewport.y); }; Canvas3dInteractionHelper.prototype.getLoci = function (pickingId, position) { var _a; var _b = this.lociGetter(pickingId), repr = _b.repr, loci = _b.loci; if (position && repr && Bond.isLoci(loci) && loci.bonds.length === 2) { var _c = loci.bonds[0], aUnit = _c.aUnit, aIndex = _c.aIndex; aUnit.conformation.position(aUnit.elements[aIndex], tmpPosA); Vec3.sub(tmpNorm, this.camera.state.position, this.camera.state.target); Vec3.projectPointOnPlane(tmpPos, position, tmpNorm, tmpPosA); var pixelSize = this.camera.getPixelSize(tmpPos); var radius = repr.theme.size.size(loci.bonds[0]) * ((_a = repr.props.sizeFactor) !== null && _a !== void 0 ? _a : 1); if (repr.props.lineSizeAttenuation === false) { // divide by two to get radius radius *= pixelSize / 2; } radius += this.props.preferAtomPixelPadding * pixelSize; if (Vec3.distance(tmpPos, tmpPosA) < radius) { return { repr: repr, loci: Bond.toFirstStructureElementLoci(loci) }; } } return { repr: repr, loci: loci }; }; Canvas3dInteractionHelper.prototype.dispose = function () { this.ev.dispose(); }; return Canvas3dInteractionHelper; }()); export { Canvas3dInteractionHelper }; //# sourceMappingURL=interaction-events.js.map