How to fill text with particles using p5js - javascript

I want to fill a text with particles like this
I tried to do this using p5.js but I am stuck where the particles are only appearing on the edges. Any idea to accomplish this rather than having it on the edges?
Here is my attempt.
Thanks a ton in advance :)
SteeringDemo.html
<body>
<script>
var font;
var vehicles=[];
var x=1360;
var y=400;
function preload() {
font=loadFont('Poppins-Medium.ttf')
}
function setup() {
var canvasDiv = document.getElementById('canvas');
var width = canvasDiv.offsetWidth;
var sketchCanvas = createCanvas(width,450);
console.log(sketchCanvas);
sketchCanvas.parent("canvas");
background('#fff');
var points=font.textToPoints('B',x/3,y/2,240);
console.log(points);
for(i=0;i<points.length;i++){
var pt=points[i];
var vehicle = new Vehicle(pt.x, pt.y);
vehicles.push(vehicle);
}
}
function draw() {
background('#fff');
for(var i=0; i< vehicles.length;i++){
var v=vehicles[i];
v.behaviors();
v.update();
v.show();
}
}
</script>
<div class="container">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div id="canvas"></div>
</div>
</div>
</div>
</body>
Vehicle.js
function Vehicle(x,y) {
this.pos= createVector(random(width),random(height));
this.target=createVector(x,y);
this.vel= p5.Vector.random2D();
this.acc= createVector();
this.radius=8;
this.maxspeed=10;
this.maxForce=1;
}
Vehicle.prototype.behaviors=function () {
var arrive=this.arrive(this.target);
var mouse= createVector(mouseX,mouseY);
var flee=this.flee(mouse);
arrive.mult(1);
flee.mult(5);
this.applyForce(arrive);
this.applyForce(flee);
}
Vehicle.prototype.applyForce =function (f) {
this.acc.add(f);
}
Vehicle.prototype.update=function () {
this.pos.add(this.vel);
this.vel.add(this.acc);
this.acc.mult(0);
}
Vehicle.prototype.show=function () {
stroke('#0097a7');
strokeWeight(4);
point(this.pos.x,this.pos.y);
}
Vehicle.prototype.arrive= function (target) {
var desired=p5.Vector.sub(target,this.pos);
var d=desired.mag();
var speed=this.maxspeed;
if(d < 100) {
speed=map(d,0,100,0,this.maxspeed)
}
desired.setMag(speed);
var steer=p5.Vector.sub(desired,this.vel);
steer.limit(this.maxForce);
return steer;
}
Vehicle.prototype.flee= function (target) {
var desired=p5.Vector.sub(target,this.pos);
var d= desired.mag();
if(d <50) {
desired.setMag(this.maxspeed);
desired.mult(-1);
var steer=p5.Vector.sub(desired,this.vel);
steer.limit(this.maxForce);
return steer;
} else {
return createVector(0,0);
}
}

Though you could but, you don't have to use p5*js to achieve that animation. Fortunately, I've came across a javascript library called Particle Slider
and as it turns out, yalantis also using the same library for their animation.
Here is how you could accomplish such animation using that library.
let init = () => {
PS.renderText({
text: 'B',
fontFamily: 'Arial',
fontSize: 200,
fontColor: '#00E2FA',
fontWeight: 'bold'
});
var myPS = new ParticleSlider({
ptlGap: 3,
ptlSize: 1,
mouseForce: 70
});
window.onresize = () => {
myPS.width = window.innerWidth;
myPS.height = window.innerHeight;
}
}
window.onload = init;
html, body {
width: 100%;
height: 100%;
overflow: hidden;
background-color: black;
}
<script src="https://istack.000webhostapp.com/PS.js"></script>
<!-- DO NOT CHANGE ANYTHING AFTER THIS LINE -->
<div class="slides">
<div class="slide"> </div>
</div>
<canvas class="draw"></canvas>
<!-- DO NOT CHANGE ANYTHING BEFORE THIS LINE -->
Yes! It's really that easy :)
also, checkout a demo on jsFiddle
for future reference always refer to the official documentation

