UNPKG

@meta2d/core

Version:

@meta2d/core: Powerful, Beautiful, Simple, Open - Web-Based 2D At Its Best .

388 lines 14.4 kB
import { setElemPosition } from '../pen'; import { deepClone, getRootDomain } from '../utils'; const iframes = {}; export function clearIframes() { for (const key in iframes) { iframes[key]?.remove(); iframes[key] = null; } iframes; } export function updateIframes(pens) { for (const key in iframes) { if (!pens.some((pen) => pen.name == 'iframe' && pen.iframe == key)) { iframes[key]?.remove(); iframes[key] = null; } } } function matchIframe(pen) { const div = iframes[pen.iframe]; if (div) { pen.calculative.singleton.div = div; generateAroundDiv(pen); return true; } return false; } export function iframe(pen) { if (!pen.onDestroy) { pen.onDestroy = destory; pen.onMove = move; pen.onResize = move; pen.onRotate = move; pen.onValue = move; pen.onMouseMove = mouseMove; pen.onBeforeValue = beforeValue; pen.onRenderPenRaw = renderPenRaw; } if (!pen.calculative.singleton) { pen.calculative.singleton = {}; } const worldRect = pen.calculative.worldRect; if (!pen.calculative.singleton.div) { if (matchIframe(pen)) { return; } const div = document.createElement('div'); div.style.position = 'absolute'; div.style.outline = 'none'; div.style.left = '-9999px'; div.style.top = '-9999px'; div.style.width = worldRect.width + 'px'; div.style.height = worldRect.height + 'px'; pen.calculative.canvas.externalElements?.parentElement.appendChild(div); setElemPosition(pen, div); pen.calculative.singleton.div = div; const iframe = document.createElement('iframe'); iframe.style.width = '100%'; iframe.style.height = '100%'; iframe.scrolling = pen.scrolling || 'no'; iframe.frameBorder = '0'; iframe.style.border = 'none'; iframe.src = pen.iframe; iframe.allowFullscreen = true; pen.calculative.iframe = pen.iframe; div.appendChild(iframe); generateAroundDiv(pen); iframe.onload = () => { iframe.setAttribute('document.domain', ''); }; } if (pen.calculative.patchFlags) { setElemPosition(pen, pen.calculative.singleton.div); } pen.onRenderPenRaw(pen); return new Path2D(); } function destory(pen) { updatePointerEvents(pen); if (pen.calculative.singleton && pen.calculative.singleton.div) { if (!pen.calculative.canvas.store.data.locked) { // 手动删除iframe pen.calculative.singleton.div.remove(); iframes[pen.calculative.iframe] = null; } else { iframes[pen.calculative.iframe] = pen.calculative.singleton.div; delete pen.calculative.singleton.div; } } } function move(pen) { pen.calculative.singleton.div && setElemPosition(pen, pen.calculative.singleton.div); } function beforeValue(pen, value) { if (value.iframe) { if (pen.calculative.singleton.div) { pen.calculative.singleton.div.children[0].src = value.iframe; pen.calculative.iframe = value.iframe; } } if (value.operationalRect || value['operationalRect.x'] !== undefined || value['operationalRect.y'] !== undefined || value['operationalRect.width'] !== undefined || value['operationalRect.height'] !== undefined) { if (!pen.operationalRect) { pen.operationalRect = {}; } let _value = deepClone(value); if (!_value.operationalRect) { _value.operationalRect = {}; } if (_value['operationalRect.x'] !== undefined) { _value.operationalRect.x = _value['operationalRect.x']; } if (_value['operationalRect.y'] !== undefined) { _value.operationalRect.y = _value['operationalRect.y']; } if (_value['operationalRect.width'] !== undefined) { _value.operationalRect.width = _value['operationalRect.width']; } if (_value['operationalRect.height'] !== undefined) { _value.operationalRect.height = _value['operationalRect.height']; } Object.assign(pen.operationalRect, _value.operationalRect); if (pen.calculative.singleton.div) { let length = pen.calculative.singleton.div.children.length; if (length === 1) { //没有创建 generateAroundDiv(pen); } else { //有更新值 pen.calculative.singleton.div.children[1].style.height = pen.operationalRect.y * 100 + '%'; pen.calculative.singleton.div.children[1].style.left = pen.operationalRect.x * 100 + '%'; pen.calculative.singleton.div.children[1].style.width = pen.operationalRect.width * 100 + '%'; pen.calculative.singleton.div.children[2].style.width = (1 - pen.operationalRect.x - pen.operationalRect.width) * 100 + '%'; pen.calculative.singleton.div.children[3].style.height = (1 - pen.operationalRect.y - pen.operationalRect.height) * 100 + '%'; pen.calculative.singleton.div.children[3].style.left = pen.operationalRect.x * 100 + '%'; pen.calculative.singleton.div.children[3].style.width = pen.operationalRect.width * 100 + '%'; pen.calculative.singleton.div.children[4].style.width = pen.operationalRect.x * 100 + '%'; } } } if (value.blur !== undefined) { for (let i = 1; i < 5; i++) { pen.calculative.singleton.div.children[i] && (pen.calculative.singleton.div.children[i].style['backdrop-filter'] = `blur(${value.blur}px)`); } } if (value.blurBackground !== undefined) { for (let i = 1; i < 5; i++) { pen.calculative.singleton.div.children[i] && (pen.calculative.singleton.div.children[i].style.backgroundColor = value.blurBackground); } } return value; } function mouseMove(pen, e) { if (!pen.calculative.canvas.store.data.locked && !pen.locked) { return; } if (initOperationalRect(pen.operationalRect)) { if (pen.calculative.zIndex < 5 && e.x > pen.x + pen.width * pen.operationalRect.x && e.x < pen.x + pen.width * (pen.operationalRect.x + pen.operationalRect.width) && e.y > pen.y + pen.height * pen.operationalRect.y && e.y < pen.y + pen.height * (pen.operationalRect.y + pen.operationalRect.height)) { if (pen.calculative.singleton.div) { let children = pen.calculative.singleton.div.parentNode.children; for (let i = 0; i < 6; i++) { children[i].style.pointerEvents = 'none'; } } } } } function initOperationalRect(operationalRect) { if (operationalRect) { if (!operationalRect.width || !operationalRect.height) { return false; } //默认居中 if (operationalRect.x === undefined) { operationalRect.x = (1 - operationalRect.width) / 2; } if (operationalRect.y === undefined) { operationalRect.y = (1 - operationalRect.height) / 2; } return true; } else { return false; } } function removeAllButFirst(parent) { while (parent.childNodes.length > 1) { parent.removeChild(parent.lastChild); } } function generateAroundDiv(pen) { if (!initOperationalRect(pen.operationalRect)) { return; } const div = pen.calculative.singleton.div; if (!div) { return; } div.childNodes.length > 1 && removeAllButFirst(div); const isLinux = navigator.userAgent.indexOf('Linux') > -1; //Kylin OS会闪屏 const top = document.createElement('div'); top.style.position = 'absolute'; top.style.left = pen.operationalRect.x * 100 + '%'; top.style.top = '0px'; top.style.width = pen.operationalRect.width * 100 + '%'; top.style.height = pen.operationalRect.y * 100 + '%'; if (!isLinux && pen.blur) { top.style['backdrop-filter'] = `blur(${pen.blur}px)`; } top.style.backgroundColor = pen.blurBackground; div.appendChild(top); const right = document.createElement('div'); right.style.position = 'absolute'; right.style.right = '0px'; right.style.top = '0px'; right.style.width = (1 - pen.operationalRect.x - pen.operationalRect.width) * 100 + '%'; right.style.height = '100%'; if (!isLinux && pen.blur) { right.style['backdrop-filter'] = `blur(${pen.blur}px)`; } right.style.backgroundColor = pen.blurBackground; div.appendChild(right); const bottom = document.createElement('div'); bottom.style.position = 'absolute'; bottom.style.left = pen.operationalRect.x * 100 + '%'; bottom.style.bottom = '0px'; bottom.style.width = pen.operationalRect.width * 100 + '%'; bottom.style.height = (1 - pen.operationalRect.y - pen.operationalRect.height) * 100 + '%'; if (!isLinux && pen.blur) { bottom.style['backdrop-filter'] = `blur(${pen.blur}px)`; } bottom.style.backgroundColor = pen.blurBackground; div.appendChild(bottom); const left = document.createElement('div'); left.style.position = 'absolute'; left.style.left = '0px'; left.style.top = '0px'; left.style.width = pen.operationalRect.x * 100 + '%'; left.style.height = '100%'; if (!isLinux && pen.blur) { left.style['backdrop-filter'] = `blur(${pen.blur}px)`; } left.style.backgroundColor = pen.blurBackground; div.appendChild(left); let mouseEnter = () => { updatePointerEvents(pen); }; top.onmouseenter = mouseEnter; bottom.onmouseenter = mouseEnter; right.onmouseenter = mouseEnter; left.onmouseenter = mouseEnter; div.onmouseleave = mouseEnter; // } } function updatePointerEvents(pen) { if (!pen.calculative.canvas.store.data.locked && !pen.locked) { return; } if (pen.calculative.zIndex < 5) { let children = pen.calculative.singleton.div.parentNode.children; for (let i = 1; i < 6; i++) { children[i].style.pointerEvents = 'initial'; } } } function renderPenRaw(pen) { if (pen.thumbImg) { if (!pen.calculative.img) { const img = new Image(); img.crossOrigin = pen.crossOrigin === 'undefined' ? undefined : pen.crossOrigin || pen.calculative.canvas.store.options.crossOrigin || 'anonymous'; if (pen.calculative.canvas.store.options.cdn && !(pen.thumbImg.startsWith('http') || pen.thumbImg.startsWith('//') || pen.thumbImg.startsWith('data:image'))) { img.src = pen.calculative.canvas.store.options.cdn + pen.thumbImg; } else { img.src = pen.thumbImg; } img.onerror = (e) => { img.remove(); pen.calculative.img = undefined; }; pen.calculative.img = img; } } else { // if (pen.calculative.singleton && pen.calculative.singleton.div) { // try { // // handleSaveImg(pen); // } catch (e) { // console.warn(e); // pen.calculative.img = null; // } // } } } async function handleSaveImg(pen) { let iframeHtml = pen.calculative.singleton.div.children[0].contentWindow; const iframeBody = iframeHtml.document.getElementsByTagName('body')[0]; const iframeScrollY = iframeHtml.document.documentElement.scrollTop; const iframeScrollX = iframeHtml.document.documentElement.scrollLeft; var fillContent = document.createElement('div'); // 把需要转换成图片的元素内容赋给创建的元素 fillContent.innerHTML = iframeBody.outerHTML; document.body.appendChild(fillContent); iframeHtml.document.domain = getRootDomain(); if (globalThis.html2canvas) { const canvas = await globalThis.html2canvas(fillContent, { allowTaint: true, useCORS: true, width: pen.width, // TODO 截屏按照1920*1080分辨率下的预览窗口宽高 height: pen.height, x: iframeScrollX, y: iframeScrollY, // foreignObjectRendering: true, }); // canvas.getContext('2d', { // willReadFrequently: true, // }); const img = new Image(); img.crossOrigin = pen.crossOrigin === 'undefined' ? undefined : pen.crossOrigin || pen.calculative.canvas.store.options.crossOrigin || 'anonymous'; img.src = canvas.toDataURL('image/png', 0.1); if (img.src.length > 10) { pen.calculative.img = img; } document.body.removeChild(fillContent); } // globalThis.html2canvas && // globalThis // .html2canvas(iframeBody, { // allowTaint: true, // useCORS: true, // width: pen.width, // TODO 截屏按照1920*1080分辨率下的预览窗口宽高 // height: pen.height, // x: iframeScrollX, // y: iframeScrollY, // foreignObjectRendering: true, // }) // .then((canvas) => { // // 转成图片,生成图片地址 // // imgBase64 = canvas.toDataURL('image/png'); // const img = new Image(); // img.crossOrigin = // pen.crossOrigin === 'undefined' // ? undefined // : pen.crossOrigin || 'anonymous'; // img.src = canvas.toDataURL('image/png', 0.1); // if (img.src.length > 10) { // pen.calculative.img = img; // } // }) // .catch((e) => { // console.warn(e); // }); } //# sourceMappingURL=iframe.js.map