Skip to content

Instantly share code, notes, and snippets.

@monfera

monfera/.block

Last active Oct 11, 2016
Embed
What would you like to do?
500 points with one polyline
license: mit
height: 480

Uploaded from codepen.io/monfera/pen/oLoRgX with blockbuilder.org

This bl.ock shows

  • rendering of 500 points with just one <polyline> and a <marker> (to switch off line and haze, set <polyline> fill-opacity and stroke-width to zero)
  • styling of the marker with CSS
  • SVG attribute update without going through string serialization / parsing (due to a probable bug in Safari, it's much slower there than the string-based equivalent)
  • pseudo 3D transformation
  • proof that SVG rendering, unlike HTML element rendering, isn't GPU accelerated for transform: open Dev Tools, Rendering -> Paint Flashing shows green rectangles
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
svg * {
stroke: black;
}
#point line {
stroke-width: 2;
}
polyline {
fill-opacity: 0.01;
stroke-width: 0.05;
}
</style>
</head>
<body>
<svg width="960" height="480">
<defs>
<marker id="point"
viewBox="0 0 1 1"
refX="0" refY="0"
markerWidth="2"
markerHeight="2"
markerUnits="userSpaceOnUse">
<line x1="1"/>
</marker>
</defs>
<polyline id="p" marker-mid="url(#point)"/>
</svg>
<script>
var n = 1000
var i
function rand() {
return (
Math.random() +
Math.random() +
Math.random() +
Math.random() +
Math.random() +
Math.random()) / 3 - 1
}
var rot = -Math.PI / 12
var X = [], Y = [], Z = []
for(i = 0; i < n; i++) {
X.push(400 * rand())
Y.push(200 * rand())
Z.push(600 * rand())
}
var origPoints = [], points = []
for(i = 0; i < n; i++) {
origPoints.push([
480 + X[i] * Math.cos(rot) - Y[i] * Math.sin(rot),
240 + Y[i] * Math.cos(rot) + X[i] * Math.sin(rot)
])
}
// first we have to populate `points` via an attrib string
// because one can't unfortunately create an SVGPoint
p.setAttribute('points', origPoints.join(' '))
var svgPoints = []
for(i = 0; i < n; i++) {
svgPoints.push(p.points.getItem(i))
}
// we no longer set attributes to string values in the
// critical rAF loop
window.requestAnimationFrame(function render(t) {
rot = t / 1000
var cos = Math.cos(rot)
var sin = Math.sin(rot)
for(i = 0; i < n; i++) {
svgPoints[i].x = 480 + X[i] * cos - Z[i] * sin
}
window.requestAnimationFrame(render)
})
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment