three-stdlib 2.19.1 → 2.20.1
Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("three");class t extends e.Mesh{constructor(t){const i=new o(t),s=new e.PlaneGeometry(.001*i.image.width,.001*i.image.height),r=new e.MeshBasicMaterial({map:i,toneMapped:!1,transparent:!0});function l(e){r.map.dispatchDOMEvent(e)}super(s,r),this.addEventListener("mousedown",l),this.addEventListener("mousemove",l),this.addEventListener("mouseup",l),this.addEventListener("click",l),this.dispose=function(){s.dispose(),r.dispose(),r.map.dispose(),n.delete(t),this.removeEventListener("mousedown",l),this.removeEventListener("mousemove",l),this.removeEventListener("mouseup",l),this.removeEventListener("click",l)}}}class o extends e.CanvasTexture{constructor(t){super(i(t)),this.dom=t,this.anisotropy=16,this.encoding=e.sRGBEncoding,this.minFilter=e.LinearFilter,this.magFilter=e.LinearFilter;const o=new MutationObserver((()=>{this.scheduleUpdate||(this.scheduleUpdate=setTimeout((()=>this.update()),16))}));o.observe(t,{attributes:!0,childList:!0,subtree:!0,characterData:!0}),this.observer=o}dispatchDOMEvent(e){e.data&&function(e,t,o,n){const i={clientX:o*e.offsetWidth+e.offsetLeft,clientY:n*e.offsetHeight+e.offsetTop,view:e.ownerDocument.defaultView};window.dispatchEvent(new MouseEvent(t,i));const s=e.getBoundingClientRect();function r(e){if(e.nodeType!==Node.TEXT_NODE&&e.nodeType!==Node.COMMENT_NODE){const s=e.getBoundingClientRect();if(o>s.left&&o<s.right&&n>s.top&&n<s.bottom&&(e.dispatchEvent(new MouseEvent(t,i)),e instanceof HTMLInputElement&&"range"===e.type&&("mousedown"===t||"click"===t))){const[t,n]=["min","max"].map((t=>parseFloat(e[t]))),i=s.width,r=(o-s.x)/i;e.value=t+(n-t)*r,e.dispatchEvent(new InputEvent("input",{bubbles:!0}))}for(let t=0;t<e.childNodes.length;t++)r(e.childNodes[t])}}o=o*s.width+s.left,n=n*s.height+s.top,r(e)}(this.dom,e.type,e.data.x,e.data.y)}update(){this.image=i(this.dom),this.needsUpdate=!0,this.scheduleUpdate=null}dispose(){this.observer&&this.observer.disconnect(),this.scheduleUpdate=clearTimeout(this.scheduleUpdate),super.dispose()}}const n=new WeakMap;function i(t){const o=document.createRange(),i=new e.Color;function s(e,t,o,n){""!==n&&("uppercase"===e.textTransform&&(n=n.toUpperCase()),c.font=e.fontWeight+" "+e.fontSize+" "+e.fontFamily,c.textBaseline="top",c.fillStyle=e.color,c.fillText(n,t,o+.1*parseFloat(e.fontSize)))}function r(e,t,o,n,i){o<2*i&&(i=o/2),n<2*i&&(i=n/2),c.beginPath(),c.moveTo(e+i,t),c.arcTo(e+o,t,e+o,t+n,i),c.arcTo(e+o,t+n,e,t+n,i),c.arcTo(e,t+n,e,t,i),c.arcTo(e,t,e+o,t,i),c.closePath()}function l(e,t,o,n,i,s){const r=e[t+"Width"],l=e[t+"Style"],d=e[t+"Color"];"0px"!==r&&"none"!==l&&"transparent"!==d&&"rgba(0, 0, 0, 0)"!==d&&(c.strokeStyle=d,c.lineWidth=parseFloat(r),c.beginPath(),c.moveTo(o,n),c.lineTo(o+i,n+s),c.stroke())}const d=t.getBoundingClientRect();let a=n.get(t);void 0===a&&(a=document.createElement("canvas"),a.width=d.width,a.height=d.height,n.set(t,a));const c=a.getContext("2d"),h=new function(e){const t=[];let o=!1;function n(){if(o&&(o=!1,e.restore()),0===t.length)return;let n=-1/0,i=-1/0,s=1/0,r=1/0;for(let e=0;e<t.length;e++){const o=t[e];n=Math.max(n,o.x),i=Math.max(i,o.y),s=Math.min(s,o.x+o.width),r=Math.min(r,o.y+o.height)}e.save(),e.beginPath(),e.rect(n,i,s-n,r-i),e.clip(),o=!0}return{add:function(e){t.push(e),n()},remove:function(){t.pop(),n()}}}(c);return function e(t,n){let a=0,p=0,f=0,u=0;if(t.nodeType===Node.TEXT_NODE){o.selectNode(t);const e=o.getBoundingClientRect();a=e.left-d.left-.5,p=e.top-d.top-.5,f=e.width,u=e.height,s(n,a,p,t.nodeValue.trim())}else{if(t.nodeType===Node.COMMENT_NODE)return;if(t instanceof HTMLCanvasElement){if("none"===t.style.display)return;c.save();const e=window.devicePixelRatio;c.scale(1/e,1/e),c.drawImage(t,0,0),c.restore()}else{if("none"===t.style.display)return;const e=t.getBoundingClientRect();a=e.left-d.left-.5,p=e.top-d.top-.5,f=e.width,u=e.height,n=window.getComputedStyle(t),r(a,p,f,u,parseFloat(n.borderRadius));const o=n.backgroundColor;"transparent"!==o&&"rgba(0, 0, 0, 0)"!==o&&(c.fillStyle=o,c.fill());const m=["borderTop","borderLeft","borderBottom","borderRight"];let g=!0,v=null;for(const e of m){if(null!==v&&(g=n[e+"Width"]===n[v+"Width"]&&n[e+"Color"]===n[v+"Color"]&&n[e+"Style"]===n[v+"Style"]),!1===g)break;v=e}if(!0===g){const e=parseFloat(n.borderTopWidth);"0px"!==n.borderTopWidth&&"none"!==n.borderTopStyle&&"transparent"!==n.borderTopColor&&"rgba(0, 0, 0, 0)"!==n.borderTopColor&&(c.strokeStyle=n.borderTopColor,c.lineWidth=e,c.stroke())}else l(n,"borderTop",a,p,f,0),l(n,"borderLeft",a,p,0,u),l(n,"borderBottom",a,p+u,f,0),l(n,"borderRight",a+f,p,0,u);if(t instanceof HTMLInputElement){let e=n.accentColor;void 0!==e&&"auto"!==e||(e=n.color),i.set(e);const o=Math.sqrt(.299*i.r**2+.587*i.g**2+.114*i.b**2)<.5?"white":"#111111";if("radio"===t.type&&(r(a,p,f,u,u),c.fillStyle="white",c.strokeStyle=e,c.lineWidth=1,c.fill(),c.stroke(),t.checked&&(r(a+2,p+2,f-4,u-4,u),c.fillStyle=e,c.strokeStyle=o,c.lineWidth=2,c.fill(),c.stroke())),"checkbox"===t.type&&(r(a,p,f,u,2),c.fillStyle=t.checked?e:"white",c.strokeStyle=t.checked?o:e,c.lineWidth=1,c.stroke(),c.fill(),t.checked)){const e=c.textAlign;c.textAlign="center";s({color:o,fontFamily:n.fontFamily,fontSize:u+"px",fontWeight:"bold"},a+f/2,p,"✔"),c.textAlign=e}if("range"===t.type){const[n,i,s]=["min","max","value"].map((e=>parseFloat(t[e]))),l=(s-n)/(i-n)*(f-u);r(a,p+u/4,f,u/2,u/4),c.fillStyle=o,c.strokeStyle=e,c.lineWidth=1,c.fill(),c.stroke(),r(a,p+u/4,l+u/2,u/2,u/4),c.fillStyle=e,c.fill(),r(a+l,p,u,u,u/2),c.fillStyle=e,c.fill()}"color"!==t.type&&"text"!==t.type&&"number"!==t.type||(h.add({x:a,y:p,width:f,height:u}),s(n,a+parseInt(n.paddingLeft),p+parseInt(n.paddingTop),t.value),h.remove())}}}const m="auto"===n.overflow||"hidden"===n.overflow;m&&h.add({x:a,y:p,width:f,height:u});for(let o=0;o<t.childNodes.length;o++)e(t.childNodes[o],n);m&&h.remove()}(t),a}exports.HTMLMesh=t;
|
@@ -0,0 +1,405 @@
|
|
1
|
+
import { Mesh, PlaneGeometry, MeshBasicMaterial, CanvasTexture, sRGBEncoding, LinearFilter, Color } from 'three';
|
2
|
+
|
3
|
+
class HTMLMesh extends Mesh {
|
4
|
+
constructor(dom) {
|
5
|
+
const texture = new HTMLTexture(dom);
|
6
|
+
const geometry = new PlaneGeometry(texture.image.width * 0.001, texture.image.height * 0.001);
|
7
|
+
const material = new MeshBasicMaterial({
|
8
|
+
map: texture,
|
9
|
+
toneMapped: false,
|
10
|
+
transparent: true
|
11
|
+
});
|
12
|
+
super(geometry, material);
|
13
|
+
|
14
|
+
function onEvent(event) {
|
15
|
+
material.map.dispatchDOMEvent(event);
|
16
|
+
}
|
17
|
+
|
18
|
+
this.addEventListener('mousedown', onEvent);
|
19
|
+
this.addEventListener('mousemove', onEvent);
|
20
|
+
this.addEventListener('mouseup', onEvent);
|
21
|
+
this.addEventListener('click', onEvent);
|
22
|
+
|
23
|
+
this.dispose = function () {
|
24
|
+
geometry.dispose();
|
25
|
+
material.dispose();
|
26
|
+
material.map.dispose();
|
27
|
+
canvases.delete(dom);
|
28
|
+
this.removeEventListener('mousedown', onEvent);
|
29
|
+
this.removeEventListener('mousemove', onEvent);
|
30
|
+
this.removeEventListener('mouseup', onEvent);
|
31
|
+
this.removeEventListener('click', onEvent);
|
32
|
+
};
|
33
|
+
}
|
34
|
+
|
35
|
+
}
|
36
|
+
|
37
|
+
class HTMLTexture extends CanvasTexture {
|
38
|
+
constructor(dom) {
|
39
|
+
super(html2canvas(dom));
|
40
|
+
this.dom = dom;
|
41
|
+
this.anisotropy = 16;
|
42
|
+
this.encoding = sRGBEncoding;
|
43
|
+
this.minFilter = LinearFilter;
|
44
|
+
this.magFilter = LinearFilter; // Create an observer on the DOM, and run html2canvas update in the next loop
|
45
|
+
|
46
|
+
const observer = new MutationObserver(() => {
|
47
|
+
if (!this.scheduleUpdate) {
|
48
|
+
// ideally should use xr.requestAnimationFrame, here setTimeout to avoid passing the renderer
|
49
|
+
this.scheduleUpdate = setTimeout(() => this.update(), 16);
|
50
|
+
}
|
51
|
+
});
|
52
|
+
const config = {
|
53
|
+
attributes: true,
|
54
|
+
childList: true,
|
55
|
+
subtree: true,
|
56
|
+
characterData: true
|
57
|
+
};
|
58
|
+
observer.observe(dom, config);
|
59
|
+
this.observer = observer;
|
60
|
+
}
|
61
|
+
|
62
|
+
dispatchDOMEvent(event) {
|
63
|
+
if (event.data) {
|
64
|
+
htmlevent(this.dom, event.type, event.data.x, event.data.y);
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
update() {
|
69
|
+
this.image = html2canvas(this.dom);
|
70
|
+
this.needsUpdate = true;
|
71
|
+
this.scheduleUpdate = null;
|
72
|
+
}
|
73
|
+
|
74
|
+
dispose() {
|
75
|
+
if (this.observer) {
|
76
|
+
this.observer.disconnect();
|
77
|
+
}
|
78
|
+
|
79
|
+
this.scheduleUpdate = clearTimeout(this.scheduleUpdate);
|
80
|
+
super.dispose();
|
81
|
+
}
|
82
|
+
|
83
|
+
} //
|
84
|
+
|
85
|
+
|
86
|
+
const canvases = new WeakMap();
|
87
|
+
|
88
|
+
function html2canvas(element) {
|
89
|
+
const range = document.createRange();
|
90
|
+
const color = new Color();
|
91
|
+
|
92
|
+
function Clipper(context) {
|
93
|
+
const clips = [];
|
94
|
+
let isClipping = false;
|
95
|
+
|
96
|
+
function doClip() {
|
97
|
+
if (isClipping) {
|
98
|
+
isClipping = false;
|
99
|
+
context.restore();
|
100
|
+
}
|
101
|
+
|
102
|
+
if (clips.length === 0) return;
|
103
|
+
let minX = -Infinity,
|
104
|
+
minY = -Infinity;
|
105
|
+
let maxX = Infinity,
|
106
|
+
maxY = Infinity;
|
107
|
+
|
108
|
+
for (let i = 0; i < clips.length; i++) {
|
109
|
+
const clip = clips[i];
|
110
|
+
minX = Math.max(minX, clip.x);
|
111
|
+
minY = Math.max(minY, clip.y);
|
112
|
+
maxX = Math.min(maxX, clip.x + clip.width);
|
113
|
+
maxY = Math.min(maxY, clip.y + clip.height);
|
114
|
+
}
|
115
|
+
|
116
|
+
context.save();
|
117
|
+
context.beginPath();
|
118
|
+
context.rect(minX, minY, maxX - minX, maxY - minY);
|
119
|
+
context.clip();
|
120
|
+
isClipping = true;
|
121
|
+
}
|
122
|
+
|
123
|
+
return {
|
124
|
+
add: function (clip) {
|
125
|
+
clips.push(clip);
|
126
|
+
doClip();
|
127
|
+
},
|
128
|
+
remove: function () {
|
129
|
+
clips.pop();
|
130
|
+
doClip();
|
131
|
+
}
|
132
|
+
};
|
133
|
+
}
|
134
|
+
|
135
|
+
function drawText(style, x, y, string) {
|
136
|
+
if (string !== '') {
|
137
|
+
if (style.textTransform === 'uppercase') {
|
138
|
+
string = string.toUpperCase();
|
139
|
+
}
|
140
|
+
|
141
|
+
context.font = style.fontWeight + ' ' + style.fontSize + ' ' + style.fontFamily;
|
142
|
+
context.textBaseline = 'top';
|
143
|
+
context.fillStyle = style.color;
|
144
|
+
context.fillText(string, x, y + parseFloat(style.fontSize) * 0.1);
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
function buildRectPath(x, y, w, h, r) {
|
149
|
+
if (w < 2 * r) r = w / 2;
|
150
|
+
if (h < 2 * r) r = h / 2;
|
151
|
+
context.beginPath();
|
152
|
+
context.moveTo(x + r, y);
|
153
|
+
context.arcTo(x + w, y, x + w, y + h, r);
|
154
|
+
context.arcTo(x + w, y + h, x, y + h, r);
|
155
|
+
context.arcTo(x, y + h, x, y, r);
|
156
|
+
context.arcTo(x, y, x + w, y, r);
|
157
|
+
context.closePath();
|
158
|
+
}
|
159
|
+
|
160
|
+
function drawBorder(style, which, x, y, width, height) {
|
161
|
+
const borderWidth = style[which + 'Width'];
|
162
|
+
const borderStyle = style[which + 'Style'];
|
163
|
+
const borderColor = style[which + 'Color'];
|
164
|
+
|
165
|
+
if (borderWidth !== '0px' && borderStyle !== 'none' && borderColor !== 'transparent' && borderColor !== 'rgba(0, 0, 0, 0)') {
|
166
|
+
context.strokeStyle = borderColor;
|
167
|
+
context.lineWidth = parseFloat(borderWidth);
|
168
|
+
context.beginPath();
|
169
|
+
context.moveTo(x, y);
|
170
|
+
context.lineTo(x + width, y + height);
|
171
|
+
context.stroke();
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
function drawElement(element, style) {
|
176
|
+
let x = 0,
|
177
|
+
y = 0,
|
178
|
+
width = 0,
|
179
|
+
height = 0;
|
180
|
+
|
181
|
+
if (element.nodeType === Node.TEXT_NODE) {
|
182
|
+
// text
|
183
|
+
range.selectNode(element);
|
184
|
+
const rect = range.getBoundingClientRect();
|
185
|
+
x = rect.left - offset.left - 0.5;
|
186
|
+
y = rect.top - offset.top - 0.5;
|
187
|
+
width = rect.width;
|
188
|
+
height = rect.height;
|
189
|
+
drawText(style, x, y, element.nodeValue.trim());
|
190
|
+
} else if (element.nodeType === Node.COMMENT_NODE) {
|
191
|
+
return;
|
192
|
+
} else if (element instanceof HTMLCanvasElement) {
|
193
|
+
// Canvas element
|
194
|
+
if (element.style.display === 'none') return;
|
195
|
+
context.save();
|
196
|
+
const dpr = window.devicePixelRatio;
|
197
|
+
context.scale(1 / dpr, 1 / dpr);
|
198
|
+
context.drawImage(element, 0, 0);
|
199
|
+
context.restore();
|
200
|
+
} else {
|
201
|
+
if (element.style.display === 'none') return;
|
202
|
+
const rect = element.getBoundingClientRect();
|
203
|
+
x = rect.left - offset.left - 0.5;
|
204
|
+
y = rect.top - offset.top - 0.5;
|
205
|
+
width = rect.width;
|
206
|
+
height = rect.height;
|
207
|
+
style = window.getComputedStyle(element); // Get the border of the element used for fill and border
|
208
|
+
|
209
|
+
buildRectPath(x, y, width, height, parseFloat(style.borderRadius));
|
210
|
+
const backgroundColor = style.backgroundColor;
|
211
|
+
|
212
|
+
if (backgroundColor !== 'transparent' && backgroundColor !== 'rgba(0, 0, 0, 0)') {
|
213
|
+
context.fillStyle = backgroundColor;
|
214
|
+
context.fill();
|
215
|
+
} // If all the borders match then stroke the round rectangle
|
216
|
+
|
217
|
+
|
218
|
+
const borders = ['borderTop', 'borderLeft', 'borderBottom', 'borderRight'];
|
219
|
+
let match = true;
|
220
|
+
let prevBorder = null;
|
221
|
+
|
222
|
+
for (const border of borders) {
|
223
|
+
if (prevBorder !== null) {
|
224
|
+
match = style[border + 'Width'] === style[prevBorder + 'Width'] && style[border + 'Color'] === style[prevBorder + 'Color'] && style[border + 'Style'] === style[prevBorder + 'Style'];
|
225
|
+
}
|
226
|
+
|
227
|
+
if (match === false) break;
|
228
|
+
prevBorder = border;
|
229
|
+
}
|
230
|
+
|
231
|
+
if (match === true) {
|
232
|
+
// They all match so stroke the rectangle from before allows for border-radius
|
233
|
+
const width = parseFloat(style.borderTopWidth);
|
234
|
+
|
235
|
+
if (style.borderTopWidth !== '0px' && style.borderTopStyle !== 'none' && style.borderTopColor !== 'transparent' && style.borderTopColor !== 'rgba(0, 0, 0, 0)') {
|
236
|
+
context.strokeStyle = style.borderTopColor;
|
237
|
+
context.lineWidth = width;
|
238
|
+
context.stroke();
|
239
|
+
}
|
240
|
+
} else {
|
241
|
+
// Otherwise draw individual borders
|
242
|
+
drawBorder(style, 'borderTop', x, y, width, 0);
|
243
|
+
drawBorder(style, 'borderLeft', x, y, 0, height);
|
244
|
+
drawBorder(style, 'borderBottom', x, y + height, width, 0);
|
245
|
+
drawBorder(style, 'borderRight', x + width, y, 0, height);
|
246
|
+
}
|
247
|
+
|
248
|
+
if (element instanceof HTMLInputElement) {
|
249
|
+
let accentColor = style.accentColor;
|
250
|
+
if (accentColor === undefined || accentColor === 'auto') accentColor = style.color;
|
251
|
+
color.set(accentColor);
|
252
|
+
const luminance = Math.sqrt(0.299 * color.r ** 2 + 0.587 * color.g ** 2 + 0.114 * color.b ** 2);
|
253
|
+
const accentTextColor = luminance < 0.5 ? 'white' : '#111111';
|
254
|
+
|
255
|
+
if (element.type === 'radio') {
|
256
|
+
buildRectPath(x, y, width, height, height);
|
257
|
+
context.fillStyle = 'white';
|
258
|
+
context.strokeStyle = accentColor;
|
259
|
+
context.lineWidth = 1;
|
260
|
+
context.fill();
|
261
|
+
context.stroke();
|
262
|
+
|
263
|
+
if (element.checked) {
|
264
|
+
buildRectPath(x + 2, y + 2, width - 4, height - 4, height);
|
265
|
+
context.fillStyle = accentColor;
|
266
|
+
context.strokeStyle = accentTextColor;
|
267
|
+
context.lineWidth = 2;
|
268
|
+
context.fill();
|
269
|
+
context.stroke();
|
270
|
+
}
|
271
|
+
}
|
272
|
+
|
273
|
+
if (element.type === 'checkbox') {
|
274
|
+
buildRectPath(x, y, width, height, 2);
|
275
|
+
context.fillStyle = element.checked ? accentColor : 'white';
|
276
|
+
context.strokeStyle = element.checked ? accentTextColor : accentColor;
|
277
|
+
context.lineWidth = 1;
|
278
|
+
context.stroke();
|
279
|
+
context.fill();
|
280
|
+
|
281
|
+
if (element.checked) {
|
282
|
+
const currentTextAlign = context.textAlign;
|
283
|
+
context.textAlign = 'center';
|
284
|
+
const properties = {
|
285
|
+
color: accentTextColor,
|
286
|
+
fontFamily: style.fontFamily,
|
287
|
+
fontSize: height + 'px',
|
288
|
+
fontWeight: 'bold'
|
289
|
+
};
|
290
|
+
drawText(properties, x + width / 2, y, '✔');
|
291
|
+
context.textAlign = currentTextAlign;
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
if (element.type === 'range') {
|
296
|
+
const [min, max, value] = ['min', 'max', 'value'].map(property => parseFloat(element[property]));
|
297
|
+
const position = (value - min) / (max - min) * (width - height);
|
298
|
+
buildRectPath(x, y + height / 4, width, height / 2, height / 4);
|
299
|
+
context.fillStyle = accentTextColor;
|
300
|
+
context.strokeStyle = accentColor;
|
301
|
+
context.lineWidth = 1;
|
302
|
+
context.fill();
|
303
|
+
context.stroke();
|
304
|
+
buildRectPath(x, y + height / 4, position + height / 2, height / 2, height / 4);
|
305
|
+
context.fillStyle = accentColor;
|
306
|
+
context.fill();
|
307
|
+
buildRectPath(x + position, y, height, height, height / 2);
|
308
|
+
context.fillStyle = accentColor;
|
309
|
+
context.fill();
|
310
|
+
}
|
311
|
+
|
312
|
+
if (element.type === 'color' || element.type === 'text' || element.type === 'number') {
|
313
|
+
clipper.add({
|
314
|
+
x: x,
|
315
|
+
y: y,
|
316
|
+
width: width,
|
317
|
+
height: height
|
318
|
+
});
|
319
|
+
drawText(style, x + parseInt(style.paddingLeft), y + parseInt(style.paddingTop), element.value);
|
320
|
+
clipper.remove();
|
321
|
+
}
|
322
|
+
}
|
323
|
+
}
|
324
|
+
/*
|
325
|
+
// debug
|
326
|
+
context.strokeStyle = '#' + Math.random().toString( 16 ).slice( - 3 );
|
327
|
+
context.strokeRect( x - 0.5, y - 0.5, width + 1, height + 1 );
|
328
|
+
*/
|
329
|
+
|
330
|
+
|
331
|
+
const isClipping = style.overflow === 'auto' || style.overflow === 'hidden';
|
332
|
+
if (isClipping) clipper.add({
|
333
|
+
x: x,
|
334
|
+
y: y,
|
335
|
+
width: width,
|
336
|
+
height: height
|
337
|
+
});
|
338
|
+
|
339
|
+
for (let i = 0; i < element.childNodes.length; i++) {
|
340
|
+
drawElement(element.childNodes[i], style);
|
341
|
+
}
|
342
|
+
|
343
|
+
if (isClipping) clipper.remove();
|
344
|
+
}
|
345
|
+
|
346
|
+
const offset = element.getBoundingClientRect();
|
347
|
+
let canvas = canvases.get(element);
|
348
|
+
|
349
|
+
if (canvas === undefined) {
|
350
|
+
canvas = document.createElement('canvas');
|
351
|
+
canvas.width = offset.width;
|
352
|
+
canvas.height = offset.height;
|
353
|
+
canvases.set(element, canvas);
|
354
|
+
}
|
355
|
+
|
356
|
+
const context = canvas.getContext('2d'
|
357
|
+
/*, { alpha: false }*/
|
358
|
+
);
|
359
|
+
const clipper = new Clipper(context); // console.time( 'drawElement' );
|
360
|
+
|
361
|
+
drawElement(element); // console.timeEnd( 'drawElement' );
|
362
|
+
|
363
|
+
return canvas;
|
364
|
+
}
|
365
|
+
|
366
|
+
function htmlevent(element, event, x, y) {
|
367
|
+
const mouseEventInit = {
|
368
|
+
clientX: x * element.offsetWidth + element.offsetLeft,
|
369
|
+
clientY: y * element.offsetHeight + element.offsetTop,
|
370
|
+
view: element.ownerDocument.defaultView
|
371
|
+
};
|
372
|
+
window.dispatchEvent(new MouseEvent(event, mouseEventInit));
|
373
|
+
const rect = element.getBoundingClientRect();
|
374
|
+
x = x * rect.width + rect.left;
|
375
|
+
y = y * rect.height + rect.top;
|
376
|
+
|
377
|
+
function traverse(element) {
|
378
|
+
if (element.nodeType !== Node.TEXT_NODE && element.nodeType !== Node.COMMENT_NODE) {
|
379
|
+
const rect = element.getBoundingClientRect();
|
380
|
+
|
381
|
+
if (x > rect.left && x < rect.right && y > rect.top && y < rect.bottom) {
|
382
|
+
element.dispatchEvent(new MouseEvent(event, mouseEventInit));
|
383
|
+
|
384
|
+
if (element instanceof HTMLInputElement && element.type === 'range' && (event === 'mousedown' || event === 'click')) {
|
385
|
+
const [min, max] = ['min', 'max'].map(property => parseFloat(element[property]));
|
386
|
+
const width = rect.width;
|
387
|
+
const offsetX = x - rect.x;
|
388
|
+
const proportion = offsetX / width;
|
389
|
+
element.value = min + (max - min) * proportion;
|
390
|
+
element.dispatchEvent(new InputEvent('input', {
|
391
|
+
bubbles: true
|
392
|
+
}));
|
393
|
+
}
|
394
|
+
}
|
395
|
+
|
396
|
+
for (let i = 0; i < element.childNodes.length; i++) {
|
397
|
+
traverse(element.childNodes[i]);
|
398
|
+
}
|
399
|
+
}
|
400
|
+
}
|
401
|
+
|
402
|
+
traverse(element);
|
403
|
+
}
|
404
|
+
|
405
|
+
export { HTMLMesh };
|