Интерактивное звездное небо

Модификатор создает эффект звездного неба на фоне, с эффектом движения по направлению курсора

Код скопирован!
Скопировать код
Код скопирован!
Скопировать код
Шаг 2
Копируем код
jQuery
Для корректной работы блоков подключите библиотеку jQuery:
Инструкция с подключением кода
Настройки сайта -> Еще -> Подключить jQuery на страницах сайта
  1. Добавляем html-элемент
  2. Задаем ему позиционирование CONTAINER: WINDOW (X: LEFT, Y: TOP)
  3. Размеры высоты и ширины по 100%
Шаг 1
Создаем Zero Block и открываем редактор
<script src="https://rawgit.com/mrdoob/stats.js/master/build/stats.min.js"></script>
<div class="tistols-stars"></div>
<style>
.tistols-stars { height:100%; left:0; position:absolute; top:0; width:100%; z-index:0;}
</style>
<script>
// Konstantin Endreev from tilda//

;(function ( $, window, document, undefined ) {
// Plugin constructor
var Starfield = function(el, options) {
this.el = el;
this.$el = $(el);
this.options = options;

that = this;
};

var isPlaying;
var isInited = false;
var canCanvas = false;
var animId;

// MIT license

(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
|| window[vendors[x]+'CancelRequestAnimationFrame'];
}

if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};

if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());

// Plugin prototype
Starfield.prototype = {
// Default settings
defaults: {
starColor: "rgba(255,255,255,1)",
bgColor: "rgba(0,0,0,8)",
mouseMove: true,
mouseColor: "rgba(0,0,0,0.2)",
mouseSpeed: .09,
fps: 15,
speed: 1,
quantity: 512,
ratio: 256,
divclass: "tistols-stars"
},

// Resize the canvas
resizer: function() {
var oldStar = this.star;
var initW = this.context.canvas.width;
var initH = this.context.canvas.height;

this.w = this.$el.width();
this.h = this.$el.height();
this.x = Math.round(this.w /150);
this.y = Math.round(this.h / 200);

// Check if the device is in portrait orientation
this.portrait = this.w < this.h;

// Get the ratio of the old height to the new height
var ratX = this.w / initW;
var ratY = this.h / initH;

this.context.canvas.width = this.w;
this.context.canvas.height = this.h;

// Recalculate the position of each star proportionally to new w and h
for(var i = 0; i < this.n; i++) {
this.star[i][0] = oldStar[i][0] * ratX;
this.star[i][1] = oldStar[i][1] * ratY;

this.star[i][3] = this.x + (this.star[i][0] / this.star[i][2]) * this.star_ratio;
this.star[i][4] = this.y + (this.star[i][1] / this.star[i][2]) * this.star_ratio;
}

that.context.fillStyle = that.settings.bgColor;
this.context.strokeStyle = this.settings.starColor;
},

init: function() {
// Get default settings
this.settings = $.extend({}, this.defaults, this.options);

// Query variables
var url = document.location.href;
this.n = parseInt(
(url.indexOf('n=') != -1) ? url.substring(url.indexOf('n=') + 2, (
(url.substring(
url.indexOf('n=') + 2,
url.length)
).indexOf('&') != -1) ? url.indexOf('n=') + 2 + (url.substring(
url.indexOf('n=') + 2,
url.length)
).indexOf('&') :
url.length) :
this.settings.quantity
);

this.flag = true;
this.test = true;
this.w = 0;
this.h = 0;
this.x = 0;
this.y = 0;
this.z = 0;
this.star_color_ratio = 0;
this.star_x_save = 0;
this.star_y_save = 0;
this.star_ratio = this.settings.ratio;
this.star_speed = this.settings.speed;
this.star_speed_save = 0;
this.star = new Array(this.n);
this.color = this.settings.starColor;
this.opacity = 0.1;

this.cursor_x = 0;
this.cursor_y = 0;
this.mouse_x = 0;
this.mouse_y = 0;

this.canvas_x = 0;
this.canvas_y = 0;
this.canvas_w = 0;
this.canvas_h = 0;

this.fps = this.settings.fps;

// Check for device orientation support
this.desktop = !navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|BB10|IEMobile)/);
this.orientationSupport = window.DeviceOrientationEvent !== undefined;
this.portrait = null;

