HTML + CANVAS: Constellation background animation - javascript

I've been wanting to implement a moving constellation background for a site of mine.
This is an example of the effect I'd like to achieve:
The image doesn't show, but those constellations are constantly moving. I took that from the: https://www.nuclino.com/ site, which is awesome BTW.
So here my questions:
How could I use a CSS animation/transition to implement this effect? CSS transitions only let me specify positions at every step of the animation.
Is there any JS library for this effect?

Here you go:
http://codepen.io/JulianLaval/pen/KpLXOO/
// particle.min.js hosted on GitHub
// Scroll down for initialisation code
!function(a){var b="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global;"function"==typeof define&&define.amd?define(["exports"],function(c){b.ParticleNetwork=a(b,c)}):"object"==typeof module&&module.exports?module.exports=a(b,{}):b.ParticleNetwork=a(b,{})}(function(a,b){var c=function(a){this.canvas=a.canvas,this.g=a.g,this.particleColor=a.options.particleColor,this.x=Math.random()*this.canvas.width,this.y=Math.random()*this.canvas.height,this.velocity={x:(Math.random()-.5)*a.options.velocity,y:(Math.random()-.5)*a.options.velocity}};return c.prototype.update=function(){(this.x>this.canvas.width+20||this.x<-20)&&(this.velocity.x=-this.velocity.x),(this.y>this.canvas.height+20||this.y<-20)&&(this.velocity.y=-this.velocity.y),this.x+=this.velocity.x,this.y+=this.velocity.y},c.prototype.h=function(){this.g.beginPath(),this.g.fillStyle=this.particleColor,this.g.globalAlpha=.7,this.g.arc(this.x,this.y,1.5,0,2*Math.PI),this.g.fill()},b=function(a,b){this.i=a,this.i.size={width:this.i.offsetWidth,height:this.i.offsetHeight},b=void 0!==b?b:{},this.options={particleColor:void 0!==b.particleColor?b.particleColor:"#fff",background:void 0!==b.background?b.background:"#1a252f",interactive:void 0!==b.interactive?b.interactive:!0,velocity:this.setVelocity(b.speed),density:this.j(b.density)},this.init()},b.prototype.init=function(){if(this.k=document.createElement("div"),this.i.appendChild(this.k),this.l(this.k,{position:"absolute",top:0,left:0,bottom:0,right:0,"z-index":1}),/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(this.options.background))this.l(this.k,{background:this.options.background});else{if(!/\.(gif|jpg|jpeg|tiff|png)$/i.test(this.options.background))return console.error("Please specify a valid background image or hexadecimal color"),!1;this.l(this.k,{background:'url("'+this.options.background+'") no-repeat center',"background-size":"cover"})}if(!/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(this.options.particleColor))return console.error("Please specify a valid particleColor hexadecimal color"),!1;this.canvas=document.createElement("canvas"),this.i.appendChild(this.canvas),this.g=this.canvas.getContext("2d"),this.canvas.width=this.i.size.width,this.canvas.height=this.i.size.height,this.l(this.i,{position:"relative"}),this.l(this.canvas,{"z-index":"20",position:"relative"}),window.addEventListener("resize",function(){return this.i.offsetWidth===this.i.size.width&&this.i.offsetHeight===this.i.size.height?!1:(this.canvas.width=this.i.size.width=this.i.offsetWidth,this.canvas.height=this.i.size.height=this.i.offsetHeight,clearTimeout(this.m),void(this.m=setTimeout(function(){this.o=[];for(var a=0;a<this.canvas.width*this.canvas.height/this.options.density;a++)this.o.push(new c(this));this.options.interactive&&this.o.push(this.p),requestAnimationFrame(this.update.bind(this))}.bind(this),500)))}.bind(this)),this.o=[];for(var a=0;a<this.canvas.width*this.canvas.height/this.options.density;a++)this.o.push(new c(this));this.options.interactive&&(this.p=new c(this),this.p.velocity={x:0,y:0},this.o.push(this.p),this.canvas.addEventListener("mousemove",function(a){this.p.x=a.clientX-this.canvas.offsetLeft,this.p.y=a.clientY-this.canvas.offsetTop}.bind(this)),this.canvas.addEventListener("mouseup",function(a){this.p.velocity={x:(Math.random()-.5)*this.options.velocity,y:(Math.random()-.5)*this.options.velocity},this.p=new c(this),this.p.velocity={x:0,y:0},this.o.push(this.p)}.bind(this))),requestAnimationFrame(this.update.bind(this))},b.prototype.update=function(){this.g.clearRect(0,0,this.canvas.width,this.canvas.height),this.g.globalAlpha=1;for(var a=0;a<this.o.length;a++){this.o[a].update(),this.o[a].h();for(var b=this.o.length-1;b>a;b--){var c=Math.sqrt(Math.pow(this.o[a].x-this.o[b].x,2)+Math.pow(this.o[a].y-this.o[b].y,2));c>120||(this.g.beginPath(),this.g.strokeStyle=this.options.particleColor,this.g.globalAlpha=(120-c)/120,this.g.lineWidth=.7,this.g.moveTo(this.o[a].x,this.o[a].y),this.g.lineTo(this.o[b].x,this.o[b].y),this.g.stroke())}}0!==this.options.velocity&&requestAnimationFrame(this.update.bind(this))},b.prototype.setVelocity=function(a){return"fast"===a?1:"slow"===a?.33:"none"===a?0:.66},b.prototype.j=function(a){return"high"===a?5e3:"low"===a?2e4:isNaN(parseInt(a,10))?1e4:a},b.prototype.l=function(a,b){for(var c in b)a.style[c]=b[c]},b});
// Initialisation
var canvasDiv = document.getElementById('particle-canvas');
var options = {
particleColor: '#888',
background: 'https://raw.githubusercontent.com/JulianLaval/canvas-particle-network/master/img/demo-bg.jpg',
interactive: true,
speed: 'medium',
density: 'high'
};
var particleCanvas = new ParticleNetwork(canvasDiv, options);
html,
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#particle-canvas {
width: 100%;
height: 100%;
}
<div id="particle-canvas"></div>
<script src="https://rawgit.com/JulianLaval/canvas-particle-network/master/particle-network.min.js"></script>
You can download the fully developed package from npm:
https://www.npmjs.com/package/canvas-particle-network

