From f26f29d84e0a68831a6af14dab3eec5500496d2e Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期三, 28 五月 2025 16:48:52 +0800
Subject: [PATCH] 初始化项目

---
 static/common/js/touch-emulator.js |  363 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 363 insertions(+), 0 deletions(-)

diff --git a/static/common/js/touch-emulator.js b/static/common/js/touch-emulator.js
new file mode 100644
index 0000000..9632413
--- /dev/null
+++ b/static/common/js/touch-emulator.js
@@ -0,0 +1,363 @@
+(function(window, document, exportName, undefined) {
+    "use strict";
+
+    var isMultiTouch = false;
+    var multiTouchStartPos;
+    var eventTarget;
+    var touchElements = {};
+
+    // polyfills
+    if(!document.createTouch) {
+        document.createTouch = function(view, target, identifier, pageX, pageY, screenX, screenY, clientX, clientY) {
+            // auto set
+            if(clientX == undefined || clientY == undefined) {
+                clientX = pageX - window.pageXOffset;
+                clientY = pageY - window.pageYOffset;
+            }
+
+            return new Touch(target, identifier, {
+                pageX: pageX,
+                pageY: pageY,
+                screenX: screenX,
+                screenY: screenY,
+                clientX: clientX,
+                clientY: clientY
+            });
+        };
+    }
+
+    if(!document.createTouchList) {
+        document.createTouchList = function() {
+            var touchList = new TouchList();
+            for (var i = 0; i < arguments.length; i++) {
+                touchList[i] = arguments[i];
+            }
+            touchList.length = arguments.length;
+            return touchList;
+        };
+    }
+
+    /**
+     * create an touch point
+     * @constructor
+     * @param target
+     * @param identifier
+     * @param pos
+     * @param deltaX
+     * @param deltaY
+     * @returns {Object} touchPoint
+     */
+    function Touch(target, identifier, pos, deltaX, deltaY) {
+        deltaX = deltaX || 0;
+        deltaY = deltaY || 0;
+
+        this.identifier = identifier;
+        this.target = target;
+        this.clientX = pos.clientX + deltaX;
+        this.clientY = pos.clientY + deltaY;
+        this.screenX = pos.screenX + deltaX;
+        this.screenY = pos.screenY + deltaY;
+        this.pageX = pos.pageX + deltaX;
+        this.pageY = pos.pageY + deltaY;
+    }
+
+    /**
+     * create empty touchlist with the methods
+     * @constructor
+     * @returns touchList
+     */
+    function TouchList() {
+        var touchList = [];
+
+        touchList.item = function(index) {
+            return this[index] || null;
+        };
+
+        // specified by Mozilla
+        touchList.identifiedTouch = function(id) {
+            return this[id + 1] || null;
+        };
+
+        return touchList;
+    }
+
+
+    /**
+     * Simple trick to fake touch event support
+     * this is enough for most libraries like Modernizr and Hammer
+     */
+    function fakeTouchSupport() {
+        var objs = [window, document.documentElement];
+        var props = ['ontouchstart', 'ontouchmove', 'ontouchcancel', 'ontouchend'];
+
+        for(var o=0; o<objs.length; o++) {
+            for(var p=0; p<props.length; p++) {
+                if(objs[o] && objs[o][props[p]] == undefined) {
+                    objs[o][props[p]] = null;
+                }
+            }
+        }
+    }
+
+    /**
+     * we don't have to emulate on a touch device
+     * @returns {boolean}
+     */
+    function hasTouchSupport() {
+        return ("ontouchstart" in window) || // touch events
+               (window.Modernizr && window.Modernizr.touch) || // modernizr
+               (navigator.msMaxTouchPoints || navigator.maxTouchPoints) > 2; // pointer events
+    }
+
+    /**
+     * disable mouseevents on the page
+     * @param ev
+     */
+    function preventMouseEvents(ev) {
+		// 娉ㄩ噴鍚敤榛樿浜嬩欢
+        // ev.preventDefault();
+        // ev.stopPropagation();
+    }
+
+    /**
+     * only trigger touches when the left mousebutton has been pressed
+     * @param touchType
+     * @returns {Function}
+     */
+    function onMouse(touchType) {
+        return function(ev) {
+            // prevent mouse events
+            preventMouseEvents(ev);
+
+            if (ev.which !== 1) {
+                return;
+            }
+
+            // The EventTarget on which the touch point started when it was first placed on the surface,
+            // even if the touch point has since moved outside the interactive area of that element.
+            // also, when the target doesnt exist anymore, we update it
+            if (ev.type == 'mousedown' || !eventTarget || (eventTarget && !eventTarget.dispatchEvent)) {
+                eventTarget = ev.target;
+            }
+
+            // shiftKey has been lost, so trigger a touchend
+            if (isMultiTouch && !ev.shiftKey) {
+                triggerTouch('touchend', ev);
+                isMultiTouch = false;
+            }
+
+            triggerTouch(touchType, ev);
+
+            // we're entering the multi-touch mode!
+            if (!isMultiTouch && ev.shiftKey) {
+                isMultiTouch = true;
+                multiTouchStartPos = {
+                    pageX: ev.pageX,
+                    pageY: ev.pageY,
+                    clientX: ev.clientX,
+                    clientY: ev.clientY,
+                    screenX: ev.screenX,
+                    screenY: ev.screenY
+                };
+                triggerTouch('touchstart', ev);
+            }
+
+            // reset
+            if (ev.type == 'mouseup') {
+                multiTouchStartPos = null;
+                isMultiTouch = false;
+                eventTarget = null;
+            }
+        }
+    }
+
+    /**
+     * trigger a touch event
+     * @param eventName
+     * @param mouseEv
+     */
+    function triggerTouch(eventName, mouseEv) {
+        var touchEvent = document.createEvent('Event');
+        touchEvent.initEvent(eventName, true, true);
+
+        touchEvent.altKey = mouseEv.altKey;
+        touchEvent.ctrlKey = mouseEv.ctrlKey;
+        touchEvent.metaKey = mouseEv.metaKey;
+        touchEvent.shiftKey = mouseEv.shiftKey;
+
+        touchEvent.touches = getActiveTouches(mouseEv, eventName);
+        touchEvent.targetTouches = getActiveTouches(mouseEv, eventName);
+        touchEvent.changedTouches = getChangedTouches(mouseEv, eventName);
+
+        eventTarget.dispatchEvent(touchEvent);
+    }
+
+    /**
+     * create a touchList based on the mouse event
+     * @param mouseEv
+     * @returns {TouchList}
+     */
+    function createTouchList(mouseEv) {
+        var touchList = new TouchList();
+
+        if (isMultiTouch) {
+            var f = TouchEmulator.multiTouchOffset;
+            var deltaX = multiTouchStartPos.pageX - mouseEv.pageX;
+            var deltaY = multiTouchStartPos.pageY - mouseEv.pageY;
+
+            touchList.push(new Touch(eventTarget, 1, multiTouchStartPos, (deltaX*-1) - f, (deltaY*-1) + f));
+            touchList.push(new Touch(eventTarget, 2, multiTouchStartPos, deltaX+f, deltaY-f));
+        } else {
+            touchList.push(new Touch(eventTarget, 1, mouseEv, 0, 0));
+        }
+
+        return touchList;
+    }
+
+    /**
+     * receive all active touches
+     * @param mouseEv
+     * @returns {TouchList}
+     */
+    function getActiveTouches(mouseEv, eventName) {
+        // empty list
+        if (mouseEv.type == 'mouseup') {
+            return new TouchList();
+        }
+
+        var touchList = createTouchList(mouseEv);
+        if(isMultiTouch && mouseEv.type != 'mouseup' && eventName == 'touchend') {
+            touchList.splice(1, 1);
+        }
+        return touchList;
+    }
+
+    /**
+     * receive a filtered set of touches with only the changed pointers
+     * @param mouseEv
+     * @param eventName
+     * @returns {TouchList}
+     */
+    function getChangedTouches(mouseEv, eventName) {
+        var touchList = createTouchList(mouseEv);
+
+        // we only want to return the added/removed item on multitouch
+        // which is the second pointer, so remove the first pointer from the touchList
+        //
+        // but when the mouseEv.type is mouseup, we want to send all touches because then
+        // no new input will be possible
+        if(isMultiTouch && mouseEv.type != 'mouseup' &&
+            (eventName == 'touchstart' || eventName == 'touchend')) {
+            touchList.splice(0, 1);
+        }
+
+        return touchList;
+    }
+
+    /**
+     * show the touchpoints on the screen
+     */
+    function showTouches(ev) {
+        var touch, i, el, styles;
+
+        // first all visible touches
+        for(i = 0; i < ev.touches.length; i++) {
+            touch = ev.touches[i];
+            el = touchElements[touch.identifier];
+            if(!el) {
+                el = touchElements[touch.identifier] = document.createElement("div");
+                document.body.appendChild(el);
+            }
+
+            styles = TouchEmulator.template(touch);
+            for(var prop in styles) {
+                el.style[prop] = styles[prop];
+            }
+        }
+
+        // remove all ended touches
+        if(ev.type == 'touchend' || ev.type == 'touchcancel') {
+            for(i = 0; i < ev.changedTouches.length; i++) {
+                touch = ev.changedTouches[i];
+                el = touchElements[touch.identifier];
+                if(el) {
+                    el.parentNode.removeChild(el);
+                    delete touchElements[touch.identifier];
+                }
+            }
+        }
+    }
+
+    /**
+     * TouchEmulator initializer
+     */
+    function TouchEmulator() {
+        if (hasTouchSupport()) {
+            return;
+        }
+
+        fakeTouchSupport();
+
+        window.addEventListener("mousedown", onMouse('touchstart'), true);
+        window.addEventListener("mousemove", onMouse('touchmove'), true);
+        window.addEventListener("mouseup", onMouse('touchend'), true);
+
+        window.addEventListener("mouseenter", preventMouseEvents, true);
+        window.addEventListener("mouseleave", preventMouseEvents, true);
+        window.addEventListener("mouseout", preventMouseEvents, true);
+        window.addEventListener("mouseover", preventMouseEvents, true);
+
+        // it uses itself!
+        window.addEventListener("touchstart", showTouches, true);
+        window.addEventListener("touchmove", showTouches, true);
+        window.addEventListener("touchend", showTouches, true);
+        window.addEventListener("touchcancel", showTouches, true);
+    }
+
+    // start distance when entering the multitouch mode
+    TouchEmulator.multiTouchOffset = 75;
+
+    /**
+     * css template for the touch rendering
+     * @param touch
+     * @returns object
+     */
+    TouchEmulator.template = function(touch) {
+        var size = 0;
+        var transform = 'translate('+ (touch.clientX-(size/2)) +'px, '+ (touch.clientY-(size/2)) +'px)';
+        return {
+            position: 'fixed',
+            left: 0,
+            top: 0,
+            background: '#fff',
+            border: 'solid 1px #999',
+            opacity: .6,
+            borderRadius: '100%',
+            height: size + 'px',
+            width: size + 'px',
+            padding: 0,
+            margin: 0,
+            display: 'block',
+            overflow: 'hidden',
+            pointerEvents: 'none',
+            webkitUserSelect: 'none',
+            mozUserSelect: 'none',
+            userSelect: 'none',
+            webkitTransform: transform,
+            mozTransform: transform,
+            transform: transform,
+            zIndex: 100
+        }
+    };
+
+    // export
+    if (typeof define == "function" && define.amd) {
+        define(function() {
+            return TouchEmulator;
+        });
+    } else if (typeof module != "undefined" && module.exports) {
+        module.exports = TouchEmulator;
+    } else {
+        window[exportName] = TouchEmulator;
+    }
+})(window, document, "TouchEmulator");
\ No newline at end of file

--
Gitblit v1.9.3