// Inject the canvas element
var canvasInit = function(){
that.w = that.$el.width();
that.h = that.$el.height();

that.initW = that.w;
that.initH = that.h;

that.portrait = that.w < that.h;

that.wrapper = $('<canvas />')
.addClass(that.settings.divclass);

that.wrapper.appendTo(that.el);

that.starz = $('canvas', that.el);

if (that.starz[0].getContext) { // Can canvas?
that.context = that.starz[0].getContext('2d');
canCanvas = true;
}

that.context.canvas.width = that.w;
that.context.canvas.height = that.h;
}
canvasInit();

// Create initial star array and canvas context
var starInit = function(){
// Get context for the canvas element
if(canCanvas){ // Check for canvas drawering abilities.
that.x = Math.round(that.w / 2);
that.y = Math.round(that.h / 2);
that.z = (that.w + that.h) / 2;
that.star_color_ratio = 1 / that.z;
that.cursor_x = that.x;
that.cursor_y = that.y;

// Big bang
for(var i = 0; i < that.n; i++) {
that.star[i] = new Array(5);

that.star[i][0] = Math.random() * that.w * 2 - that.x * 2;
that.star[i][1] = Math.random() * that.h * 2 - that.y * 2;
that.star[i][2] = Math.round(Math.random() * that.z);
that.star[i][3] = 0;
that.star[i][4] = 0;
}

// Set the colors
that.context.fillStyle = that.settings.bgColor;
that.context.strokeStyle = that.settings.starColor;
} else {
return;
}
}
starInit();

isInited = true;
},

// Iterate over every star on the field and move it slightly
anim: function(){
this.mouse_x = this.cursor_x - this.x;
this.mouse_y = this.cursor_y - this.y;
this.context.fillRect(0, 0, this.w, this.h);

for(var i = 0; i < this.n; i++) {
this.test = true;
this.star_x_save = this.star[i][3];
this.star_y_save = this.star[i][4];
this.star[i][0] += this.mouse_x >> 7;

// X coords
if(this.star[i][0] > this.x << 1) {
this.star[i][0] -= this.w << 1;
this.test = false;
}
if(this.star[i][0] <- this.x << 1) {
this.star[i][0] += this.w << 1;
this.test = false;
}

// Y coords
this.star[i][1] += this.mouse_y >> 7;
if(this.star[i][1] > this.y << 1) {
this.star[i][1] -= this.h << 1;
this.test = false;
}
if(this.star[i][1] <- this.y << 1) {
this.star[i][1] += this.h << 1;
this.test = false;
}

// Z coords
this.star[i][2] -= this.star_speed;
if(this.star[i][2] > this.z) {
this.star[i][2] -= this.z;
this.test = false;
}
if(this.star[i][2] < 0) {
this.star[i][2] += this.z;
this.test = false;
}

this.star[i][3] = this.x + (this.star[i][0] / this.star[i][2]) * this.star_ratio;
this.star[i][4] = this.y + (this.star[i][1] / this.star[i][2]) * this.star_ratio;

if(this.star_x_save > 0
&& this.star_x_save < this.w
&& this.star_y_save > 0
&& this.star_y_save < this.h
&& this.test) {
this.context.lineWidth = (1 - this.star_color_ratio * this.star[i][2]) * 2;
this.context.beginPath();
this.context.moveTo(this.star_x_save,this.star_y_save);
this.context.lineTo(this.star[i][3], this.star[i][4]);
this.context.stroke();
this.context.closePath();
}
}
},

loop: function(){
this.anim();

animId = window.requestAnimationFrame(function(){that.loop()});
},

