Ich habe etwas Ähnliches getan, als ich eine CSS-bezogene Webiste entwickelt habe . Ich musste eine von einem HTML / CSS erzeugte Ausgabe mit einem Bild vergleichen, das zuvor mit einem HTML / CSS erzeugt wurde.
Ich habe Dom-to-Image verwendet , das Code in ein Base64-codiertes Image konvertiert. Ich platziere dieses Bild auf einer Leinwand und verwende dann Pixelmatch , um zwischen beiden Bildern zu vergleichen.
Hier ist ein Beispiel zur Veranschaulichung:
var node1 = document.querySelector("pre");
var node2 = document.querySelector(".div");
var canvas1 = document.querySelector(".first");
var canvas2 = document.querySelector(".second");
var ctx1 = canvas1.getContext("2d");
var ctx2 = canvas2.getContext("2d");
/* Change both code to Image and put inside Canvas */
domtoimage.toPng(node1)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx1.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
domtoimage.toPng(node2)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx2.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
/* Run the pixel matching*/
setTimeout(function() {
var im_r = ctx1.getImageData(0, 0, 300, 300).data;
var im_o = ctx2.getImageData(0, 0, 300, 300).data;
var pixDiff = pixelmatch(im_r, im_o, false, 280, 280, {
threshold: 0.1
});
console.log(pixDiff);
}, 3000);
canvas {
border: 1px solid;
}
pre,
.div {
border: 2px solid red;
width: 300px;
height: 300px;
box-sizing: border-box;
margin: 0;
}
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/dom-to-image.js"></script>
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/pixel.js"></script>
<pre>
sun<br/>
mercury <br/>
venus <br/>
earth <br/>
mars <br/>
jupiter <br/>
saturn <br/>
</pre>
<div class="div" style="font-family:monospace">
<div style="text-indent: 0">sun</div> <br/>
<div style="text-indent: 4ch">mercury</div> <br/>
<div style="text-indent: 4ch">venus</div> <br/>
<div style="text-indent: 8ch">earth</div> <br/>
<div style="text-indent: 8ch">mars</div> <br/>
<div style="text-indent: 12ch">jupiter</div> <br/>
<div style="text-indent: 4ch">saturn</div> <br/>
</div>
<canvas width="300" height="300" class="first"></canvas>
<canvas width="300" height="300" class="second"></canvas>
Im obigen Code haben wir unsere 2 HTML-Blöcke und 2 Leinwände, auf denen wir unsere Blöcke malen werden. Wie Sie sehen können, ist der JS recht einfach. Der Code am Ende führt die Pixelanpassung aus und zeigt, wie viele verschiedene Pixel beide Leinwände haben. Ich habe eine Verzögerung hinzugefügt, um sicherzustellen, dass beide Bilder geladen werden (Sie können sie später bei einigen Ereignissen optimieren).
Sie können auch eine dritte Leinwand in Betracht ziehen, um den Unterschied zwischen beiden Bildern hervorzuheben und Ihren visuellen Unterschied zu erhalten:
var node1 = document.querySelector("pre");
var node2 = document.querySelector(".div");
var canvas1 = document.querySelector(".first");
var canvas2 = document.querySelector(".second");
var canvas3 = document.querySelector(".result");
var ctx1 = canvas1.getContext("2d");
var ctx2 = canvas2.getContext("2d");
var ctx3 = canvas3.getContext("2d");
/* Change both code to Image and put inside Canvas */
domtoimage.toPng(node1)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx1.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
domtoimage.toPng(node2)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx2.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
/* Run the pixel matching*/
setTimeout(function() {
var im_r = ctx1.getImageData(0, 0, 300, 300).data;
var im_o = ctx2.getImageData(0, 0, 300, 300).data;
var diff = ctx3.createImageData(300, 300);
var pixDiff = pixelmatch(im_r, im_o, diff.data, 300, 300, {
threshold: 0.1
});
ctx3.putImageData(diff, 0, 0);
console.log(pixDiff);
}, 3000);
canvas {
border: 1px solid;
}
pre,
.div {
border: 2px solid red;
width: 300px;
height: 300px;
box-sizing: border-box;
margin: 0;
}
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/dom-to-image.js"></script>
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/pixel.js"></script>
<pre>
sun<br/>
mercury <br/>
venus <br/>
earth <br/>
mars <br/>
jupiter <br/>
saturn <br/>
</pre>
<div class="div" style="font-family:monospace">
<div style="text-indent: 0">sun</div> <br/>
<div style="text-indent: 4ch">mercury</div> <br/>
<div style="text-indent: 4ch">venus</div> <br/>
<div style="text-indent: 8ch">earth</div> <br/>
<div style="text-indent: 8ch">mars</div> <br/>
<div style="text-indent: 12ch">jupiter</div> <br/>
<div style="text-indent: 4ch">saturn</div> <br/>
</div>
<canvas width="300" height="300" class="first"></canvas>
<canvas width="300" height="300" class="second"></canvas>
<canvas width="300" height="300" class="result"></canvas>
Lassen Sie uns den Inhalt ändern, um einen Unterschied zu sehen:
var node1 = document.querySelector("pre");
var node2 = document.querySelector(".div");
var canvas1 = document.querySelector(".first");
var canvas2 = document.querySelector(".second");
var canvas3 = document.querySelector(".result");
var ctx1 = canvas1.getContext("2d");
var ctx2 = canvas2.getContext("2d");
var ctx3 = canvas3.getContext("2d");
/* Change both code to Image and put inside Canvas */
domtoimage.toPng(node1)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx1.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
domtoimage.toPng(node2)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx2.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
/* Run the pixel matching*/
setTimeout(function() {
var im_r = ctx1.getImageData(0, 0, 300, 300).data;
var im_o = ctx2.getImageData(0, 0, 300, 300).data;
var diff = ctx3.createImageData(300, 300);
var pixDiff = pixelmatch(im_r, im_o, diff.data, 300, 300, {
threshold: 0.1
});
ctx3.putImageData(diff, 0, 0);
console.log(pixDiff);
}, 3000);
canvas {
border: 1px solid;
}
pre,
.div {
border: 2px solid red;
width: 300px;
height: 300px;
box-sizing: border-box;
margin: 0;
}
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/dom-to-image.js"></script>
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/pixel.js"></script>
<pre>
sun<br/>
mercury <br/>
venus <br/>
earth <br/>
mars <br/>
jupiter <br/>
saturn <br/>
</pre>
<div class="div" style="font-family:monospace">
<div style="text-indent: 0">sun</div> <br/>
<div style="text-indent: 4ch">mercury</div> <br/>
<div style="text-indent: 4ch">venus</div> <br/>
<div style="text-indent: 8ch">earth</div> <br/>
<div style="text-indent: 8ch">april</div> <br/>
<div style="text-indent: 12ch">jupiter</div> <br/>
<div style="text-indent: 4ch">saturn</div> <br/>
</div>
<canvas width="300" height="300" class="first"></canvas>
<canvas width="300" height="300" class="second"></canvas>
<canvas width="300" height="300" class="result"></canvas>
Sie können mehr darüber lesen, wie die beiden von mir verwendeten Plugins funktionieren, und weitere interessante Optionen finden.
Ich korrigiere die Größen auf 300 x 300, um die Demonstration im Snippet zu vereinfachen, aber Sie können eine größere Höhe und Breite in Betracht ziehen.
Aktualisieren
Hier ist ein realistischeres Beispiel für den Vergleich zwischen zwei Layouts, die das gleiche Ergebnis erzielen. Die Breite / Höhe der Leinwand ist dynamisch und basiert auf dem Inhalt. Ich werde nur die letzte Leinwand mit dem Unterschied zeigen.
var node1 = document.querySelector(".flex");
var node2 = document.querySelector(".grid");
var canvas1 = document.querySelector(".first");
var canvas2 = document.querySelector(".second");
var canvas3 = document.querySelector(".result");
canvas1.height= node1.offsetHeight;
canvas2.height= node2.offsetHeight;
canvas3.height= node1.offsetHeight;
canvas1.width= node1.offsetWidth;
canvas2.width= node2.offsetWidth;
canvas3.width= node1.offsetWidth;
var ctx1 = canvas1.getContext("2d");
var ctx2 = canvas2.getContext("2d");
var ctx3 = canvas3.getContext("2d");
domtoimage.toPng(node1)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx1.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
domtoimage.toPng(node2)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx2.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
setTimeout(function() {
var im_r = ctx1.getImageData(0, 0, canvas1.width, canvas1.height).data;
var im_o = ctx2.getImageData(0, 0, canvas1.width, canvas1.height).data;
var diff = ctx3.createImageData(canvas1.width, canvas1.height);
var pixDiff = pixelmatch(im_r, im_o, diff.data, canvas1.width, canvas1.height, {
threshold: 0.2
});
ctx3.putImageData(diff, 0, 0);
console.log(pixDiff);
}, 3000);
.grid {
display:grid;
grid-template-columns:repeat(3,minmax(0,1fr));
border:2px solid red;
}
h1 {
text-align:center;
grid-column:1/-1;
flex-basis:100%;
}
.flex {
display:flex;
flex-wrap:wrap;
border:2px solid red;
}
.flex > div {
flex-grow:1;
flex-basis:0;
}
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/dom-to-image.js"></script>
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/pixel.js"></script>
<div class="grid">
<h1>A title here</h1>
<div>
<img src="https://picsum.photos/id/10/200/200" >
</div>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus aliquam condimentum mollis. Phasellus faucibus diam quis lorem efficitur, id egestas neque malesuada</div>
<div> Maecenas sollicitudin lacinia finibus. Integer vel varius eros. Morbi et ante eget est mollis sollicitudin.</div>
</div>
<div class="flex">
<h1>A title here</h1>
<div>
<img src="https://picsum.photos/id/10/200/200" >
</div>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus aliquam condimentum mollis. Phasellus faucibus diam quis lorem efficitur, id egestas neque malesuada</div>
<div> Maecenas sollicitudin lacinia finibus. Integer vel varius eros. Morbi et ante eget est mollis sollicitudin.</div>
</div>
<canvas width="300" height="300" class="first" style="display:none;"></canvas>
<canvas width="300" height="300" class="second" style="display:none;"></canvas>
<canvas width="300" height="300" class="result"></canvas>
Verwenden wir ein anderes Bild:
var node1 = document.querySelector(".flex");
var node2 = document.querySelector(".grid");
var canvas1 = document.querySelector(".first");
var canvas2 = document.querySelector(".second");
var canvas3 = document.querySelector(".result");
canvas1.height= node1.offsetHeight;
canvas2.height= node2.offsetHeight;
canvas3.height= node1.offsetHeight;
canvas1.width= node1.offsetWidth;
canvas2.width= node2.offsetWidth;
canvas3.width= node1.offsetWidth;
var ctx1 = canvas1.getContext("2d");
var ctx2 = canvas2.getContext("2d");
var ctx3 = canvas3.getContext("2d");
domtoimage.toPng(node1)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx1.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
domtoimage.toPng(node2)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx2.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
setTimeout(function() {
var im_r = ctx1.getImageData(0, 0, canvas1.width, canvas1.height).data;
var im_o = ctx2.getImageData(0, 0, canvas1.width, canvas1.height).data;
var diff = ctx3.createImageData(canvas1.width, canvas1.height);
var pixDiff = pixelmatch(im_r, im_o, diff.data, canvas1.width, canvas1.height, {
threshold: 0.2
});
ctx3.putImageData(diff, 0, 0);
console.log(pixDiff);
}, 3000);
.grid {
display:grid;
grid-template-columns:repeat(3,minmax(0,1fr));
border:2px solid red;
}
h1 {
text-align:center;
grid-column:1/-1;
flex-basis:100%;
}
.flex {
display:flex;
flex-wrap:wrap;
border:2px solid red;
}
.flex > div {
flex-grow:1;
flex-basis:0;
}
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/dom-to-image.js"></script>
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/pixel.js"></script>
<div class="grid">
<h1>A title here</h1>
<div>
<img src="https://picsum.photos/id/10/200/200" >
</div>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus aliquam condimentum mollis. Phasellus faucibus diam quis lorem efficitur, id egestas neque malesuada</div>
<div> Maecenas sollicitudin lacinia finibus. Integer vel varius eros. Morbi et ante eget est mollis sollicitudin.</div>
</div>
<div class="flex">
<h1>A title here</h1>
<div>
<img src="https://picsum.photos/id/12/200/200" >
</div>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus aliquam condimentum mollis. Phasellus faucibus diam quis lorem efficitur, id egestas neque malesuada</div>
<div> Maecenas sollicitudin lacinia finibus. Integer vel varius eros. Morbi et ante eget est mollis sollicitudin.</div>
</div>
<canvas width="300" height="300" class="first" style="display:none;"></canvas>
<canvas width="300" height="300" class="second" style="display:none;"></canvas>
<canvas width="300" height="300" class="result"></canvas>