Related

Javascript animate Method Accumulation Problem

I am trying to do an animation example but there is a problem about accumulation. At first click on the button, the translate animation is done and the position of the element changes permanently. However, on second click it does the translate animation again but this time does not keep the last position. How to overcome this? I went through MDN document and applied the optional section but failed to complete this challenge. Regards,
https://jsfiddle.net/ja218pbr/19/
document.getElementsByTagName("button")[0].addEventListener("click", function() {
document.querySelectorAll("div")[0].animate([
{transform: 'translate(100%, 0)'}
], {
duration: 250,
composite: "accumulate",
iterationComposite: "accumulate",
fill: "forwards"
});
});
If I'm understanding this correctly, you want to be able to let the object slide again from the position it ended in earlier. To do this we can get the boundingClientRect each time the button is clicked and calculate the new translation distance by basically taking the width of the object and adding the left distance of the client rect, this will effectively allow the rectangle to keep moving from the distance it ended in before. Also I removed the composite property because it caused the rectangle to jump over the correct position.
document.getElementsByTagName("button")[0].addEventListener("click", function() {
const clientRect = document.querySelectorAll("div")[0].getBoundingClientRect();
const translationX = clientRect.width + clientRect.left;
document.querySelectorAll("div")[0].animate([{
transform: `translate(${translationX}px, 0)`
}], {
duration: 250,
iterationComposite: "accumulate",
fill: "forwards"
});
});
body {
margin: 0;
}
div {
position: relative;
height: 150px;
width: 150px;
background-color: yellow;
text-align: center;
line-height: 150px;
}
<div>Moving Object</div>
<button>Press</button>

Full screen background image minus flexible top-nav bar