move: function(){
var doc = document.documentElement;

if (this.orientationSupport && !this.desktop) {
//$('<p class="output"></p>').prependTo('.content');
//var output = document.querySelector('.output');
window.addEventListener('deviceorientation', handleOrientation, false);
} else {
window.addEventListener('mousemove', handleMousemove, false);
}

function handleOrientation(event) {
if( event.beta !== null && event.gamma !== null) {
var x = event.gamma, y = event.beta;

if (!that.portrait) {
x = event.beta * -1;
y = event.gamma;
}

that.cursor_x = (that.w / 2) + (x * 5);
that.cursor_y = (that.h / 2) + (y * 5);

/*var output = document.querySelector('.output');
output.innerHTML = "rotZ : " + Math.round(event.alpha) + "<br />\n";
output.innerHTML += "rotX: " + Math.round(event.beta) + "<br />\n";
output.innerHTML += "rotY: " + Math.round(event.gamma) + "<br />\n";*/
}
}

function handleMousemove(event) {
that.cursor_x = event.pageX || event.clientX + doc.scrollLeft - doc.clientLeft;
that.cursor_y = event.pageY || event.clientY + doc.scrollTop - doc.clientTop;
}
},

stop: function(){
window.cancelAnimationFrame(animId);

isPlaying = false;
},

// this.start this whole thing
start: function() {
// Initialize
if (!isInited) {
isInited = true;
this.init();
}

// Start the animation loop
if (!isPlaying) {
isPlaying = true;
this.loop();
}

window.addEventListener('resize', function(){that.resizer()}, false);

window.addEventListener('orientationchange', function(){that.resizer()}, false);

// Move stars on mouse move
if (this.settings.mouseMove) {
this.move();
}

return this;
}
}

Starfield.defaults = Starfield.prototype.defaults;

// Finally, the actual plugin code
$.fn.starfield = function(options){
return this.each(function() {
new Starfield(this, options).start();
});
}

window.Starfield = Starfield;
})( jQuery, window, document );

$('.tistols-stars').starfield();

