前端电商网站开发周期|网站前端程序制作开发|web前端是网站开发么
前两天看到了一个动画,就琢磨着怎么简单实现一下。
我们要做的,就是将DOM的内容原原本本复制,并绘制成图片。svg的foreignObject元素可以包含html片段,这样就可以将整个DOM片段转换成svg。
然后我们可以有两个选择,第一是将svg插入到一个div中,或者将svg绘制到canvas。svg相对于canvas来说,更清晰。
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<meta http-equiv=”X-UA-Compatible” content=”ie=edge”>
<title>前端快速开发网站:js Dom</title>
</head>
<body>
<script>
// dom
const div = document.createElement(‘div’);
div.innerHTML = `<div>
<h4>svg:</h4>
<div id=”svg”></div>
</div>
<div>
<h4>canvas:</h4>
<canvas id=”canvas” style=”width: 200px; height: 200px; zoom: .5;” width=”100″ height=”100″></canvas>
</div>`;
document.body.appendChild(div);
// 图片
const html = `<svg width=”100″ height=”100″ xmlns=”http://www.w3.org/2000/svg”>
<foreignObject width=”100%” height=”100%”>
<div xmlns=”http://www.w3.org/1999/xhtml”>Hello, world!</div>
</foreignObject>
</svg>`;
document.getElementById(‘svg’).innerHTML = html;
const img = new Image();
const svg = new Blob(html.split(”), {
type: ‘image/svg+xml;charset=utf-8’
});
const url = window.URL.createObjectURL(svg);
function imgLoad(event) {
let canvas = document.getElementById(‘canvas’);
let ctx = canvas.getContext(‘2d’);
ctx.drawImage(img, 0, 0);
ctx.scale(2, 2);
window.URL.revokeObjectURL(url);
}
img.src = url;
img.addEventListener(‘load’, imgLoad, false);
</script>
</body>
</html>
不过要注意的是,在svg里面的class
是无效的,样式只有style=“key: value;”
才能生效。可以使用window.getComputedStyle
来获取DOM的样式。如果嫌麻烦,还可以使用html2canvas库。
svg内dom节点的xmlns
属性不能省略。
最后来个简单的Demo:
canvas:
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>前端网站开发教程:js</title>
<style>
body {
margin: 0;
}
.article {
box-sizing: border-box;
margin: 0 auto;
padding: 10px;
width: 300px;
height: 560px;
border: 1px solid #ddd;
border-radius: 5px;
background-color: #fff;
}
.article-title {
font-size: 16px;
}
.article-secondtitle {
font-size: 12px;
color: #7e7e7e;
}
.article-title,
.article-secondtitle {
text-align: center;
}
.article p {
font-size: 14px;
}
.canvas {
position: fixed;
top: 0;
left: 50%;
display: block;
width: 300px;
height: 560px;
margin: 0 0 0 -152px;
border: 1px solid #ddd;
border-radius: 5px;
}
@keyframes body1 {
0% {
transform: rotateZ(0) rotateY(0) scale(1);
}
50% {
transform: rotateZ(180deg) rotateY(0) scale(.9);
}
100% {
transform: rotateZ(360deg) rotateY(180deg) scale(0);
}
}
.animate {
animation-name: body1;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
.ani0 {
animation-delay: 1s;
animation-duration: 2s;
z-index: 4;
}
.ani1 {
animation-delay: 1.4s;
animation-duration: 1.7s;
z-index: 3;
}
.ani2 {
animation-delay: 1.8s;
animation-duration: 1.4s;
z-index: 2;
}
.ani3 {
animation-delay: 2.2s;
animation-duration: 1.1s;
z-index: 1;
}
</style>
</head>
<body>
<article class=”article” id=”article”>
<h1 class=”article-title”>将进酒·君不见黄河之水天上来</h1>
<h6 class=”article-secondtitle”>[唐] 李白</h6>
<p>君不见黄河之水天上来,奔流到海不复回。</p>
<p>君不见高堂明镜悲白发,朝如青丝暮成雪。</p>
<p>人生得意须尽欢,莫使金樽空对月。</p>
<p>天生我材必有用,千金散尽还复来。</p>
<p>烹羊宰牛且为乐,会须一饮三百杯。</p>
<p>岑夫子,丹丘生,将进酒,杯莫停。</p>
<p>与君歌一曲,请君为我侧耳听。</p>
<p>钟鼓馔玉不足贵,但愿长醉不复醒。</p>
<p>古来圣贤皆寂寞,惟有饮者留其名。</p>
<p>陈王昔时宴平乐,斗酒十千恣欢谑。</p>
<p>主人何为言少钱,径须沽取对君酌。</p>
<p>五花马,千金裘,</p>
<p>呼儿将出换美酒,与尔同销万古愁。</p>
</article>
<canvas class=”canvas animate ani0″ id=”canvas_0″ width=”300″ height=”560″></canvas>
<canvas class=”canvas animate ani1″ id=”canvas_1″ width=”300″ height=”560″></canvas>
<canvas class=”canvas animate ani2″ id=”canvas_2″ width=”300″ height=”560″></canvas>
<canvas class=”canvas animate ani3″ id=”canvas_3″ width=”300″ height=”560″></canvas>
<!– 特效代码 –>
<script>
function style2String(node) {
let style = ”;
style += `padding: ${css.padding}; `;
style += `width: ${css.width}; `;
style += `font-size: ${css.fontSize}; `;
style += `font-family: ${css.fontFamily.replace(/”/g, ”)}; `;
style += `border-radius: ${css.borderRadius}; `;
style += `color: ${css.color}; `;
style += `text-align: ${css.textAlign}; `;
style += `background-color: ${css.backgroundColor}; `;
return style;
}
function html2Text(node) {
// 节点
let txt = ”;
if (node.nodeName !== ‘#text’) {
const nodeName = node.nodeName.toLowerCase();
const style = style2String(node);
txt += `<${nodeName} style=”${style}”>`;
// 子节点
const childNodes = node.childNodes;
for (let i = 0, j = childNodes.length; i < j; i++) {
txt += html2Text(childNodes[i]);
}
txt += `</${nodeName}>`;
} else {
txt += node.data;
}
return txt;
}
</script>
<script>
const article = document.getElementById(‘article’);
const html = `<svg width=”300″ height=”560px” xmlns=”http://www.w3.org/2000/svg”>
<foreignObject width=”100%” height=”100%”>
<div xmlns=”http://www.w3.org/1999/xhtml”>${ html2Text(article)}</div>
</foreignObject>
</svg>`;
// nodeName
const img = new Image();
const svg = new Blob(html.split(”), {
type: ‘image/svg+xml;charset=utf-8’
});
const url = window.URL.createObjectURL(svg);
function onCanvasAnimationEnd(event) {
this.removeEventListener(‘animationend’, onCanvasAnimationEnd);
const father = this.parentNode;
father.removeChild(this);
}
function imgLoad(event) {
for (let i = 0; i < 4; i++) {
let canvas = document.getElementById(‘canvas_’ + i);
let ctx = canvas.getContext(‘2d’);
ctx.drawImage(img, 0, 0);
canvas.addEventListener(‘animationend’, onCanvasAnimationEnd, false);
canvas = ctx = null;
}
window.URL.revokeObjectURL(url);
}
img.src = url;
img.addEventListener(‘load’, imgLoad, false);
</script>
</body>
</html>
svg:
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<style>
body {
margin: 0;
}
.article {
box-sizing: border-box;
margin: 0 auto;
padding: 10px;
width: 300px;
height: 560px;
border: 1px solid #ddd;
border-radius: 5px;
background-color: #fff;
}
.article-title {
font-size: 16px;
}
.article-secondtitle {
font-size: 12px;
color: #7e7e7e;
}
.article-title,
.article-secondtitle {
text-align: center;
}
.article p {
font-size: 14px;
}
.svg {
position: fixed;
top: 0;
left: 50%;
display: block;
width: 300px;
height: 560px;
margin: 0 0 0 -152px;
border: 1px solid #ddd;
border-radius: 5px;
}
@keyframes body1 {
0% {
transform: rotateZ(0) rotateY(0) scale(1);
}
50% {
transform: rotateZ(180deg) rotateY(0) scale(.9);
}
100% {
transform: rotateZ(360deg) rotateY(180deg) scale(0);
}
}
.animate {
animation-name: body1;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
.ani0 {
animation-delay: 1s;
animation-duration: 2s;
z-index: 4;
}
.ani1 {
animation-delay: 1.4s;
animation-duration: 1.7s;
z-index: 3;
}
.ani2 {
animation-delay: 1.8s;
animation-duration: 1.4s;
z-index: 2;
}
.ani3 {
animation-delay: 2.2s;
animation-duration: 1.1s;
z-index: 1;
}
</style>
</head>
<body>
<article class=”article” id=”article”>
<h1 class=”article-title”>将进酒·君不见黄河之水天上来</h1>
<h6 class=”article-secondtitle”>[唐] 李白</h6>
<p>君不见黄河之水天上来,奔流到海不复回。</p>
<p>君不见高堂明镜悲白发,朝如青丝暮成雪。</p>
<p>人生得意须尽欢,莫使金樽空对月。</p>
<p>天生我材必有用,千金散尽还复来。</p>
<p>烹羊宰牛且为乐,会须一饮三百杯。</p>
<p>岑夫子,丹丘生,将进酒,杯莫停。</p>
<p>与君歌一曲,请君为我侧耳听。</p>
<p>钟鼓馔玉不足贵,但愿长醉不复醒。</p>
<p>古来圣贤皆寂寞,惟有饮者留其名。</p>
<p>陈王昔时宴平乐,斗酒十千恣欢谑。</p>
<p>主人何为言少钱,径须沽取对君酌。</p>
<p>五花马,千金裘,</p>
<p>呼儿将出换美酒,与尔同销万古愁。</p>
</article>
<!– 特效代码 –>
<script>
function style2String(node) {
const css = window.getComputedStyle(node);
let style = ”;
style += `padding: ${css.padding}; `;
style += `width: ${css.width}; `;
style += `font-size: ${css.fontSize}; `;
style += `font-family: ${css.fontFamily.replace(/”/g, ”)}; `;
style += `border-radius: ${css.borderRadius}; `;
style += `color: ${css.color}; `;
style += `text-align: ${css.textAlign}; `;
style += `background-color: ${css.backgroundColor}; `;
return style;
}
function html2Text(node) {
// 节点
let txt = ”;
if (node.nodeName !== ‘#text’) {
const nodeName = node.nodeName.toLowerCase();
const style = style2String(node);
txt += `<${nodeName} style=”${style}”>`;
// 子节点
const childNodes = node.childNodes;
for (let i = 0, j = childNodes.length; i < j; i++) {
txt += html2Text(childNodes[i]);
}
txt += `</${nodeName}>`;
} else {
txt += node.data;
}
return txt;
}
</script>
<script>
const body = document.body;
const article = document.getElementById(‘article’);
const html = `<svg width=”300″ height=”560px” xmlns=”http://www.w3.org/2000/svg”>
<foreignObject width=”100%” height=”100%”>
<div xmlns=”http://www.w3.org/1999/xhtml”>${ html2Text(article)}</div>
</foreignObject>
</svg>`;
function onCanvasAnimationEnd(event) {
this.removeEventListener(‘animationend’, onCanvasAnimationEnd);
const father = this.parentNode;
father.removeChild(this);
}
for (let i = 0; i < 4; i++) {
let div = document.createElement(‘div’);
div.innerHTML = html;
div.className = `svg animate ani${i}`;
div.addEventListener(‘animationend’, onCanvasAnimationEnd, true);
body.appendChild(div);
div = null;
}
</script>
</body>
</html>
网站前端开发研究内容|适合新手前端开发的网站|需要前端开发的网站
评论前必须登录!
注册