Related

How do I edit the styles of all divs with the same class using javascript?

I'm working on a website to contain my programming projects and such, that will grow as I get more skilled and make more things.
I'm implementing a dark mode button that I would like to target all divs with the class "mainBody" however, it currently only targets the one that the dark button is in. I've tried many solutions from stackoverflow and other sites that don't seem to work. Here is the code that only changes one instance:
function goingDark() {
document.getElementsByClassName("mainBody")[0].style.backgroundColor = "#242526";
document.getElementsByClassName("mainBody")[0].style.color = "#ffffff";
document.getElementsByClassName("h2")[0].style.color = "#ffffff";
}
function goingLight() {
document.getElementsByClassName("mainBody")[0].style.backgroundColor = "#ffffff";
document.getElementsByClassName("mainBody")[0].style.color = "#000000";
document.getElementsByClassName("h2")[0].style.color = "#000000";
}
I'm pretty new to Javascript, so any help is greatly appreciated!
document.querySelectorAll('.myclass').forEach(item => {
item.style.setProperty('padding-top', '0', 'important')
item.style.display = "none";
})
<div class="myclass">1</div>
<div class="myclass">2</div>
<div class="myclass">3</div>
You have to use querySelectorAll then iterate through the node list with forEach or forLoop or forOf.Possibilies are endless.Hope i could help
let mainBody = document.querySelectorAll(".mainBody")
let h2 = document.querySelectorAll("h2");
function goingDark() {
mainBody.forEach(element => {
element.style.backgroundColor = "#242526"
element.style.color = "#ffffff"
});
h2.forEach(element => {
element.style.backgroundColor = "#242526"
element.style.color = "#ffffff"
});
}
function goingLight() {
mainBody.forEach(element => {
element.style.backgroundColor = "#ffffff"
element.style.color = "#000000"
});
h2.forEach(element => {
element.style.backgroundColor = "#ffffff"
element.style.color = "#000000"
});
}
<body class="mainBody">
<h2>I am a h2</h2>
<button onclick="goingDark()">goingDark</button>
<button onclick="goingLight()">goingLight</button>
</body>
in html file :
<div class="myclass">1</div>
<div class="myclass">2</div>
<div class="myclass">3</div>
try like this in js file:
$("#myclass").addClass("mystyle");
// or this
$("#myclass").attr('style', 'padding-top: 0px !important');
// or this
$("#myclass").css("display","none");
and try this in css file:
#mystyle{
color:'red'
...
}
let m = document.getElementsByClassName("m");
let mi = document.getElementsByClassName("mi");
function goingDark() {
for ( i = 0; i < m.length; i++) {
m[i].style.backgroundColor = "#242526";
m[i].style.color = "#ffffff";
mi[i].style.color = "#ffffff";
}
}
function goingLight() {
for ( i = 0; i < m.length; i++) {
m[i].style.backgroundColor = "#ffffff";
m[i].style.color = "#000000";
mi[i].style.color = "#000000";
}
}
.m{
background: pink;
color : red;
border: 1px solid black;
margin: 5px;
}
<div class="m">
<h2 class="mi">something</h2>
<p>whatever you want here</p>
</div>
<div class="m">
<h2 class="mi">something</h2>
<p>whatever you want here</p>
</div>
<button onclick="goingDark()">dark</button>
<button onclick="goingLight()">light</button>
the issue is that when you select by classname in javascript it returns a html dom object list and this becomes what the styles are added to which is non existent so we have to iterate through it. you can use the foreach but then again its your choice.
hope this helps

JavasScript infinitive background change with function

