> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/web/browser/event/type/mouse/+ext.md).

# MouseEvent+ext

[browser](/web/browser.md) ⟩ [event](/web/browser/event.md) ⟩ [type](/web/browser/event/type.md) ⟩ [mouse](/web/browser/event/type/mouse.md) ⟩ +ext

{% hint style="success" %}
extend [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent).

```javascript
// 🔸 .pointInViewport
// 🔸 .pointInPage
// 🔸 .pointInScreen
// 🔹 .pointInElement()
```

:point\_right: [custom](/web/appendix/custom.md)
{% endhint %}

{% tabs %}
{% tab title="💾 程式" %}

* replit ⟩ [click to move ball](https://replit.com/@pegasusroe/click-to-move-ball#js/ext/MouseEvent+ext.js)

```javascript
// 2023.01.21 - 12:20 (•) first draft
// -------------------------------------------------------

// ⭐ import
import {vec, linearCombination} from './Vector.js';       // 👔 Vector
// -------------------------------------------------------

// ⭐ MouseEvent + ext
// -------------------------------------------------------
// 🔸 .pointInViewport
// 🔸 .pointInPage
// 🔸 .pointInScreen
// 🔹 .pointInElement()
//
Object.defineProperties(MouseEvent.prototype, {
    
    // 🔸 .pointInViewport
    pointInViewport: {
        get() {
            return vec(this.clientX, this.clientY);
        },
    },

    // 🔸 .pointInPage
    pointInPage: {
        get() {
            return vec(this.pageX, this.pageY);
        },
    },

    // 🔸 .pointInScreen
    pointInScreen: {
        get() {
            return vec(this.screenX, this.screenY);
        },
    },

    // 🔹 .pointInElement()
    // - relative to element's "padding box" origin
    pointInElement: {
        value: function(elem = this.target) {
            const a = this.pointInViewport;
            const b = elem.boundingBox.origin;
            const c = elem.paddingBox.origin;
            // v = a - (b + c)
            return linearCombination([1, -1, -1], [a, b, c]);
        },
    },
    
});

// ⭐ export
export {};        // ES module
```

{% endtab %}

{% tab title="💈範例" %}

* [click to move ball](/web/browser/event/type/mouse/click/click-to-move-ball.md)

replit ⟩ [click to move ball](https://replit.com/@pegasusroe/click-to-move-ball#js/ext/MouseEvent+ext.js) (this example)

```javascript
const { log } = console

// ⭐️ import
import { $ } from './js/ext/Node_ext.js';        // 👔 Node + ext
import { rect } from './js/ext/Rect.js';         // 👔 Rect
import {  } from './js/ext/Element+boxes.js';    // 👔 Element + boxes
import {  } from './js/ext/MouseEvent+ext.js';   // 👔 MouseEvent + ext
// --------------------------------------------------------------------

// elements
const ball = $("#ball");                    // 👔 Node + ext
const field = $("#field");
const info = $("#info");

const ballSize = ball.paddingBox.size;      // 👔 Element + boxes
const {width: w, height: h} = field.paddingBox.size;
const dx = ballSize.width/2;

// ⭐️ event handlers
// -------------------------------------------------------

// field.onclick
field.onclick = (event) => {
    
    // calculate ball's (constrained) new origin
    const {x, y} = event
        // mouse cursor point
        .pointInElement(field)
        // constrain center in "inset" rect
        .clampInRect(rect(dx, dx, w-2*dx, h-2*dx))    // 👔 Rect
        // translate to top left corner
        .plus(ballSize.vector.times(-0.5));
        
    
    // update ball's position
    ball.style.left = x + 'px';
    ball.style.top = y + 'px';
};

// document.onmousemove
document.onmousemove = (e) => {
    info.innerHTML = `• screen: ${e.pointInScreen}<br>` // 👔 MouseEvent + ext
        + `• page  : ${e.pointInPage}<br>`
        + `• viewport: ${e.pointInViewport}<br>`
        + `• field: ${e.pointInElement(field)}`;
};
```

{% endtab %}

{% tab title="🗺️ 圖表" %}
{% embed url="<https://replit.com/@pegasusroe/click-to-move-ball#index.js>" %}
{% endtab %}

{% tab title="📗 參考" %}

* [ ] javascript.info ⟩  intro to browser events ⟩ [moving ball across field](https://javascript.info/introduction-browser-events#move-the-ball-across-the-field) ⭐️ &#x20;
  {% endtab %}

{% tab title="📘 手冊" %}

* [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent)
  {% endtab %}
  {% endtabs %}
