使用 html2canvas 截取用 css 包裹在杯子周围的图像结果
Capturing an image wrapped around a mug with css using html2canvas results cut up
我正在尝试捕捉我第一次使用 CSS 生成的图像。
CSS生成的图片是这样的..
并且当前的 html2canvas 输出是...
目前我试过的代码如下...
html2canvas(document.querySelector("#capture"), {
allowTaint: true
}).then(canvas => {
document.body.appendChild(canvas)
});
body {
background: #0000007a;
}
h1 {
font: small-caps 167% Arial, Helvetica, sans-serif
}
#container {
margin-left: -56px;
top: 450px;
width: 550px;
-moz-perspective: 800px;
-webkit-perspective: 800px;
margin-top: 130px;
}
#container:hover * {
-moz-animation-play-state: paused;
-webkit-animation-play-state: paused
}
#frame {
margin-top: 95px;
width: 23px;
-moz-transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
/* translate must be last */
-moz-transform: rotateX(-1deg) rotateY(45deg) rotateZ(0deg) translate3d(325px, -70px, 50px);
-webkit-transform: rotateX(-1deg) rotateY(45deg) rotateZ(0deg) translate3d(325px, -70px, 50px)
}
.strip {
-moz-transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
animation: spin 0.01s forwards;
}
.mastercontainer {
width: 400px;
height: 400px;
display: inline-block;
overflow: hidden;
}
.strip div {
position: absolute;
background: #000 url(http://automation.stickermonkey.shop/codeplayground/images/djmug2.jpg);
border: solid rgb(145, 87, 0);
border-width: thin 0;
height: 275px;
width: 34px;
opacity: 1;
}
.strip .a {
background-position: 0 0;
-moz-transform: rotateY(0deg) translateZ(124px);
-webkit-transform: rotateY(0deg) translateZ(124px)
}
.strip .b {
background-position: 759px 0;
-moz-transform: rotateY(15deg) translateZ(124px);
-webkit-transform: rotateY(15deg) translateZ(124px)
}
.strip .c {
background-position: 726px 0;
-moz-transform: rotateY(30deg) translateZ(124px);
-webkit-transform: rotateY(30deg) translateZ(124px)
}
.strip .d {
background-position: 693px 0;
-moz-transform: rotateY(45deg) translateZ(124px);
-webkit-transform: rotateY(45deg) translateZ(124px)
}
.strip .e {
background-position: 660px 0;
-moz-transform: rotateY(60deg) translateZ(124px);
-webkit-transform: rotateY(60deg) translateZ(124px)
}
.strip .f {
background-position: 627px 0;
-moz-transform: rotateY(75deg) translateZ(124px);
-webkit-transform: rotateY(75deg) translateZ(124px)
}
.strip .g {
background-position: 594px 0;
-moz-transform: rotateY(90deg) translateZ(124px);
-webkit-transform: rotateY(90deg) translateZ(124px)
}
.strip .h {
background-position: 561px 0;
-moz-transform: rotateY(105deg) translateZ(124px);
-webkit-transform: rotateY(105deg) translateZ(124px)
}
.strip .i {
background-position: 528px 0;
-moz-transform: rotateY(120deg) translateZ(124px);
-webkit-transform: rotateY(120deg) translateZ(124px)
}
.strip .j {
background-position: 495px 0;
-moz-transform: rotateY(135deg) translateZ(124px);
-webkit-transform: rotateY(135deg) translateZ(124px)
}
.strip .k {
background-position: 462px 0;
-moz-transform: rotateY(150deg) translateZ(124px);
-webkit-transform: rotateY(150deg) translateZ(124px)
}
.strip .l {
background-position: 429px 0;
-moz-transform: rotateY(165deg) translateZ(124px);
-webkit-transform: rotateY(165deg) translateZ(124px)
}
.strip .m {
background-position: 396px 0;
-moz-transform: rotateY(180deg) translateZ(124px);
-webkit-transform: rotateY(180deg) translateZ(124px)
}
.strip .n {
background-position: 363px 0;
-moz-transform: rotateY(195deg) translateZ(124px);
-webkit-transform: rotateY(195deg) translateZ(124px)
}
.strip .o {
background-position: 330px 0;
-moz-transform: rotateY(210deg) translateZ(124px);
-webkit-transform: rotateY(210deg) translateZ(124px)
}
.strip .p {
background-position: 297px 0;
-moz-transform: rotateY(225deg) translateZ(124px);
-webkit-transform: rotateY(225deg) translateZ(124px)
}
.strip .q {
background-position: 264px 0;
-moz-transform: rotateY(240deg) translateZ(124px);
-webkit-transform: rotateY(240deg) translateZ(124px)
}
.strip .r {
background-position: 231px 0;
-moz-transform: rotateY(255deg) translateZ(124px);
-webkit-transform: rotateY(255deg) translateZ(124px)
}
.strip .s {
background-position: 198px 0;
-moz-transform: rotateY(270deg) translateZ(124px);
-webkit-transform: rotateY(270deg) translateZ(124px)
}
.strip .t {
background-position: 165px 0;
-moz-transform: rotateY(285deg) translateZ(124px);
-webkit-transform: rotateY(285deg) translateZ(124px)
}
.strip .u {
background-position: 132px 0;
-moz-transform: rotateY(300deg) translateZ(124px);
-webkit-transform: rotateY(300deg) translateZ(124px)
}
.strip .v {
background-position: 99px 0;
-moz-transform: rotateY(315deg) translateZ(124px);
-webkit-transform: rotateY(315deg) translateZ(124px)
}
.strip .w {
background-position: 66px 0;
-moz-transform: rotateY(330deg) translateZ(124px);
-webkit-transform: rotateY(330deg) translateZ(124px)
}
.strip .x {
background-position: 33px 0;
-moz-transform: rotateY(345deg) translateZ(124px);
-webkit-transform: rotateY(345deg) translateZ(124px)
}
@-moz-keyframes spin {
from {
-moz-transform: rotateY(360deg)
}
to {
-moz-transform: rotateY(230deg)
}
}
@-webkit-keyframes spin {
from {
-webkit-transform: rotateY(360deg)
}
to {
-webkit-transform: rotateY(230deg)
}
}
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<div id="capture" class="mastercontainer">
<div id="container">
<div id="frame">
<div class="strip">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
<div class="d"></div>
<div class="e"></div>
<div class="f"></div>
<div class="g"></div>
<div class="h"></div>
<div class="i"></div>
<div class="j"></div>
<div class="k"></div>
<div class="l"></div>
<div class="m"></div>
<div class="n"></div>
<div class="o"></div>
<div class="p"></div>
<div class="q"></div>
<div class="r"></div>
<div class="s"></div>
<div class="t"></div>
<div class="u"></div>
<div class="v"></div>
<div class="w"></div>
<div class="x"></div>
</div>
</div>
</div>
</div>
我已经把所有东西都放到了这里的 jsfiddle 中..
https://jsfiddle.net/StickerMonkey/tLqrdey5/4/
编辑添加:
我也试过 foreignObjectRendering: true
这给出了正确的形状但是是一个涂黑的图像。
要添加的第二次编辑;
我也乐于接受另一种方法的建议,将矩形图像包裹在杯子周围或另一种截屏方式或以其他方式抓取我已经生成的图像。
这是一个使用 Three.js 的例子。
它创建了一个带有彩绘杯子旋转视图的场景。
它还在新的 canvas 中以 60° 旋转拍摄快照。
它还在白色背景的第三个 canvas 中单独显示油漆。
//Moved to <script type="module">
//import * as THREE from 'https://cdn.skypack.dev/three';
function actualCode(THREE) {
//Variables for rendering
const renderer = new THREE.WebGLRenderer({
antialias: true
});
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(30, 400.0 / 400, 1, 1000);
//Object variables
let texture;
let paintedMug;
//Preload image, then trigger rendering
const loader = new THREE.TextureLoader();
//Real URL triggers cross origin error in tests:
// texture = loader.load("http://automation.stickermonkey.shop/codeplayground/images/djmug2.jpg", function(_tex) {
//Hosting it on local server works:
// texture = loader.load("./djmug2.jpg", function(_tex) {
//Example with image hosted from Imgur:
texture = loader.load("https://i.imgur.com/TQZrUSP.jpeg", function(_tex) {
// /*Debugging:*/ setTimeout(() => document.body.appendChild(texture.image), 100);
init();
snapShot(60);
renderImageSolo(60);
render();
});
function init() {
//Init scene and camera
camera.position.set(0, 1.3, 11);
camera.lookAt(scene.position);
renderer.setSize(400, 400);
addTitle("Animated scene:");
document.body.appendChild(renderer.domElement);
//Set an ambient light
const light = new THREE.AmbientLight(0xffffff); // soft white light
scene.add(light);
//Draw white mug
const muggeom = new THREE.CylinderGeometry(1.5, 1.5, 3.5, 240, 1);
const mugmaterial = new THREE.MeshStandardMaterial({
color: "#fff",
});
const mug = new THREE.Mesh(muggeom, mugmaterial);
//Draw painting on mug with slightly larger radius
const paintgeom = new THREE.CylinderGeometry(1.5001, 1.5001, 3.3, 240, 1, true);
const paintmaterial = new THREE.MeshStandardMaterial({
map: texture,
});
const paint = new THREE.Mesh(paintgeom, paintmaterial);
//Define a group as mug + paint
paintedMug = new THREE.Group();
paintedMug.add(mug);
paintedMug.add(paint);
//Add group to scene
scene.add(paintedMug);
}
function render() {
try {
//Draw
renderer.render(scene, camera);
//Rotate a bit at each frame
paintedMug.rotation.y += -.01
//Trigger next animation frame (default 60fps)
requestAnimationFrame(render);
} catch (err) {
console.log(err, err.message);
}
}
function snapShot(angle) {
const orgAngle = paintedMug.rotation.y;
//Rotate objects by angle
paintedMug.rotation.y = angle;
//render once
renderer.render(scene, camera);
//Take still into new canvas
var canvas = document.createElement("canvas");
canvas.width = renderer.domElement.width;
canvas.height = renderer.domElement.height;
canvas.getContext("2d").drawImage(renderer.domElement, 0, 0);
canvas.style.marginTop = "1em"; //Space out canvas
addTitle(`Snapshot at ${angle}°:`);
document.body.append(canvas);
//Restore rotation
paintedMug.rotation.y = orgAngle;
}
function renderImageSolo(angle) {
//Init just like main renderer / scene, will use same camera
const solo_renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true });
solo_renderer.setSize(renderer.domElement.width, renderer.domElement.height);
solo_renderer.domElement.style.marginTop = "1em"; //Space out canvas
addTitle(`Paint alone at ${angle}°:`);
document.body.appendChild(solo_renderer.domElement);
const solo_scene = new THREE.Scene();
//Set an ambient light
const light = new THREE.AmbientLight(0xffffff); // soft white light
solo_scene.add(light);
//Draw painting alone
const paintgeom = new THREE.CylinderGeometry(1.5, 1.5, 3.3, 240, 1, true);
const paintmaterial = new THREE.MeshStandardMaterial({
map: texture,
});
const paint = new THREE.Mesh(paintgeom, paintmaterial);
//Add paint to scene
solo_scene.add(paint);
//Rotate paint by angle
paint.rotation.y = angle
//Draw result
solo_scene.background = new THREE.Color(0xffffff);
solo_renderer.render(solo_scene, camera);
}
function addTitle(title) {
const h2 = document.createElement('h2');
h2.innerText = title;
document.body.appendChild(h2);
}
}
<!-- Below code is just a workaround for ES6 imports in SO snippet -->
<script type="module"> //Forced to put import in HTML section, as SO snippet does not support ES6 module loading
import * as THREE from 'https://cdn.skypack.dev/three';
document.addEventListener("DOMContentLoaded", _e => actualCode(THREE));
</script>
由于 CORS 策略,使用来自另一台服务器的原始图像时出现问题。我已经使用托管在 Imgur 上的副本设置示例,但还包括原始位置的代码(请参阅评论)。
我正在尝试捕捉我第一次使用 CSS 生成的图像。
CSS生成的图片是这样的..
并且当前的 html2canvas 输出是...
目前我试过的代码如下...
html2canvas(document.querySelector("#capture"), {
allowTaint: true
}).then(canvas => {
document.body.appendChild(canvas)
});
body {
background: #0000007a;
}
h1 {
font: small-caps 167% Arial, Helvetica, sans-serif
}
#container {
margin-left: -56px;
top: 450px;
width: 550px;
-moz-perspective: 800px;
-webkit-perspective: 800px;
margin-top: 130px;
}
#container:hover * {
-moz-animation-play-state: paused;
-webkit-animation-play-state: paused
}
#frame {
margin-top: 95px;
width: 23px;
-moz-transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
/* translate must be last */
-moz-transform: rotateX(-1deg) rotateY(45deg) rotateZ(0deg) translate3d(325px, -70px, 50px);
-webkit-transform: rotateX(-1deg) rotateY(45deg) rotateZ(0deg) translate3d(325px, -70px, 50px)
}
.strip {
-moz-transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
animation: spin 0.01s forwards;
}
.mastercontainer {
width: 400px;
height: 400px;
display: inline-block;
overflow: hidden;
}
.strip div {
position: absolute;
background: #000 url(http://automation.stickermonkey.shop/codeplayground/images/djmug2.jpg);
border: solid rgb(145, 87, 0);
border-width: thin 0;
height: 275px;
width: 34px;
opacity: 1;
}
.strip .a {
background-position: 0 0;
-moz-transform: rotateY(0deg) translateZ(124px);
-webkit-transform: rotateY(0deg) translateZ(124px)
}
.strip .b {
background-position: 759px 0;
-moz-transform: rotateY(15deg) translateZ(124px);
-webkit-transform: rotateY(15deg) translateZ(124px)
}
.strip .c {
background-position: 726px 0;
-moz-transform: rotateY(30deg) translateZ(124px);
-webkit-transform: rotateY(30deg) translateZ(124px)
}
.strip .d {
background-position: 693px 0;
-moz-transform: rotateY(45deg) translateZ(124px);
-webkit-transform: rotateY(45deg) translateZ(124px)
}
.strip .e {
background-position: 660px 0;
-moz-transform: rotateY(60deg) translateZ(124px);
-webkit-transform: rotateY(60deg) translateZ(124px)
}
.strip .f {
background-position: 627px 0;
-moz-transform: rotateY(75deg) translateZ(124px);
-webkit-transform: rotateY(75deg) translateZ(124px)
}
.strip .g {
background-position: 594px 0;
-moz-transform: rotateY(90deg) translateZ(124px);
-webkit-transform: rotateY(90deg) translateZ(124px)
}
.strip .h {
background-position: 561px 0;
-moz-transform: rotateY(105deg) translateZ(124px);
-webkit-transform: rotateY(105deg) translateZ(124px)
}
.strip .i {
background-position: 528px 0;
-moz-transform: rotateY(120deg) translateZ(124px);
-webkit-transform: rotateY(120deg) translateZ(124px)
}
.strip .j {
background-position: 495px 0;
-moz-transform: rotateY(135deg) translateZ(124px);
-webkit-transform: rotateY(135deg) translateZ(124px)
}
.strip .k {
background-position: 462px 0;
-moz-transform: rotateY(150deg) translateZ(124px);
-webkit-transform: rotateY(150deg) translateZ(124px)
}
.strip .l {
background-position: 429px 0;
-moz-transform: rotateY(165deg) translateZ(124px);
-webkit-transform: rotateY(165deg) translateZ(124px)
}
.strip .m {
background-position: 396px 0;
-moz-transform: rotateY(180deg) translateZ(124px);
-webkit-transform: rotateY(180deg) translateZ(124px)
}
.strip .n {
background-position: 363px 0;
-moz-transform: rotateY(195deg) translateZ(124px);
-webkit-transform: rotateY(195deg) translateZ(124px)
}
.strip .o {
background-position: 330px 0;
-moz-transform: rotateY(210deg) translateZ(124px);
-webkit-transform: rotateY(210deg) translateZ(124px)
}
.strip .p {
background-position: 297px 0;
-moz-transform: rotateY(225deg) translateZ(124px);
-webkit-transform: rotateY(225deg) translateZ(124px)
}
.strip .q {
background-position: 264px 0;
-moz-transform: rotateY(240deg) translateZ(124px);
-webkit-transform: rotateY(240deg) translateZ(124px)
}
.strip .r {
background-position: 231px 0;
-moz-transform: rotateY(255deg) translateZ(124px);
-webkit-transform: rotateY(255deg) translateZ(124px)
}
.strip .s {
background-position: 198px 0;
-moz-transform: rotateY(270deg) translateZ(124px);
-webkit-transform: rotateY(270deg) translateZ(124px)
}
.strip .t {
background-position: 165px 0;
-moz-transform: rotateY(285deg) translateZ(124px);
-webkit-transform: rotateY(285deg) translateZ(124px)
}
.strip .u {
background-position: 132px 0;
-moz-transform: rotateY(300deg) translateZ(124px);
-webkit-transform: rotateY(300deg) translateZ(124px)
}
.strip .v {
background-position: 99px 0;
-moz-transform: rotateY(315deg) translateZ(124px);
-webkit-transform: rotateY(315deg) translateZ(124px)
}
.strip .w {
background-position: 66px 0;
-moz-transform: rotateY(330deg) translateZ(124px);
-webkit-transform: rotateY(330deg) translateZ(124px)
}
.strip .x {
background-position: 33px 0;
-moz-transform: rotateY(345deg) translateZ(124px);
-webkit-transform: rotateY(345deg) translateZ(124px)
}
@-moz-keyframes spin {
from {
-moz-transform: rotateY(360deg)
}
to {
-moz-transform: rotateY(230deg)
}
}
@-webkit-keyframes spin {
from {
-webkit-transform: rotateY(360deg)
}
to {
-webkit-transform: rotateY(230deg)
}
}
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<div id="capture" class="mastercontainer">
<div id="container">
<div id="frame">
<div class="strip">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
<div class="d"></div>
<div class="e"></div>
<div class="f"></div>
<div class="g"></div>
<div class="h"></div>
<div class="i"></div>
<div class="j"></div>
<div class="k"></div>
<div class="l"></div>
<div class="m"></div>
<div class="n"></div>
<div class="o"></div>
<div class="p"></div>
<div class="q"></div>
<div class="r"></div>
<div class="s"></div>
<div class="t"></div>
<div class="u"></div>
<div class="v"></div>
<div class="w"></div>
<div class="x"></div>
</div>
</div>
</div>
</div>
我已经把所有东西都放到了这里的 jsfiddle 中.. https://jsfiddle.net/StickerMonkey/tLqrdey5/4/
编辑添加:
我也试过 foreignObjectRendering: true
这给出了正确的形状但是是一个涂黑的图像。
要添加的第二次编辑; 我也乐于接受另一种方法的建议,将矩形图像包裹在杯子周围或另一种截屏方式或以其他方式抓取我已经生成的图像。
这是一个使用 Three.js 的例子。
它创建了一个带有彩绘杯子旋转视图的场景。
它还在新的 canvas 中以 60° 旋转拍摄快照。
它还在白色背景的第三个 canvas 中单独显示油漆。
//Moved to <script type="module">
//import * as THREE from 'https://cdn.skypack.dev/three';
function actualCode(THREE) {
//Variables for rendering
const renderer = new THREE.WebGLRenderer({
antialias: true
});
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(30, 400.0 / 400, 1, 1000);
//Object variables
let texture;
let paintedMug;
//Preload image, then trigger rendering
const loader = new THREE.TextureLoader();
//Real URL triggers cross origin error in tests:
// texture = loader.load("http://automation.stickermonkey.shop/codeplayground/images/djmug2.jpg", function(_tex) {
//Hosting it on local server works:
// texture = loader.load("./djmug2.jpg", function(_tex) {
//Example with image hosted from Imgur:
texture = loader.load("https://i.imgur.com/TQZrUSP.jpeg", function(_tex) {
// /*Debugging:*/ setTimeout(() => document.body.appendChild(texture.image), 100);
init();
snapShot(60);
renderImageSolo(60);
render();
});
function init() {
//Init scene and camera
camera.position.set(0, 1.3, 11);
camera.lookAt(scene.position);
renderer.setSize(400, 400);
addTitle("Animated scene:");
document.body.appendChild(renderer.domElement);
//Set an ambient light
const light = new THREE.AmbientLight(0xffffff); // soft white light
scene.add(light);
//Draw white mug
const muggeom = new THREE.CylinderGeometry(1.5, 1.5, 3.5, 240, 1);
const mugmaterial = new THREE.MeshStandardMaterial({
color: "#fff",
});
const mug = new THREE.Mesh(muggeom, mugmaterial);
//Draw painting on mug with slightly larger radius
const paintgeom = new THREE.CylinderGeometry(1.5001, 1.5001, 3.3, 240, 1, true);
const paintmaterial = new THREE.MeshStandardMaterial({
map: texture,
});
const paint = new THREE.Mesh(paintgeom, paintmaterial);
//Define a group as mug + paint
paintedMug = new THREE.Group();
paintedMug.add(mug);
paintedMug.add(paint);
//Add group to scene
scene.add(paintedMug);
}
function render() {
try {
//Draw
renderer.render(scene, camera);
//Rotate a bit at each frame
paintedMug.rotation.y += -.01
//Trigger next animation frame (default 60fps)
requestAnimationFrame(render);
} catch (err) {
console.log(err, err.message);
}
}
function snapShot(angle) {
const orgAngle = paintedMug.rotation.y;
//Rotate objects by angle
paintedMug.rotation.y = angle;
//render once
renderer.render(scene, camera);
//Take still into new canvas
var canvas = document.createElement("canvas");
canvas.width = renderer.domElement.width;
canvas.height = renderer.domElement.height;
canvas.getContext("2d").drawImage(renderer.domElement, 0, 0);
canvas.style.marginTop = "1em"; //Space out canvas
addTitle(`Snapshot at ${angle}°:`);
document.body.append(canvas);
//Restore rotation
paintedMug.rotation.y = orgAngle;
}
function renderImageSolo(angle) {
//Init just like main renderer / scene, will use same camera
const solo_renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true });
solo_renderer.setSize(renderer.domElement.width, renderer.domElement.height);
solo_renderer.domElement.style.marginTop = "1em"; //Space out canvas
addTitle(`Paint alone at ${angle}°:`);
document.body.appendChild(solo_renderer.domElement);
const solo_scene = new THREE.Scene();
//Set an ambient light
const light = new THREE.AmbientLight(0xffffff); // soft white light
solo_scene.add(light);
//Draw painting alone
const paintgeom = new THREE.CylinderGeometry(1.5, 1.5, 3.3, 240, 1, true);
const paintmaterial = new THREE.MeshStandardMaterial({
map: texture,
});
const paint = new THREE.Mesh(paintgeom, paintmaterial);
//Add paint to scene
solo_scene.add(paint);
//Rotate paint by angle
paint.rotation.y = angle
//Draw result
solo_scene.background = new THREE.Color(0xffffff);
solo_renderer.render(solo_scene, camera);
}
function addTitle(title) {
const h2 = document.createElement('h2');
h2.innerText = title;
document.body.appendChild(h2);
}
}
<!-- Below code is just a workaround for ES6 imports in SO snippet -->
<script type="module"> //Forced to put import in HTML section, as SO snippet does not support ES6 module loading
import * as THREE from 'https://cdn.skypack.dev/three';
document.addEventListener("DOMContentLoaded", _e => actualCode(THREE));
</script>
由于 CORS 策略,使用来自另一台服务器的原始图像时出现问题。我已经使用托管在 Imgur 上的副本设置示例,但还包括原始位置的代码(请参阅评论)。