I'm curious if there is a way to repeat a function for as long as user stays on the page. I want function f1() to repeat changing the color of div #gallery. It's probably an infinitive loop or something, please help me.
function f1() {
setTimeout(
function() {
document.getElementById("gallery").style.backgroundColor = "blue";
}, 3000);
setTimeout(
function() {
document.getElementById("gallery").style.backgroundColor = "red";
}, 6000);
}
#gallery {
width: 500px;
height: 300px;
background-color: red;
}
<body onload="f1()">
<div id="gallery">
</div>
</body>
The previous method of using setInterval is really great, but I personally like to have a little bit more control over what happens so I use something like this for repetition:
fiddle
The 'meat and bones' is a loop like this:
const target = document.getElementById('target');
const colors = ["red", "blue", "purple", "black", "gray", "aliceblue"];
const randomColor = () => {
const randomInt = Math.floor(Math.random() * colors.length + 1);
return colors[randomInt];
}
const userStillOnPage = true;
function f1(newInterval, continueWith) {
target.style.background = randomColor();
if (userStillOnPage) {
setTimeout(continueWith || f1, newInterval || 1000);
}
}
f1();
This method makes it easy to do all kinds of things like make the loop go faster by changing the interval or even injecting a different continuation function. It's quite powerful and easily abstracted to something very generic!
You can infinitely loop your javascript with setInterval:
<html>
<head>
<style>
#gallery {
width: 500px;
height: 300px;
background-color: red;
}
</style>
</head>
<body onload="f1()">
<div id="gallery">
</div>
</body>
<script type="text/javascript">
function f1(){
setInterval(oneSecondFunction, 9000);
};
function oneSecondFunction() {
setTimeout(
function() {
document.getElementById("gallery").style.backgroundColor = "blue";
}, 3000);
setTimeout(
function() {
document.getElementById("gallery").style.backgroundColor = "red";
}, 6000);
}
</script>
</html>
document.addEventListener('DOMContentLoaded', init);
function init() {
var target = document.getElementById('gallery');
setInterval(function() {
target.style.backgroundColor = getRandomColor();
}, 1000)
// From http://stackoverflow.com/questions/1484506/random-color-generator-in-javascript
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
}

How to tilt/rotate the item being dragged in javascript drag and drop?

