I am trying to create a custom post header background for a forum website. But because I always want to make my life more difficult I tried to make it fancy. I also need to link to that script in every post.
When I duplicate the post (or simulate it by just ctrl+a ctrl+c ctrl+v ctrl+v the HTMP code) only the last post gets any smoke effect background. I tried to add the function to the window on init and loop it for every element with the SiffrinSmoke class but still only one smoke is displayed - at the bottom.
HTML:
<div class="SiffrinBody">
<div class="SiffrinHeader">
<div class="SiffrinSmoke">
<!--h1>Siffrin<br>Drauglir</h1-->
<h1 data-heading="Siffrin
Drauglir"></h1>
</div>
<div class="SiffrinCanvasBackground" id="SiffrinCanvasBackground"></div>
<div class="SiffrinCanvasForeground" id="SiffrinCanvasForeground"></div>
<img id="SiffrinHeaderBackground" src="https://i.imgur.com/iYnkBdZ.jpg">
<img id="SiffrinWolf" src="https://i.imgur.com/MBLqG00.png">
</div>
</div>
CSS:
@import url('https://fonts.googleapis.com/css2?family=Arvo:ital@0;1&family=Carter+One&family=Dosis:wght@400;500;600&display=swap');
.SiffrinBody .SiffrinHeader .SiffrinCanvasBackground{
height: 330px;
width: 656px;
position: absolute;
left: inherit;
top: inherit;
z-index: 5;
}
.SiffrinBody .SiffrinHeader .SiffrinCanvasForeground{
height: 330px;
width: 656px;
position: absolute;
left: inherit;
top: inherit;
z-index: 7;
}
.SiffrinBody .SiffrinHeader img{
position: absolute;
height: 330px;
width: 656px;
grid-row: 1;
}
.SiffrinBody .SiffrinHeader .SiffrinSmoke{
width: 328px;
height: 330px;
position: relative;
z-index: 6;
float: right;
display: block;
}
.SiffrinBody .SiffrinHeader .SiffrinSmoke canvas{
position: absolute;
top: 0;
left: 0;
z-index: -4;
}
.SiffrinBody .SiffrinHeader #SiffrinHeaderBackground{
z-index: 4;
}
.SiffrinBody .SiffrinHeader #SiffrinWolf{
z-index: 6;
}
.SiffrinBody .SiffrinHeader h1{
font-family: Carter One;
z-index: 1000;
color: white;
grid-column: 2;
font-size: 50;
margin-top: 32%;
text-align: center;
background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/209981/6963bbf342d87b3a2150bd8f59682b89.jpg);
-webkit-background-clip: text;
background-size: cover;
width: 100%;
color: transparent;
font-weight: 900;
display: block;
white-space: pre-wrap !important;
line-height: 1.1em;
text-shadow: 2px 2px 6px rgba(46,146,211,0.8);
}
.SiffrinBody .SiffrinHeader h1::before{
content: attr(data-heading);
position: relative;
left: 0;
top: 0;
width: 100%;
background: linear-gradient(45deg, rgba(255,255,255,0) 45%,rgba(255,255,255,0.8) 50%,rgba(255,255,255,0) 55%,rgba(255,255,255,0) 100%);
-webkit-background-clip: text;
color: transparent;
mix-blend-mode: screen;
animation: SiffrinShine 15s infinite linear;
background-size: 200%;
}
.SiffrinBody .SiffrinHeader #SiffrinName{
z-index: 22;
transform: scale(0.8);
left: 150px;
}
.SiffrinBody .SiffrinHeader{
grid-row: 1;
mask-image: linear-gradient(
to top,
rgba(255, 255, 255, 0) 0,
rgba(255, 255, 255, 1) 15px
);
}
.SiffrinBody .SiffrinHeader > *{
user-select: none;
}
.SiffrinBody{
color: white;
display: grid;
grid-template-rows: 330px auto auto;
grid-template-columns: 1fr;
margin: 0;
padding: 0;
width: 656px;
/*background-image: linear-gradient(#bad4eb, #bad4eb, #a7c8e7, #4789c6, #037ccf);*/
background-image: url("https://i.imgur.com/UqFcRzS.jpg");
background-repeat: repeat;
}
.SiffrinBody *::selection{
background: rgba(225, 0, 255, 0.3);
color: inherit;
}
.SiffrinBody .SiffrinHeader{
/*
z-index: 7;
text-align: center;
font-family: Oleo Script;
margin: auto;
font-size: 30px;
transition-duration: 2s;
transition-timing-function: ease-in-out;
background-image: radial-gradient(#0e111800, #232b3e00, #24212a00, #403b6600);
user-select: none;
*/
}
.SiffrinBody .SiffrinBody:hover .SiffrinHeader{
/*
letter-spacing: 0.35em;
transition-duration: 3s;
transition-timing-function: ease-in-out;
transform: translate(0px, 40px);
*/
}
.SiffrinBody .SiffrinText{
z-index: 7;
margin: 10px 50px;
padding: 20px;
background-color: rgba(0, 0, 0, 0.5);
font-family: Dosis;
font-size: 17px;
margin-bottom: 0;
line-height: 1.235em;
font-weight: 500;
}
.SiffrinBody .SiffrinText::before{
border-top: 3px solid blue;
border-right: 3px solid blue;
}
.SiffrinBody .SiffrinText::after{
border-bottom: 3px solid orange;
border-left: 3px solid orange;
}
.SiffrinBody .SiffrinText p{
padding: 0;
margin-bottom: 1em;
}
.SiffrinBody .SiffrinText p u,
.SiffrinBody .SiffrinText p i,
.SiffrinBody .SiffrinText p q{
font-family: Arvo;
font-size: 16px;
}
.SiffrinBody .SiffrinText p u{
text-decoration: none;
color:rgb(250, 210, 255);
}
.SiffrinBody .SiffrinText p u::before {
content: "“"
}
.SiffrinBody.SiffrinText p u::after {
content: "”"
}
.SiffrinBody .SiffrinText p i{
font-family: Arvo;
color:rgb(250, 210, 255);
font-style: italic;
}
.SiffrinBody .SiffrinText p q{
text-decoration: none;
color:rgb(219, 223, 255);
}
.SiffrinBody .SiffrinText p:last-child{
margin: 0;
}
.SiffrinBody .SiffrinText p:first-child{
margin-top: 0;
}
.SiffrinBody .SiffrinFooter{
display: flex;
align-items: center;
justify-content: center;
padding: 10px;
margin: 0;
}
.SiffrinBody .SiffrinFooter p{
text-align: center;
font-size: 20px;
color: #f8f7fd;
text-align: center;
}
@keyframes SiffrinShine {
0% {background-position: 110%;}
60% {background-position: -90%;}
100% {background-position: -90%;}
}
Import THREE:
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>
JS:
function initiateSmoke() {
smokeBackgrounds = document.getElementsByClassName('SiffrinSmoke');
clock = new THREE.Clock();
renderW = smokeBackgrounds[0].offsetWidth;
renderH = smokeBackgrounds[0].offsetHeight;
renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize( renderW, renderH );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, renderW / renderH , 1, 10000 );
camera.position.z = 1300;
scene.add( camera );
geometry = new THREE.CubeGeometry( 200, 200, 200 );
material = new THREE.MeshLambertMaterial( { color: 0xaa6666, wireframe: false } );
mesh = new THREE.Mesh( geometry, material );
cubeSineDriver = 0;
textGeo = new THREE.PlaneGeometry(300,300);
THREE.ImageUtils.crossOrigin = ''; //Need this to pull in crossdomain images from AWS
light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(-1,0,1);
scene.add(light);
smokeTexture = THREE.ImageUtils.loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/95637/Smoke-Element.png');
smokeMaterial = new THREE.MeshLambertMaterial({color: 0x333333, opacity: 1, map: smokeTexture, transparent: true});
smokeGeo = new THREE.PlaneGeometry(650,650);
smokeParticles = [];
for (p = 0; p < 36; p++) {
particle = new THREE.Mesh(smokeGeo,smokeMaterial);
particle.position.set(Math.random() * 950 - 500, Math.random() * 620 - 300, Math.random() * 200 - 100);
particle.rotation.z = Math.random() * 360;
particle.scale.set(2,2,2);
scene.add(particle);
smokeParticles.push(particle);
}
for(i = 0; i < smokeBackgrounds.length; i++) {
smokeBackgrounds[i].appendChild( renderer.domElement );
}
}
function animateSmoke() {
// note: three.js includes requestAnimationFrame shim
delta = clock.getDelta();
requestAnimationFrame( animateSmoke );
evolveSmoke();
render();
}
function evolveSmoke() {
var sp = smokeParticles.length;
while(sp--) {
smokeParticles[sp].rotation.z += (delta * 0.2);
}
}
function render() {
mesh.rotation.x += 0.005;
mesh.rotation.y += 0.01;
cubeSineDriver += .01;
mesh.position.z = 100 + (Math.sin(cubeSineDriver) * 500);
renderer.render( scene, camera );
}
window.onload = function Snowfall(){
initiateSmoke();
animateSmoke();
}
Do you know how to apply that same effect as background for every element with that class? Maybe another tool would be better for the job?
EDIT: Solution The Smoke init function accepts the background elements from before and returns relevant objects
function initiateSmoke(smokeBackground) {
[...]
return({
"renderer": renderer,
"scene": scene,
"camera": camera,
"mesh": mesh,
"cubeSineDriver": cubeSineDriver,
"smokeParticles": smokeParticles
})
}
Then in window.onloadI have this loop
smokeBackgrounds = document.getElementsByClassName('SiffrinSmoke');
for(i = 0; i < smokeBackgrounds.length; i++) {
smokeScenes[i] = initiateSmoke(smokeBackgrounds[i]);
smokeBackgrounds[i].appendChild(smokeScenes[i]['renderer'].domElement);
}
animateSmoke();
I also edited the animate functions
function animateSmoke() {
delta = clock.getDelta();
requestAnimationFrame(animateSmoke);
evolveSmoke();
render();
}
function evolveSmoke() {
for(i = 0; i < smokeScenes.length; i++) {
smokeScene = smokeScenes[i];
var sp = smokeScene['smokeParticles'].length;
while(sp--) {
smokeScene['smokeParticles'][sp].rotation.z += (delta * 0.2);
}
}
}
function render() {
for(i = 0; i < smokeScenes.length; i++) {
smokeScene = smokeScenes[i];
smokeScene['mesh'].rotation.x += 0.005;
smokeScene['mesh'].rotation.y += 0.01;
smokeScene['cubeSineDriver'] += .01;
smokeScene['mesh'].position.z = 100 + (Math.sin(smokeScene['cubeSineDriver']) * 500);
smokeScene['renderer'].render( smokeScene['scene'], smokeScene['camera']);
}
}
let smokeScenes = []
let clock = new THREE.Clock();
and that works!
It's because you're only creating one canvas, and just appending that to each "smokeBackgrounds" in the loop. But each one overwrites the last one, because there's only one canvas (renderer.domElement).
There's a few ways you could solve it:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.