Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!DOCTYPE html>
<html>
<head>
<title>Canvas Transform: Automatic update via drawElementImage and DrawElementImageOptions</title>
<link rel="help" href="https://github.com/WICG/html-in-canvas">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/html/canvas/resources/wait-for-canvas-paint.js"></script>
</head>
<body style="margin: 0;">
<canvas id="canvas" style="position: absolute; left: 0; top: 0; width: 400px; height: 400px;" width="400" height="400" layoutsubtree>
<div id="target" style="position: absolute; left: 0; top: 0; width: 100px; height: 50px; transform-origin: 0 0;"></div>
</canvas>
<script>
'use strict';
promise_test(async (t) => {
const canvas = document.getElementById('canvas');
const target = document.getElementById('target');
const ctx = canvas.getContext('2d');
t.add_cleanup(() => canvas.clearElementGeometry(target));
await waitForCanvasPaint(canvas);
assert_true(canvas.getElementTransform(target).isIdentity, 'Initial canvas transform is identity');
assert_equals(target.getBoundingClientRect().left, 0);
assert_equals(target.getBoundingClientRect().top, 0);
// Default options ({preserveElementGeometry: false}).
ctx.drawElementImage(target, 30, 40);
assert_array_equals(canvas.getElementTransform(target).toFloat64Array(),
new DOMMatrix().translate(30, 40).toFloat64Array(),
'target canvas transform matches drawn position');
const rect = target.getBoundingClientRect();
assert_equals(rect.left, 30);
assert_equals(rect.top, 40);
}, 'drawElementImage() automatically updates element canvas transform by default');
promise_test(async (t) => {
const canvas = document.getElementById('canvas');
const target = document.getElementById('target');
const ctx = canvas.getContext('2d');
t.add_cleanup(() => canvas.clearElementGeometry(target));
await waitForCanvasPaint(canvas);
ctx.drawElementImage(target, 50, 60, {preserveElementGeometry: false});
assert_array_equals(canvas.getElementTransform(target).toFloat64Array(),
new DOMMatrix().translate(50, 60).toFloat64Array(),
'target canvas transform matches drawn position with preserveElementGeometry: false');
const rect = target.getBoundingClientRect();
assert_equals(rect.left, 50);
assert_equals(rect.top, 60);
}, 'drawElementImage() updates element canvas transform with explicit {preserveElementGeometry: false}');
promise_test(async (t) => {
const canvas = document.getElementById('canvas');
const target = document.getElementById('target');
const ctx = canvas.getContext('2d');
t.add_cleanup(() => canvas.clearElementGeometry(target));
await waitForCanvasPaint(canvas);
canvas.updateElementGeometry(target, {canvasTransform: new DOMMatrix().translate(10, 20)});
const initialTransform = canvas.getElementTransform(target);
const initialRect = target.getBoundingClientRect();
ctx.drawElementImage(target, 100, 120, {preserveElementGeometry: true});
assert_array_equals(canvas.getElementTransform(target).toFloat64Array(), initialTransform.toFloat64Array(),
'target canvas transform is unchanged when preserveElementGeometry is true');
const rect = target.getBoundingClientRect();
assert_equals(rect.left, initialRect.left);
assert_equals(rect.top, initialRect.top);
assert_equals(rect.width, initialRect.width);
assert_equals(rect.height, initialRect.height);
}, 'drawElementImage() does not update element canvas transform with {preserveElementGeometry: true}');
promise_test(async (t) => {
const canvas = document.getElementById('canvas');
const target = document.getElementById('target');
const ctx = canvas.getContext('2d');
t.add_cleanup(() => canvas.clearElementGeometry(target));
await waitForCanvasPaint(canvas);
// Overload: (element, dx, dy, dwidth, dheight, [options])
ctx.drawElementImage(target, 20, 30, 200, 100);
assert_array_equals(canvas.getElementTransform(target).toFloat64Array(),
new DOMMatrix().translate(20, 30).scale(2, 2).toFloat64Array());
let rect = target.getBoundingClientRect();
assert_equals(rect.left, 20);
assert_equals(rect.top, 30);
assert_equals(rect.width, 200);
assert_equals(rect.height, 100);
const prevTransform = canvas.getElementTransform(target);
ctx.drawElementImage(target, 80, 90, 300, 150, {preserveElementGeometry: true});
assert_array_equals(canvas.getElementTransform(target).toFloat64Array(), prevTransform.toFloat64Array());
rect = target.getBoundingClientRect();
assert_equals(rect.left, 20);
assert_equals(rect.top, 30);
assert_equals(rect.width, 200);
assert_equals(rect.height, 100);
}, 'drawElementImage() with destination size overload (4 arguments)');
promise_test(async (t) => {
const canvas = document.getElementById('canvas');
const target = document.getElementById('target');
const ctx = canvas.getContext('2d');
t.add_cleanup(() => canvas.clearElementGeometry(target));
await waitForCanvasPaint(canvas);
// Overload: (element, sx, sy, swidth, sheight, dx, dy, [options])
ctx.drawElementImage(target, 0, 0, 100, 50, 40, 50);
assert_array_equals(canvas.getElementTransform(target).toFloat64Array(),
new DOMMatrix().translate(40, 50).toFloat64Array());
let rect = target.getBoundingClientRect();
assert_equals(rect.left, 40);
assert_equals(rect.top, 50);
const prevTransform = canvas.getElementTransform(target);
ctx.drawElementImage(target, 0, 0, 100, 50, 80, 90, {preserveElementGeometry: true});
assert_array_equals(canvas.getElementTransform(target).toFloat64Array(), prevTransform.toFloat64Array());
rect = target.getBoundingClientRect();
assert_equals(rect.left, 40);
assert_equals(rect.top, 50);
}, 'drawElementImage() with source rect overload (6 arguments)');
promise_test(async (t) => {
const canvas = document.getElementById('canvas');
const target = document.getElementById('target');
const ctx = canvas.getContext('2d');
t.add_cleanup(() => canvas.clearElementGeometry(target));
await waitForCanvasPaint(canvas);
// Overload: (element, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, [options])
ctx.drawElementImage(target, 0, 0, 100, 50, 15, 25, 200, 100);
assert_array_equals(canvas.getElementTransform(target).toFloat64Array(),
new DOMMatrix().translate(15, 25).scale(2, 2).toFloat64Array());
let rect = target.getBoundingClientRect();
assert_equals(rect.left, 15);
assert_equals(rect.top, 25);
assert_equals(rect.width, 200);
assert_equals(rect.height, 100);
const prevTransform = canvas.getElementTransform(target);
ctx.drawElementImage(target, 0, 0, 100, 50, 70, 80, 300, 150, {preserveElementGeometry: true});
assert_array_equals(canvas.getElementTransform(target).toFloat64Array(), prevTransform.toFloat64Array());
rect = target.getBoundingClientRect();
assert_equals(rect.left, 15);
assert_equals(rect.top, 25);
assert_equals(rect.width, 200);
assert_equals(rect.height, 100);
}, 'drawElementImage() with source and destination rect overload (8 arguments)');
</script>
</body>
</html>