I want to tilt an item being dragged to show distinction. I have basic drag and drop fiddle here https://jsfiddle.net/igaurav/bqprc9p8/3/
My javascript looks like:
"use strict";
var source = null;
function listItemDragStartHandler(event){
// What is true there for?
source = event.currentTarget;
event.dataTransfer.setData("text/plain", event.currentTarget.innerHTML);
event.currentTarget.style.transform = 'rotate(15deg)';
event.dataTransfer.effectAllowed = "move";
}
function dragoverHandler(event) {
event.preventDefault();
event.dataTransfer.dropEffect = "move";
}
function dropHandler(event) {
event.preventDefault();
event.stopPropagation();
var currentElement = event.currentTarget;
var listContainer = currentElement.parentNode;
listContainer.insertBefore(source, currentElement);
source.style.transform = 'rotate(0deg)';
}
function delete_item(event) {
var currentTarget = event.currentTarget;
var grandParentOfDelete = currentTarget.parentNode.parentNode;
grandParentOfDelete.remove();
}
function add_item() {
var item_text_node = document.getElementsByName("add-item-text")[0]
var item_text = item_text_node.value;
if (item_text.length > 0) {
var item_template = document.getElementById("item-template");
var item_clone = item_template.cloneNode(true);
item_clone.removeAttribute("id");
var clone_text = item_clone.getElementsByClassName("item-text")[0];
clone_text.textContent = item_text;
// reset the value
item_text_node.value = "";
var item_list = document.getElementById("item-list");
item_list.appendChild(item_clone);
} else {
alert("No text?? Add some text!");
}
}
function add_item_listener() {
var add_item_button = document.getElementById("add-item");
add_item_button.addEventListener("click", add_item);
}
function sample_data() {
for(var i=0;i<10;i++){
var item_text_node = document.getElementsByName('add-item-text')[0]
item_text_node.value = i;
add_item();
}
}
function init_app() {
add_item_listener();
sample_data();
}
window.onload = function () {
init_app()
}
Relevant HTML is:
<body>
<div id="container">
<div id="add-item-div">
<input type="text" name="add-item-text">
<button id="add-item">Add Item</button>
</div>
<div id="item-list">
</div>
<div id="item-template" class="item-list-element" draggable="true" ondragstart="listItemDragStartHandler(event);" ondrop="dropHandler(event);" ondragover="dragoverHandler(event);">
<div class="item-text"></div>
<div class="delete-item-div">
<button class="delete-item" onclick="delete_item(event);">Delete Item</button>
</div>
</div>
</div>
</body>
I am applying the transform on line 9 but the drag operation stops and drag doesn't start.
What am I doing wrong?
P.S: I don't want to use libraries.
Basically, we can use setDragImage for replacing the browser implementation of the ghost image it is rendering for the dragging operation, with one of our own.
We use a cloned node as you do in the fiddle, and we add it to the dom.
Then, you can do the transformation on an inner container in the cloned element.
document.getElementById("drag-with-create-add").addEventListener("dragstart", function(e) {
var crt = this.cloneNode(true);
crt.style.position = "absolute";
crt.style.top = "0px";
crt.style.left = "-100px";
var inner = crt.getElementsByClassName("inner")[0];
inner.style.backgroundColor = "orange";
inner.style.transform = "rotate(20deg)";
document.body.appendChild(crt);
e.dataTransfer.setDragImage(crt, 20, 20);
}, false);
<div id="drag-with-create-add" class="dragdemo" draggable="true">
<div class="inner">
drag me
</div>
</div>
This is partly based on an helpfull article by Stuart Langridge.
Note: Trick here is to apply transformation on inner element and not on the one which has drag events. Transformation would appear only if applied to inner elements.
I just created a sample fiddle. Which uses the setDragImage method, Please have a look and comment your needs so that we can upate the answer.
I have added a ghost image and added 'shake' feel while drag start. You can similarly rotate the dragging ghost image via css.
Also note, we are cloning the image while dragging to show ghost image. So we need to manually remove that from dom.
document.addEventListener("dragstart", function(e) {
var img = document.createElement("img");
img.src = "http://i.imgur.com/BDcvqmf.jpg";
e.dataTransfer.setDragImage(img, 5000, 5000); //5000 will be out of the window
drag(e)
}, false);
var crt, dragX, dragY;
//document.addEventListener('drag',drag)
function drag(ev) {
crt = ev.target.cloneNode(true);
crt.className = "face";
crt.style.position = "absolute";
crt.style.opacity = "0.9";
document.body.appendChild(crt);
ev.dataTransfer.setData("text", ev.target.id);
}
document.addEventListener("dragover", function(ev) {
ev = ev || window.event;
dragX = ev.pageX;
dragY = ev.pageY;
crt.style.left = dragX + "px";
crt.style.top = dragY + "px";
}, false);
document.addEventListener("dragend", function(event) {
crt.style.display = 'none';
crt.remove()
});
body {
padding: 10px
}
#draggable-element {
width: 100px;
height: 100px;
background-color: #666;
color: white;
padding: 10px 12px;
cursor: move;
position: relative;
/* important (all position that's not `static`) */
}
.face {
animation: shake 1s cubic-bezier(.36, .07, .19, .97) both;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
perspective: 1000px;
}
#keyframes shake {
10%,
90% {
transform: translate3d(-1px, 0, 0);
}
20%,
80% {
transform: translate3d(4px, 0, 0);
}
30%,
50%,
70% {
transform: translate3d(-5px, 0, 0);
}
40%,
60% {
transform: translate3d(5px, 0, 0);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
See the tilt in action on drag start. <br>
<img draggable id="draggable-element" src="http://i.imgur.com/BDcvqmf.jpg">

AngularJS - Display image on top of another image

I am sorry if my codes are messy. I am trying to display image on top of another image in Ionic AngularJS. Basically, when user clicks the "apply" button, it will display the image "toilet.png" on top of the image "PathFindingMap.png".
In my navigation.html, I have the following code snippet:
<button ng-click="apply()" type="button">Apply</button>
<div style="width: 627px; height:975px; background-image: url('img/PathFindingMap.png'); background-repeat: no-repeat; background-size:cover;">
</div>
<div ng-style="navigationStyleToilet[$index]" ng-repeat="o in arr"></div>
In my controller.js, I have the following code snippet:
.controller('NavigationCtrl', function ($scope, NavigationService) {
$scope.myCategory = {}
$scope.apply = function () {
$scope.arr = [];
var strCategoryName = "Washroom";
categoryInfo = NavigationService.fnGetCategoryInfo(strCategoryName);
$scope.navigationStyleToilet = [];
for (i = 0; i < categoryInfo.length; i++)
{
$scope.arr.push(i);
var targetImageX = categoryInfo[i].X;
var targetImageY = categoryInfo[i].Y;
$scope.navigationStyleToilet[i] = {
"z-index":"1",
"position":"absolute",
"width": "100px",
"height": "100px",
"top": targetImageY,
"left":targetImageX,
"background": "url('img/toilet.png')",
"background-repeat": "no-repeat",
}
}
}
})
In my servicesjs I have the following code snippet:
.factory('NavigationService', function () {
var ToiletCoordinates = new Array();
ToiletCoordinates[0] = { X: 16, Y: 100 };
return {
fnGetCategoryInfo: function (strCategoryName) {
if (strCategoryName == "All Booth") {
}
else if (strCategoryName == "Washroom") {
return ToiletCoordinates;
}
}
}
})
Unfortunately, the "toilet.png" image always display below the "PathFindingMap.png", regardless of the X and Y coordinates of the "toilet.png". I have tried many things but I still could not make the "toilet.png" displayed on top of the "PathFindingMap.png". It seems there is something wrong with my code. Can anyone tell me a way to make it work? Thanks!
You can do it with the help of CSS. To add image on the top of another image on button click, you can use ng-class attribute.
var app = angular.module("ap", []);
app.controller("con", function($scope) {
$scope.class = "imgagOnBottom";
$scope.changeClass = function() {
if ($scope.class === "imageOnBottom") $scope.class = "imageOnTop";
else $scope.class = "imageOnBottom";
};
});
.container {
position: relative;
}
.imageOnTop {
position: absolute;
width: 100px;
height: 100px;
border: 1px solid red;
}
.imageOnBottom {
/*whatever css you want.*/
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="ap" ng-controller="con">
<div class="container" style="background-image:'PathFindingImage.png';">
<img ng-class="class" / src="toliet.png">
</div>
<button ng-click="changeClass()">Change Class</button>
</body>

Pass paramaters to animate jquery function

I would like to pass paramaters in a custom function to animate specific parts. entirely not sure what im missing?
I've created a JsFiddle
function animate($class,$method,$value,$duration,$delay) {
var delay_time = 0;
$($class).each(function() {
$(this).delay(delay_time).animate({
$method : $value
}, {
duration: $duration
});
delay_time += $delay;
});
}
animate(".container","width", 100, 300, 250);
The $method is what im trying to pass, which for some reason just doesnt want to work? What am i missing?
Working Fiddle
You couldn't define an object as you do in {$method: $value}, But you could construct you object outside of animate method then just pass it :
var my_object = {};
my_object[$method]=$value;
$(this).delay(delay_time).animate(my_object,{duration: $duration});
Hope this helps.
function animate($class,$method,$value,$duration,$delay) {
var delay_time = 0;
$($class).each(function() {
var my_object = {};
my_object[$method]=$value;
$(this).delay(delay_time).animate(my_object,{duration: $duration});
delay_time += $delay;
});
}
animate(".container","width", 100, 300, 250);
.container {
opacity: 1;
width: 0;
background: #0f0;
height: 100px;
}
p {
margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<p>show me</p>
</div>
<div class="container">
<p>show me</p>
</div>

Categories

Resources