This is my first post here and I haven't been able to find the answer to my question.
I am building a page and I want a picture to fill the entire screen, from the bottom of the top-nav bar (menu etc..) to the bottom of the screen. Only issue I have... the bar is responsive : it's taller on very large screen and much smaller on mobiles, which of course impacts my background image differently on different screens.
Here's my css :
.backgroundimage{
background-image: url(https://file...);
background-repeat: no-repeat;
background-size: cover;
width: 100%;
min-height: 100vh;
background-position: center center;
position: relative;
}
</style>
So I've tried multiples things for hours, playing around with the "vh" property.
For example :
min-height:calc(100vh - 17vh)
That gives decent result on my laptop, but not on a larger screen. So I've been trying to find the fonction or class that represents the navHeight, but I can't find a proper way to do it and nothing is working so far. I've tried stuff like :
min-height:calc(100vh - $headerHeight)
And so on... This is a shopify store and I have no knowledge in js, which may explain why I'm struggling. Here's some js code that revolves around the header, but nowhere can I find a way to remove the height of the header. Any idea or direction to give me ? Thanks.
JS code (not in proper order):
theme.headerNav = (function() {
var selectors = {
siteNav: '#SiteNav',
siteNavCompressed: '#SiteNavCompressed',
siteNavParent: '#SiteNavParent',
siteNavItem: '.site-nav__item',
stickyNavWrapper: '#StickNavWrapper',
stickyNav: '#StickyNav'
};
function init() {
sizeNav();
initMegaNavs();
initHeaderSearch();
$(window).on('resize.headernav', $.debounce(250, sizeNav));
}
window.Meganav = (function() {
var Meganav = function(options) {
this.cache = {
$document: $(document),
$page: $('.page-element')
};
var defaults = {
$meganavs: $('.meganav'),
$megaNav: $('.meganav__nav'),
$meganavToggle: $('.meganav-toggle'),
$meganavDropdownContainers: $('.site-nav__dropdown-container'),
$meganavToggleThirdLevel: $('.meganav__link-toggle'),
$meganavLinkSecondLevel: $('.meganav__link--second-level'),
$meganavLinkThirdLevel: $('.meganav__link--third-level'),
$meganavDropdownThirdLevel: $('.site-nav__dropdown--third-level'),
isOpen: false,
preventDuplicates: false,
closeOnPageClick: false,
closeThirdLevelOnBlur: false,
activeClass: 'meganav--active',
drawerClass: 'meganav--drawer',
meganavDropdown: '.site-nav__dropdown',
meganavLinkClass: 'meganav__link',
drawerToggleClass: 'drawer__nav-toggle-btn',
drawerNavItem: '.drawer__nav-item',
navCollectionClass: 'meganav__nav--collection',
secondLevelClass: 'meganav__link--second-level',
thirdLevelClass: 'meganav__link-toggle',
thirdLevelContainerClass: 'site-nav__dropdown--third-level',
noAnimationClass: 'meganav--no-animation'
};
theme.HeaderSection = (function() {
function Header() {
theme.stickyHeader.init();
theme.headerNav.init();
theme.Notify = new window.Notify();
theme.NavDrawer = new window.Drawers('NavDrawer', 'left');
drawerSearch();
}

Ion.RangeSlider 2.0.3

I’m trying to using Ion.RangeSlider 2.0.3
URL : http://ionden.com/a/plugins/ion.rangeSlider/demo_advanced.html
So I want to modify that slider with three colors. Left, Middle, Right likewise. I have attached this image for get idea what I want to need.
So i need your help to customize this slider.
Thanks.
I did the similar thing. Here is the related css and javascript code segments to achieve it.
Let say I want left side green, mid yellow and right side red, then
CSS
.irs-line-left {
background: #66b032;
width: 60%;
}
.irs-line-mid {
background: #FFBF00;
}
.irs-line-mid:before {
content: '';
background-color: #FF0000;
position: absolute;
left: 54%;
top: 0;
right: 0;
bottom: 0;
}
.budget-page .irs-line-right {
background: #FF0000;
width: 40%;
}
.budget-page .irs-line-mid {
width: 0 !important;
}
.irs-bar {
background: #FFBF00;
}
Now here is the trick. When you change the two points we need to change the left and right side width to change the color width dynamically.
Javascript section.
var iri_line_left = $(".irs-line-left");
var iri_line_right = $(".irs-line-right");
$("#color-slider").ionRangeSlider({
type: "double",
min: 0,
max: 100,
from: 60,
to: 80,
grid: true,
onChange: function (data) {
var leftWidth = Math.ceil(data.from_percent);
var rightWidth = 100 - leftWidth;
// set left side width
iri_line_left.css({ 'width': leftWidth + "%" });
// set right side width
iri_line_right.css({ 'width': rightWidth + "%" });
}
});
Hope this will help you.
can be well
.irs-line {
// needs latest Compass, add '#import "compass"' to your scss
#include background-image(linear-gradient(left, #32ff6c 0%,#28ff57 33%,#207cca 33%,#2989d8 66%,#ff3030 66%,#ff0000 100%));
}

Enyo JS Vertical Sliders

I am trying to code a vertical slider in enyo (Like a control on mixing desk). I was trying to avoid starting from scratch so I started tweaking the onyx.Slider class. I changed to styles from left to top and from width to height and with a few other tweaks, it's working. I'm now stuck on getting the slider to fill from bottom to top as at the minute it is vertical but it fills from the top down. Thanks in advance for any help.
Here are the code changes I have done:
in ProgressBar.js:
updateBarPosition: function(inPercent) {
this.$.bar.applyStyle("height", inPercent + "%");
},
in Slider.js (dividing by 64 is a temporary hack):
valueChanged: function() {
this.value = this.clampValue(this.min, this.max, this.value);
var p = this.calcPercent(this.value);
this.updateKnobPosition(p/64);
if (this.lockBar) {
this.setProgress(this.value);
}
},
updateKnobPosition: function(inPercent) {
this.$.knob.applyStyle("top", inPercent + "%");
},
calcKnobPosition: function(inEvent) {
var y = inEvent.clientY - this.hasNode().getBoundingClientRect().top;
return (y / this.getBounds().height) * (this.max - this.min) + this.min;
},
CSS:
/* ProgressBar.css */
.onyx-progress-bar {
margin: 8px;
height: 400px;
width: 8px;
border: 1px solid rgba(15, 15, 15, 0.2);
border-radius: 3px;
background: #b8b8b8 url(./../images/gradient-invert.png) repeat-x;
background-size: auto 100%;
}
.onyx-progress-bar-bar {
height: 100%;
border-radius: 3px;
background: #58abef url(./../images/gradient.png) repeat-x;
background-size: auto 100%;
}
Tom
There are a couple of approaches you could take. The most obvious (except for the fact it didn't occur to me first) is just to swap the background/gradient of the bar and the bar-bar. This will give you the appearance of filling from the bottom. I would recommend this.
The other method is what I did in this jsFiddle here: http://jsfiddle.net/RoySutton/b9PmA/ (Do ignore the doubled updateBarPosition function)
Instead of modifying those files directly, I derived from Slider and overrode the appropriate functions and added a new class for the vertical slider.
I changed the 'fill' to be absolutely positioned within the slider.
Now, your next problem is that value '0' is fully filled and '100' is fully empty. I handled that by modifying your calcKnobPosition to adjust from max and inverting the positioning logic as seen in this fiddle here: http://jsfiddle.net/RoySutton/b9PmA/2/
return this.max - (y / this.getBounds().height) * (this.max - this.min);

Change Height and Width of TextArea in codemirror

I am developing website which having xml, java programs. So i chose CodeMirror for displaying programs in TextArea. I had successfully displayed. It's default height is 300px in codemirror.css. How to change Height and Width of TextArea programmatically in codemirror?
The CodeMirror user manual is your friend.
Example code:
<textarea id="myText" rows="4" cols="10"></textarea>
<script type="text/javascript" language="javascript">
var myTextArea = document.getElementById('myText');
var myCodeMirror = CodeMirror.fromTextArea(myTextArea);
myCodeMirror.setSize(500, 300);
</script>
myCodeMirror.setSize(null, 500);
You can pass null for either of them to indicate that that dimension should not be changed.
Documentation:
cm.setSize(width: number|string, height: number|string)
Programmatically set the size of the editor (overriding the applicable
CSS rules). width and height can be either numbers (interpreted as
pixels) or CSS units ("100%", for example). You can pass null for
either of them to indicate that that dimension should not be changed.
Although the answer from Christian is great, just a heads up:
Autoresize Demo.
.CodeMirror {
border: 1px solid #eee;
height: auto;
}
By setting an editor's height style to auto and giving the viewportMargin a value of Infinity, CodeMirror can be made to automatically resize to fit its content.
Source: https://codemirror.net/demo/resize.html
As an extention to the correct answer:
If you want that it takes the whole size of the Parent element, you can use:
myCodeMirror.setSize("100%", "100%");
if you are doing this in react use ref
const codemirrorRef = React.useRef();
React.useEffect(() => {
const current = codemirrorRef.current.editor.display.wrapper.style.height = "1000px";
});
<CodeMirror
[...]
ref={codemirrorRef}
/>
codemirrorRef.current.editor.display.wrapper contains the div element. From there you can do anything you would do if you did document.getElementById('#id')
$(function () {
// CodeMirror
CodeMirror.fromTextArea(document.getElementById("codeMirrorDemo"), {
lineNumbers: true,
readOnly: true,
//mode: "htmlmixed",
}).setSize("100%", 610);
})
I used the solutions above but always struggled with the option when one line was too long and then it break out of the wrapper and broke the layout. I did not want to use the lineBreak option so I defined following:
<div class="container">
<textarea id="codemirror">
</div>
and the style was following:
.container {
position: relative;
height: {as you want}
width: 100%;
}
#codemirror {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
If you use ngx-codemirror package in your angular application the below blog will be very much useful for you
https://devsuhas.com/2021/04/06/change-height-and-width-of-textarea-in-codemirror/

Categories