// заменить $('поставить айди блока').starfield(); //
</script>
<script>
const LiquidButton = class LiquidButton {
constructor(svg) {
const options = svg.dataset;
this.id = this.constructor.id || (this.constructor.id = 1);
this.constructor.id++;
this.xmlns = 'http://www.w3.org/2000/svg';
this.tension = options.tension * 1 || 0.4;
this.width = options.width * 1 || 218;
this.height = options.height * 1 || 56;
this.margin = options.margin || 40;
this.hoverFactor = options.hoverFactor || -0.1;
this.gap = options.gap || 5;
this.debug = options.debug || false;
this.forceFactor = options.forceFactor || 0.2;
this.color1 = options.color1 || '#151617';
this.color2 = options.color2 || '#151617';
this.color3 = options.color3 || '#151617';
this.textColor = options.textColor || '#fff';
this.text = options.text || 'Button';
this.svg = svg;
this.layers = [{
points: [],
viscosity: 0.5,
mouseForce: 100,
forceLimit: 2,
},{
points: [],
viscosity: 0.8,
mouseForce: 150,
forceLimit: 3,
}];
for (let layerIndex = 0; layerIndex < this.layers.length; layerIndex++) {
const layer = this.layers[layerIndex];
layer.viscosity = options['layer-' + (layerIndex + 1) + 'Viscosity'] * 1 || layer.viscosity;
layer.mouseForce = options['layer-' + (layerIndex + 1) + 'MouseForce'] * 1 || layer.mouseForce;
layer.forceLimit = options['layer-' + (layerIndex + 1) + 'ForceLimit'] * 1 || layer.forceLimit;
layer.path = document.createElementNS(this.xmlns, 'path');
this.svg.appendChild(layer.path);
}
this.wrapperElement = options.wrapperElement || document.body;
if (!this.svg.parentElement) {
this.wrapperElement.append(this.svg);
}

this.svgText = document.createElementNS(this.xmlns, 'text');
this.svgText.setAttribute('x', '50%');
this.svgText.setAttribute('y', '50%');
this.svgText.setAttribute('dy', ~~(this.height / 8) + 'px');
this.svgText.setAttribute('font-size', ~~(this.height / 3));
this.svgText.style.fontFamily = 'sans-serif';
this.svgText.setAttribute('text-anchor', 'middle');
this.svgText.setAttribute('pointer-events', 'none');
this.svg.appendChild(this.svgText);

this.svgDefs = document.createElementNS(this.xmlns, 'defs')
this.svg.appendChild(this.svgDefs);

this.touches = [];
this.noise = options.noise || 0;
document.body.addEventListener('touchstart', this.touchHandler);
document.body.addEventListener('touchmove', this.touchHandler);
document.body.addEventListener('touchend', this.clearHandler);
document.body.addEventListener('touchcancel', this.clearHandler);
this.svg.addEventListener('mousemove', this.mouseHandler);
this.svg.addEventListener('mouseout', this.clearHandler);
this.initOrigins();
this.animate();
}

get mouseHandler() {
return (e) => {
this.touches = [{
x: e.offsetX,
y: e.offsetY,
force: 1,
}];
};
}

get touchHandler() {
return (e) => {
this.touches = [];
const rect = this.svg.getBoundingClientRect();
for (let touchIndex = 0; touchIndex < e.changedTouches.length; touchIndex++) {
const touch = e.changedTouches[touchIndex];
const x = touch.pageX - rect.left;
const y = touch.pageY - rect.top;
if (x > 0 && y > 0 && x < this.svgWidth && y < this.svgHeight) {
this.touches.push({x, y, force: touch.force || 1});
}
}
e.preventDefault();
};
}

get clearHandler() {
return (e) => {
this.touches = [];
};
}

get raf() {
return this.__raf || (this.__raf = (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(callback){ setTimeout(callback, 10)}
).bind(window));
}

distance(p1, p2) {
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
}

update() {
for (let layerIndex = 0; layerIndex < this.layers.length; layerIndex++) {
const layer = this.layers[layerIndex];
const points = layer.points;
for (let pointIndex = 0; pointIndex < points.length; pointIndex++) {
const point = points[pointIndex];
const dx = point.ox - point.x + (Math.random() - 0.5) * this.noise;
const dy = point.oy - point.y + (Math.random() - 0.5) * this.noise;
const d = Math.sqrt(dx * dx + dy * dy);
const f = d * this.forceFactor;
point.vx += f * ((dx / d) || 0);
point.vy += f * ((dy / d) || 0);
for (let touchIndex = 0; touchIndex < this.touches.length; touchIndex++) {
const touch = this.touches[touchIndex];
let mouseForce = layer.mouseForce;
if (
touch.x > this.margin &&
touch.x < this.margin + this.width &&
touch.y > this.margin &&
touch.y < this.margin + this.height
) {
mouseForce *= -this.hoverFactor;
}
const mx = point.x - touch.x;
const my = point.y - touch.y;
const md = Math.sqrt(mx * mx + my * my);
const mf = Math.max(-layer.forceLimit, Math.min(layer.forceLimit, (mouseForce * touch.force) / md));
point.vx += mf * ((mx / md) || 0);
point.vy += mf * ((my / md) || 0);
}
point.vx *= layer.viscosity;
point.vy *= layer.viscosity;
point.x += point.vx;
point.y += point.vy;
}
for (let pointIndex = 0; pointIndex < points.length; pointIndex++) {
const prev = points[(pointIndex + points.length - 1) % points.length];
const point = points[pointIndex];
const next = points[(pointIndex + points.length + 1) % points.length];
const dPrev = this.distance(point, prev);
const dNext = this.distance(point, next);

const line = {
x: next.x - prev.x,
y: next.y - prev.y,
};
const dLine = Math.sqrt(line.x * line.x + line.y * line.y);

point.cPrev = {
x: point.x - (line.x / dLine) * dPrev * this.tension,
y: point.y - (line.y / dLine) * dPrev * this.tension,
};
point.cNext = {
x: point.x + (line.x / dLine) * dNext * this.tension,
y: point.y + (line.y / dLine) * dNext * this.tension,
};
}
}
}

animate() {
this.raf(() => {
this.update();
this.draw();
this.animate();
});
}

get svgWidth() {
return this.width + this.margin * 2;
}

get svgHeight() {
return this.height + this.margin * 2;
}

draw() {
for (let layerIndex = 0; layerIndex < this.layers.length; layerIndex++) {
const layer = this.layers[layerIndex];
if (layerIndex === 1) {
if (this.touches.length > 0) {
while (this.svgDefs.firstChild) {
this.svgDefs.removeChild(this.svgDefs.firstChild);
}
for (let touchIndex = 0; touchIndex < this.touches.length; touchIndex++) {
const touch = this.touches[touchIndex];
const gradient = document.createElementNS(this.xmlns, 'radialGradient');
gradient.id = 'liquid-gradient-' + this.id + '-' + touchIndex;
const start = document.createElementNS(this.xmlns, 'stop');
start.setAttribute('stop-color', this.color3);
start.setAttribute('offset', '0%');
const stop = document.createElementNS(this.xmlns, 'stop');
stop.setAttribute('stop-color', this.color2);
stop.setAttribute('offset', '100%');
gradient.appendChild(start);
gradient.appendChild(stop);
this.svgDefs.appendChild(gradient);
gradient.setAttribute('cx', touch.x / this.svgWidth);
gradient.setAttribute('cy', touch.y / this.svgHeight);
gradient.setAttribute('r', touch.force);
layer.path.style.fill = 'url(#' + gradient.id + ')';
}
} else {
layer.path.style.fill = this.color2;
}
} else {
layer.path.style.fill = this.color1;
}
const points = layer.points;
const commands = [];
commands.push('M', points[0].x, points[0].y);
for (let pointIndex = 1; pointIndex < points.length; pointIndex += 1) {
commands.push('C',
points[(pointIndex + 0) % points.length].cNext.x,
points[(pointIndex + 0) % points.length].cNext.y,
points[(pointIndex + 1) % points.length].cPrev.x,
points[(pointIndex + 1) % points.length].cPrev.y,
points[(pointIndex + 1) % points.length].x,
points[(pointIndex + 1) % points.length].y
);
}
commands.push('Z');
layer.path.setAttribute('d', commands.join(' '));
}
this.svgText.textContent = this.text;
this.svgText.style.fill = this.textColor;
}

createPoint(x, y) {
return {
x: x,
y: y,
ox: x,
oy: y,
vx: 0,
vy: 0,
};
}

initOrigins() {
this.svg.setAttribute('width', this.svgWidth);
this.svg.setAttribute('height', this.svgHeight);
for (let layerIndex = 0; layerIndex < this.layers.length; layerIndex++) {
const layer = this.layers[layerIndex];
const points = [];
for (let x = ~~(this.height / 2); x < this.width - ~~(this.height / 2); x += this.gap) {
points.push(this.createPoint(
x + this.margin,
this.margin
));
}
for (let alpha = ~~(this.height * 1.25); alpha >= 0; alpha -= this.gap) {
const angle = (Math.PI / ~~(this.height * 1.25)) * alpha;
points.push(this.createPoint(
Math.sin(angle) * this.height / 2 + this.margin + this.width - this.height / 2,
Math.cos(angle) * this.height / 2 + this.margin + this.height / 2
));
}
for (let x = this.width - ~~(this.height / 2) - 1; x >= ~~(this.height / 2); x -= this.gap) {
points.push(this.createPoint(
x + this.margin,
this.margin + this.height
));
}
for (let alpha = 0; alpha <= ~~(this.height * 1.25); alpha += this.gap) {
const angle = (Math.PI / ~~(this.height * 1.25)) * alpha;
points.push(this.createPoint(
(this.height - Math.sin(angle) * this.height / 2) + this.margin - this.height / 2,
Math.cos(angle) * this.height / 2 + this.margin + this.height / 2
));
}
layer.points = points;
}
}
}


const redraw = () => {
button.initOrigins();
};

const buttons = document.getElementsByClassName('btn0009_liquid');
for (let buttonIndex = 0; buttonIndex < buttons.length; buttonIndex++) {
const button = buttons[buttonIndex];
button.liquidButton = new LiquidButton(button);
}
</script>
Шаблон страницы
Код скопирован!
68259147
Нажми, чтобы скопировать номер
Текст скопирован в буфер обмена!
Текст скопирован в буфер обмена!
Текст скопирован в буфер обмена!
Вам также может быть интересно:
Pro подписка
Pro подписка
Модификации
Модификации
Модификации
Pro подписка
Подпишитесь на наши обновления в телеграм