I've implemented a canvas element with a javascript particle effect. The effect is working on every browser but IOS/Safari. I've done a bit of research and IOS/Safari supports HTML5/Canvas: According to Browser Support Charts for HTML5/Canvas
$(function() {
var WIDTH = window.innerWidth * .9,
HEIGHT = window.innerHeight,
MAX_PARTICLES = 100,
DRAW_INTERVAL = 60,
canvas = document.querySelector('#pixies'),
context = canvas.getContext('2d'),
gradient = null,
pixies = new Array();
function setDimensions() {
WIDTH = window.outerWidth;
HEIGHT = window.innerHeight;
canvas.width = WIDTH;
canvas.height = HEIGHT;
}
setDimensions();
window.addEventListener('resize', setDimensions);
function Circle() {
this.settings = {ttl:8000, xmax:5, ymax:2, rmax:10, rt:1, xdef:960, ydef:540, xdrift:4, ydrift: 4, random:true, blink:true};
this.reset = function() {
this.x = (this.settings.random ? WIDTH*Math.random() : this.settings.xdef);
this.y = (this.settings.random ? HEIGHT*Math.random() : this.settings.ydef);
this.r = ((this.settings.rmax-1)*Math.random()) + 1;
this.dx = (Math.random()*this.settings.xmax) * (Math.random() < .5 ? -1 : 1);
this.dy = (Math.random()*this.settings.ymax) * (Math.random() < .5 ? -1 : 1);
this.hl = (this.settings.ttl/DRAW_INTERVAL)*(this.r/this.settings.rmax);
this.rt = Math.random()*this.hl;
this.settings.rt = Math.random()+1;
this.stop = Math.random()*.2+.4;
this.settings.xdrift *= Math.random() * (Math.random() < .5 ? -1 : 1);
this.settings.ydrift *= Math.random() * (Math.random() < .5 ? -1 : 1);
}
this.fade = function() {
this.rt += this.settings.rt;
}
this.draw = function() {
if(this.settings.blink && (this.rt <= 0 || this.rt >= this.hl)) {
this.settings.rt = this.settings.rt*-1;
} else if(this.rt >= this.hl) {
this.reset();
}
var newo = 1-(this.rt/this.hl);
context.beginPath();
context.arc(this.x, this.y, this.r, 0, Math.PI*2, true);
context.closePath();
var cr = this.r*newo;
gradient = context.createRadialGradient(this.x, this.y, 0, this.x, this.y, (cr <= 0 ? 1 : cr));
gradient.addColorStop(0.0, 'rgba(255,255,255,'+newo+')');
gradient.addColorStop(this.stop, 'rgba(255,255,255,'+(newo*.6)+')');
gradient.addColorStop(1.0, 'rgba(255,255,255,0)');
context.fillStyle = gradient;
context.fill();
}
this.move = function() {
this.x += (this.rt/this.hl)*this.dx;
this.y += (this.rt/this.hl)*this.dy;
if(this.x > WIDTH || this.x < 0) this.dx *= -1;
if(this.y > HEIGHT || this.y < 0) this.dy *= -1;
}
this.getX = function() { return this.x; }
this.getY = function() { return this.y; }
}
for (var i = 0; i < MAX_PARTICLES; i++) {
pixies.push(new Circle());
pixies[i].reset();
}
function draw() {
context.clearRect(0, 0, WIDTH, HEIGHT);
for(var i = 0; i < pixies.length; i++) {
pixies[i].fade();
pixies[i].move();
pixies[i].draw();
}
}
setInterval(draw, DRAW_INTERVAL);
});
#particles {
position: absolute;
background: navy;
width: 200px;
height: 200px;
}
<script src=".1.1/jquery.min.js"></script>
<div id="particles">
<canvas id="pixies"></canvas>
</div>
I've implemented a canvas element with a javascript particle effect. The effect is working on every browser but IOS/Safari. I've done a bit of research and IOS/Safari supports HTML5/Canvas: According to Browser Support Charts for HTML5/Canvas
$(function() {
var WIDTH = window.innerWidth * .9,
HEIGHT = window.innerHeight,
MAX_PARTICLES = 100,
DRAW_INTERVAL = 60,
canvas = document.querySelector('#pixies'),
context = canvas.getContext('2d'),
gradient = null,
pixies = new Array();
function setDimensions() {
WIDTH = window.outerWidth;
HEIGHT = window.innerHeight;
canvas.width = WIDTH;
canvas.height = HEIGHT;
}
setDimensions();
window.addEventListener('resize', setDimensions);
function Circle() {
this.settings = {ttl:8000, xmax:5, ymax:2, rmax:10, rt:1, xdef:960, ydef:540, xdrift:4, ydrift: 4, random:true, blink:true};
this.reset = function() {
this.x = (this.settings.random ? WIDTH*Math.random() : this.settings.xdef);
this.y = (this.settings.random ? HEIGHT*Math.random() : this.settings.ydef);
this.r = ((this.settings.rmax-1)*Math.random()) + 1;
this.dx = (Math.random()*this.settings.xmax) * (Math.random() < .5 ? -1 : 1);
this.dy = (Math.random()*this.settings.ymax) * (Math.random() < .5 ? -1 : 1);
this.hl = (this.settings.ttl/DRAW_INTERVAL)*(this.r/this.settings.rmax);
this.rt = Math.random()*this.hl;
this.settings.rt = Math.random()+1;
this.stop = Math.random()*.2+.4;
this.settings.xdrift *= Math.random() * (Math.random() < .5 ? -1 : 1);
this.settings.ydrift *= Math.random() * (Math.random() < .5 ? -1 : 1);
}
this.fade = function() {
this.rt += this.settings.rt;
}
this.draw = function() {
if(this.settings.blink && (this.rt <= 0 || this.rt >= this.hl)) {
this.settings.rt = this.settings.rt*-1;
} else if(this.rt >= this.hl) {
this.reset();
}
var newo = 1-(this.rt/this.hl);
context.beginPath();
context.arc(this.x, this.y, this.r, 0, Math.PI*2, true);
context.closePath();
var cr = this.r*newo;
gradient = context.createRadialGradient(this.x, this.y, 0, this.x, this.y, (cr <= 0 ? 1 : cr));
gradient.addColorStop(0.0, 'rgba(255,255,255,'+newo+')');
gradient.addColorStop(this.stop, 'rgba(255,255,255,'+(newo*.6)+')');
gradient.addColorStop(1.0, 'rgba(255,255,255,0)');
context.fillStyle = gradient;
context.fill();
}
this.move = function() {
this.x += (this.rt/this.hl)*this.dx;
this.y += (this.rt/this.hl)*this.dy;
if(this.x > WIDTH || this.x < 0) this.dx *= -1;
if(this.y > HEIGHT || this.y < 0) this.dy *= -1;
}
this.getX = function() { return this.x; }
this.getY = function() { return this.y; }
}
for (var i = 0; i < MAX_PARTICLES; i++) {
pixies.push(new Circle());
pixies[i].reset();
}
function draw() {
context.clearRect(0, 0, WIDTH, HEIGHT);
for(var i = 0; i < pixies.length; i++) {
pixies[i].fade();
pixies[i].move();
pixies[i].draw();
}
}
setInterval(draw, DRAW_INTERVAL);
});
#particles {
position: absolute;
background: navy;
width: 200px;
height: 200px;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="particles">
<canvas id="pixies"></canvas>
</div>
Any ideas why this isn't working in IOS/Safari? The actual site in question is this one: www.pjmaskslive.
Share Improve this question edited May 15, 2017 at 21:42 Joel Hoelting asked May 15, 2017 at 20:39 Joel HoeltingJoel Hoelting 1,9923 gold badges26 silver badges45 bronze badges 8- An actual look at the developer console might help. Any errors? Also, it's generally a good idea to pay attention to the "known issues" tab on the caniuse site! Sidenote:<troll>Who cares for Safari?</troll> – Christoph Commented May 15, 2017 at 20:42
-
There are some rumblings about Safari not playing nicely with Canvas on stackoverflow (ex. it seems like
.bind()
isn't supported). I have no instances ofbind()
anywhere. It's working on desktop-based (OSX) Safari, just not IOS/Safari. Just curious why this is happening. – Joel Hoelting Commented May 15, 2017 at 20:56 - The above snippet runs fine for me in Safari on iOS 10.3.2 – Lennart Commented May 15, 2017 at 21:08
- @LennartHase: would you mind trying this site on IOS/Safari? pjmaskslive. – Joel Hoelting Commented May 15, 2017 at 21:15
- @JoelB Okay, not working on the site you linked, however, there are also no errors or warnings in the console, curious... – Lennart Commented May 15, 2017 at 21:20
2 Answers
Reset to default 3The issue appears to be that the canvas elements width is set 0 on the aforementioned website. So I would assume that the issue is setting the WIDTH
variable at the start. This might be due to an ongoing bug with iOS 10 as mentioned in this question.
An alternative approach might be to use document.body.getBoundingClientRect().width
as an alternative to window.innerWidth
and/or window.outerWidth
. screen.width
could also be used, however, these could also have the same issues as your previous methods.
Seems like a safari issue rather than your code either way!
This is the fix I used for my project. the code was more than this but the idea was that I wanted to draw on an office plan as a navigating app for workers and I finished the project and it ran perfectly on Android, but did not run on iOS, so I used the navigator.platform
method, then set the canvas size based on the platform
if (/iPad|iPhone|iPod|MacIntel/.test(navigator.platform)) {
const maxWidth = 5400; // Maximum width
canvas.width = Math.min(maxWidth, document.body.getBoundingClientRect().width || window.innerWidth || screen.width);
const aspectRatio = image.width / image.height;
canvas.height = canvas.width / aspectRatio;
document.querySelector('.devicename').innerHTML =
`${navigator.platform}\s
width ${canvas.width} height: ${canvas.height}\s
image height: ${image.height} image width: ${image.width}\s
device height: ${window.innerHeight || screen.height} width : ${window.innerWidth || screen.width}`;
}
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);