Skip to content

Instantly share code, notes, and snippets.

@trentb-daycos
Created June 11, 2025 19:34
Show Gist options
  • Save trentb-daycos/681e383fa66afea9cbad5f0e83bb8c03 to your computer and use it in GitHub Desktop.
Save trentb-daycos/681e383fa66afea9cbad5f0e83bb8c03 to your computer and use it in GitHub Desktop.
Gas welding SVG effect
<svg id="snap"></svg>
<canvas id="canvas"></canvas>
/*
animation example https://www.youtube.com/watch?v=OTfuQUyl0L0
svg path animation example https://codepen.io/mattsince87/pen/snqLy/?editors=001
svg decoration example http://css.yoksel.ru/svg-decoration/
*/
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
// 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);
};
}());
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
function GasWelding() {
this.speed = 5000;
this.filters = {};
this.init();
};
GasWelding.prototype = {
init: function() {
this.paper = Snap("#snap");
this.paper.attr({
width: 500,
height: 600
});
},
draw: function() {
var s = this.paper;
s.clear();
this.filters.shadow = s.filter(Snap.filter.shadow(0, 0, 5, '#FFA319'));
this.filters.blurS = s.filter(Snap.filter.blur(1, 1));
this.filters.blurM = s.filter(Snap.filter.blur(4, 4));
var pathL = "M 90 50 L 120 50 L 180 60 L 180 120 L 120 180 L 60 180 L 50 120 L 50 60 Z";
this.outerL = s.path(pathL).attr({
fill: 'none',
stroke: '#FF4719',
strokeWidth: 10,
filter: this.filters.blurM
});
this.innerL = s.path(pathL).attr({
fill: 'none',
stroke: '#FFFF19',
strokeWidth: 5,
filter: this.filters.blurS
});
this.dotL = s.circle(90, 50, 8).attr({
fill: 'yellow',
filter: this.filters.blurM
});
},
animateDot: function() {
var that = this;
that.dotL.animate({
r: 12
}, 100, mina.linear, function() {
that.dotL.animate({
r: 8
}, 100, mina.linear, function(){
that.animateDot();
});
});
},
dropSpark: function(startX, startY) {
var s = this.paper;
var spark = s.circle(startX, startY, 4).attr({
fill: 'yellow',
filter: this.filters.blurS
});
spark.animate({
cx: getRandomInt(10, 300),
cy: 550,
opacity: 0
}, 3000, mina.linear, function() {
spark.remove();
});
},
animatePath: function(path, speed, dot) {
var s = this.paper;
var len = path.getTotalLength();
var obj = this;
var step = len / 100;
var d = 0;
path.attr({
"stroke-dasharray": len,
"stroke-dashoffset": len
});
path.animate({
"stroke-dashoffset": 0
}, speed, mina.linear);
if (dot && s) {
Snap.animate(0, len, function(value) {
var movePoint = path.getPointAtLength(value);
dot.attr({
cx: movePoint.x,
cy: movePoint.y
});
if (value > d) {
obj.dropSpark(movePoint.x, movePoint.y);
d += step;
}
}, speed, mina.linear, function(){
dot.remove();
});
}
},
run: function() {
this.draw();
this.animatePath(this.innerL, this.speed, this.dotL);
this.animatePath(this.outerL, this.speed);
this.animateDot();
}
}
window.onload = function() {
var gasWelding = new GasWelding();
var gui = new dat.GUI();
gui.add(gasWelding, 'speed', 0, 10000);
gui.add(gasWelding, 'run');
};
/*window.onload = function() {
// Initialise an empty canvas and place it on the page
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
canvas.width = 800;
canvas.height = 380;
document.body.appendChild(canvas);
// Inital starting position
var posX = 20,
posY = canvas.height / 2;
// No longer setting velocites as they will be random
// Set up object to contain particles and set some default values
var particles = {},
particleIndex = 0,
settings = {
density: 20,
particleSize: 10,
startingX: canvas.width / 2,
startingY: canvas.height / 4,
gravity: 0.5
};
// Set up a function to create multiple particles
function Particle() {
// Establish starting positions and velocities
this.x = settings.startingX;
this.y = settings.startingY;
// Determine original X-axis speed based on setting limitation
this.vx = Math.random() * 20 - 10;
this.vy = Math.random() * 20 - 5;
// Add new particle to the index
// Object used as it's simpler to manage that an array
particleIndex ++;
particles[particleIndex] = this;
this.id = particleIndex;
this.life = 0;
this.maxLife = 100;
}
// Some prototype methods for the particle's "draw" function
Particle.prototype.draw = function() {
this.x += this.vx;
this.y += this.vy;
// Adjust for gravity
this.vy += settings.gravity;
// Age the particle
this.life++;
// If Particle is old, it goes in the chamber for renewal
if (this.life >= this.maxLife) {
delete particles[this.id];
}
// Create the shapes
context.clearRect(settings.leftWall, settings.groundLevel, canvas.width, canvas.height);
context.beginPath();
context.fillStyle="#ffffff";
// Draws a circle of radius 20 at the coordinates 100,100 on the canvas
context.arc(this.x, this.y, settings.particleSize, 0, Math.PI*2, true);
context.closePath();
context.fill();
}
setInterval(function() {
context.fillStyle = "rgba(10,10,10,0.8)";
context.fillRect(0, 0, canvas.width, canvas.height);
// Draw the particles
for (var i = 0; i < settings.density; i++) {
if (Math.random() > 0.97) {
// Introducing a random chance of creating a particle
// corresponding to an chance of 1 per second,
// per "density" value
new Particle();
}
}
for (var i in particles) {
particles[i].draw();
}
}, 30);
};*/
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.0/TimelineMax.min.js"></script>
body {
background-color: black;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment