import { assert } from 'chai'; import KonvaModule from '../../src/index'; import '../../src/index-node'; export const Konva = KonvaModule; import * as canvas from 'canvas'; Konva.enableTrace = true; Konva.showWarnings = true; import { imagediff } from './imagediff'; import { Layer } from '../../src/Layer'; import { Stage } from '../../src/Stage'; // reset some data beforeEach(function () { Konva._mouseInDblClickWindow = false; Konva._touchInDblClickWindow = false; Konva._pointerInDblClickWindow = false; }); // clear after test afterEach(function () { var isFailed = this.currentTest.state == 'failed'; var isManual = this.currentTest.parent.title === 'Manual'; Konva.stages.forEach(function (stage) { clearTimeout(stage._mouseDblTimeout); clearTimeout(stage._touchDblTimeout); clearTimeout(stage._pointerDblTimeout); }); if (!isFailed && !isManual) { Konva.stages.forEach(function (stage) { stage.destroy(); }); if (Konva.DD._dragElements.size) { throw 'Why drag elements are not cleaned?'; } } }); export const isNode = typeof global.document === 'undefined'; export const isBrowser = !isNode; export function getContainer() { return document.getElementById('konva-container'); } export function addContainer() { if (isNode) { return; } var container = document.createElement('div'); getContainer().appendChild(container); return container; } export function addStage(attrs?) { var container = (!isNode && global.document.createElement('div')) || undefined; var stage = new Konva.Stage({ container: container, width: 578, height: 200, ...attrs, }); if (!isNode) { getContainer().appendChild(container); } return stage; } export function loadImage(url, callback) { const isBase64 = url.indexOf('base64') >= 0; if (isNode && !isBase64) { url = './test/assets/' + url; } else if (!isBase64) { url = (document.getElementById(url) as HTMLImageElement).src; } return canvas .loadImage(url) .then(callback) .catch((e) => { console.error(e); }); } export function getPixelRatio() { return (typeof window !== 'undefined' && window.devicePixelRatio) || 1; } function get(element, content?) { element = document.createElement(element); if (element && content) { element.innerHTML = content; } return element; } export function compareCanvases(canvas1, canvas2, tol?, secondTol?) { // don't test in PhantomJS as it use old chrome engine // it it has opacity + shadow bug var equal = imagediff.equal(canvas1, canvas2, tol, secondTol); if (!equal) { const diff = imagediff.diff(canvas1, canvas2); const diffCanvas = createCanvas(); const context = diffCanvas.getContext('2d'); context.putImageData(diff, 0, 0); var base64 = diffCanvas.toDataURL(); console.error('Diff image:'); console.error(base64); if (isBrowser) { var div = get('div'), b = get('div', '
Expected:
'), c = get('div', '
Diff:
'); div.style.overflow = 'hidden'; b.style.float = 'left'; c.style.float = 'left'; canvas2.style.position = ''; canvas2.style.display = ''; b.appendChild(canvas2); c.appendChild(diffCanvas); div.appendChild(b); div.appendChild(c); getContainer().appendChild(div); } } assert.equal( equal, true, 'Result from Konva is different with canvas result' ); } export function compareLayerAndCanvas(layer: Layer, canvas, tol?, secondTol?) { compareCanvases(layer.getNativeCanvasElement(), canvas, tol, secondTol); } export function cloneAndCompareLayer(layer: Layer, tol?, secondTol?) { var layer2 = layer.clone(); layer.getStage().add(layer2); layer2.hide(); compareLayers(layer, layer2, tol, secondTol); } export function compareLayers(layer1: Layer, layer2: Layer, tol?, secondTol?) { compareLayerAndCanvas( layer1, layer2.getNativeCanvasElement(), tol, secondTol ); } export function createCanvas() { var node = canvas.createCanvas(300, 300); node.width = 578 * Konva.pixelRatio; node.height = 200 * Konva.pixelRatio; node.getContext('2d').scale(Konva.pixelRatio, Konva.pixelRatio); return node; } export function showHit(layer) { if (isNode) { return; } var canvas = layer.hitCanvas._canvas; canvas.style.position = 'relative'; getContainer().appendChild(canvas); } export function simulateMouseDown(stage, pos) { simulatePointerDown(stage, pos); var top = isNode ? 0 : stage.content.getBoundingClientRect().top; stage._pointerdown({ clientX: pos.x, clientY: pos.y + top, button: pos.button || 0, type: 'mousedown', }); } export function simulateMouseMove(stage, pos) { simulatePointerMove(stage, pos); var top = isNode ? 0 : stage.content.getBoundingClientRect().top; var evt = { clientX: pos.x, clientY: pos.y + top, button: pos.button || 0, type: 'mousemove', }; Konva.DD._drag(evt); stage._pointermove(evt); } export function simulateMouseUp(stage, pos) { simulatePointerUp(stage, pos); var top = isNode ? 0 : stage.content.getBoundingClientRect().top; var evt = { clientX: pos.x, clientY: pos.y + top, button: pos.button || 0, type: 'mouseup', }; Konva.DD._endDragBefore(evt); stage._pointerup(evt); Konva.DD._endDragAfter(evt); } export function simulateTouchStart(stage, pos, changed?) { var top = isNode ? 0 : stage.content.getBoundingClientRect().top; var touches; var changedTouches; if (Array.isArray(pos)) { touches = pos.map(function (touch) { return { identifier: touch.id, clientX: touch.x, clientY: touch.y + top, }; }); changedTouches = (changed || pos).map(function (touch) { return { identifier: touch.id, clientX: touch.x, clientY: touch.y + top, }; }); } else { changedTouches = touches = [ { clientX: pos.x, clientY: pos.y + top, id: 0, }, ]; } var evt = { touches: touches, changedTouches: changedTouches, type: 'touchstart', }; stage._pointerdown(evt); } export function simulateTouchMove(stage, pos, changed?) { var top = isNode ? 0 : stage.content.getBoundingClientRect().top; var touches; var changedTouches; if (Array.isArray(pos)) { touches = pos.map(function (touch) { return { identifier: touch.id, clientX: touch.x, clientY: touch.y + top, }; }); changedTouches = (changed || pos).map(function (touch) { return { identifier: touch.id, clientX: touch.x, clientY: touch.y + top, }; }); } else { changedTouches = touches = [ { clientX: pos.x, clientY: pos.y + top, id: 0, }, ]; } var evt = { touches: touches, changedTouches: changedTouches, type: 'touchmove', }; stage._pointermove(evt); Konva.DD._drag(evt); } export function simulateTouchEnd(stage, pos, changed?) { var top = isNode ? 0 : stage.content.getBoundingClientRect().top; var touches; var changedTouches; if (Array.isArray(pos)) { touches = pos.map(function (touch) { return { identifier: touch.id, clientX: touch.x, clientY: touch.y + top, }; }); changedTouches = (changed || pos).map(function (touch) { return { identifier: touch.id, clientX: touch.x, clientY: touch.y + top, }; }); } else { changedTouches = touches = [ { clientX: pos.x, clientY: pos.y + top, id: 0, }, ]; } var evt = { touches: touches, changedTouches: changedTouches, type: 'touchend', }; Konva.DD._endDragBefore(evt); stage._pointerup(evt); Konva.DD._endDragAfter(evt); } export function simulatePointerDown(stage: Stage, pos) { var top = isNode ? 0 : stage.content.getBoundingClientRect().top; stage._pointerdown({ clientX: pos.x, clientY: pos.y + top, button: pos.button || 0, pointerId: pos.pointerId || 1, type: 'pointerdown', } as any); } export function simulatePointerMove(stage: Stage, pos) { var top = isNode ? 0 : stage.content.getBoundingClientRect().top; var evt = { clientX: pos.x, clientY: pos.y + top, button: pos.button || 0, pointerId: pos.pointerId || 1, type: 'pointermove', }; stage._pointermove(evt as any); // Konva.DD._drag(evt); } export function simulatePointerUp(stage: Stage, pos) { var top = isNode ? 0 : stage.content.getBoundingClientRect().top; var evt = { clientX: pos.x, clientY: pos.y + top, button: pos.button || 0, pointerId: pos.pointerId || 1, type: 'pointerup', }; // Konva.DD._endDragBefore(evt); stage._pointerup(evt as any); // Konva.DD._endDragAfter(evt); } function isClose(a, b) { return Math.abs(a - b) < 0.000001; } export const assertAlmostEqual = function (val1, val2) { if (!isClose(val1, val2)) { throw new Error('Expected ' + val1 + ' to be almost equal to ' + val2); } }; export const assertAlmostDeepEqual = function (obj1, obj2) { for (var key1 in obj1) { assertAlmostEqual(obj1[key1], obj2[key1]); } };