$cache[$key] = empty($arr) ? NULL : $arr; return $cache[$key]; } // 门户 获取需要在频道显示的栏目主题数据 function portal_channel_thread($fid) { global $forumlist; if (empty($fid)) return NULL; $orderby = array('tid' => 1); $page = 1; // 遍历所有在频道显示内容的栏目 $category_forumlist = channel_category($fid); $arrlist = array(); $forum_tids = array(); $tidlist = array(); if ($category_forumlist) { foreach ($category_forumlist as &$_forum) { // 频道显示数据 $arrlist['list'][$_forum['fid']] = array( 'fid' => $_forum['fid'], 'name' => $_forum['name'], 'rank' => $_forum['rank'], 'type' => $_forum['type'], 'url' => $_forum['url'], 'channel_new' => $_forum['channel_new'], ); $forum_thread = thread_tid__find(array('fid' => $_forum['fid']), $orderby, $page, $_forum['channel_new'], 'tid', array('tid')); // 最新信息按栏目分组 foreach ($forum_thread as $key => $_thread) { $forum_tids[$key] = $_thread; } unset($forum_thread); } $tidlist += $forum_tids; } unset($category_forumlist); // 获取属性对应的tid集合 list($flaglist, $flagtids) = flag_thread_by_fid($fid); empty($flagtids) || $tidlist += $flagtids; unset($flagtids); // 频道置顶 $stickylist = sticky_list_thread($fid); empty($stickylist) || $tidlist += $stickylist; // 在这之前合并所有二维数组 tid值为键/array('tid值' => tid值) $tidarr = arrlist_values($tidlist, 'tid'); // 在这之前使用$tidarr = array_merge($tidarr, $arr)前合并所有一维数组 tid/array(1,2,3) if (empty($tidarr)) { $arrlist['list'] = isset($arrlist['list']) ? array_multisort_key($arrlist['list'], 'rank', FALSE, 'fid') : array(); return $arrlist; } $tidarr = array_unique($tidarr); $pagesize = count($tidarr); // 遍历获取的所有tid主题 $threadlist = well_thread_find_asc($tidarr, $pagesize); // 遍历时为升序,翻转为降序 $threadlist = array_reverse($threadlist); foreach ($threadlist as &$_thread) { // 各栏目最新内容 isset($forum_tids[$_thread['tid']]) AND $arrlist['list'][$_thread['fid']]['news'][$_thread['tid']] = $_thread; // 全站置顶内容 isset($stickylist[$_thread['tid']]) AND $arrlist['sticky'][$_thread['tid']] = $_thread; // 首页属性主题 if (!empty($flaglist)) { foreach ($flaglist as $key => $val) { if (isset($val['tids']) && in_array($_thread['tid'], $val['tids'])) { $arrlist['flaglist'][$key][array_search($_thread['tid'], $val['tids'])] = $_thread; ksort($arrlist['flaglist'][$key]); $arrlist['flag'][$_thread['tid']] = $_thread; } } } } unset($threadlist); if (isset($arrlist['sticky'])) { $i = 0; foreach ($arrlist['sticky'] as &$val) { ++$i; $val['i'] = $i; } } if (isset($arrlist['flag'])) { $i = 0; foreach ($arrlist['flag'] as &$val) { ++$i; $val['i'] = $i; } } if (isset($arrlist['flaglist'])) { foreach ($arrlist['flaglist'] as &$val) { $i = 0; foreach ($val as &$v) { ++$i; $v['i'] = $i; } } } isset($arrlist['list']) AND $arrlist['list'] = array_multisort_key($arrlist['list'], 'rank', FALSE, 'fid'); return $arrlist; } ?>javascript - Speed up the drawing of many points on a HTML5 canvas element - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Speed up the drawing of many points on a HTML5 canvas element - Stack Overflow

programmeradmin1浏览0评论

I need to draw a lot of points on a HTML5 canvas, and it is taking pretty long. My code looks like this:

var points = getPoints() // Array of {x,y,color}
var ctx = canvas.getContext("2d");

for (var i = 0; i < points.length; i++) {
   ctx.fillStyle = points[i].color
   ctx.beginPath()
   ctx.arc(points[i].x, points[i].y, radius, 0, Math.PI * 2, true)
   ctx.fill() }

I am wondering what performance tweaks I could do to speed this up. I only have 5 different colors. For example, would I benefit form sorting the points list on-the-fly to change ctx.fillStyle only 5 times instead of one time per point?

I need to draw a lot of points on a HTML5 canvas, and it is taking pretty long. My code looks like this:

var points = getPoints() // Array of {x,y,color}
var ctx = canvas.getContext("2d");

for (var i = 0; i < points.length; i++) {
   ctx.fillStyle = points[i].color
   ctx.beginPath()
   ctx.arc(points[i].x, points[i].y, radius, 0, Math.PI * 2, true)
   ctx.fill() }

I am wondering what performance tweaks I could do to speed this up. I only have 5 different colors. For example, would I benefit form sorting the points list on-the-fly to change ctx.fillStyle only 5 times instead of one time per point?

Share Improve this question asked Dec 17, 2012 at 14:30 NicolasNicolas 2,3673 gold badges30 silver badges44 bronze badges 10
  • I think this is a pretty slow line: ctx.arc(points[i].x, points[i].y, radius, 0, Math.PI * 2, true) Try drawing simple rectangles, and see if that speeds it up. (IMHO, it should...) – ppeterka Commented Dec 17, 2012 at 14:33
  • 1 I tried it and yes, it does speed up. I don't see how that helps however. – Nicolas Commented Dec 17, 2012 at 14:40
  • 1 I think if you set up a fiddle it would be easier for people to tweak it, here's some modifications I can think of to make it a little faster (maybe) -> FIDDLE ... – adeneo Commented Dec 17, 2012 at 14:42
  • @Stewie drawing an arc needs a lot of computation. Filling a rectangle is a lot simpler... – ppeterka Commented Dec 17, 2012 at 14:44
  • How many is "many", and how long is "pretty long" ? – Alnitak Commented Dec 17, 2012 at 14:44
 |  Show 5 more comments

1 Answer 1

Reset to default 17

For example, would I benefit form sorting the points list on-the-fly to change ctx.fillStyle only 5 times instead of one time per point?

In my experience, yes - changing .fillStyle frequently is quite expensive.

I had code that was plotting a large number of rectangles in a canvas and the time to plot rectangles with only two infrequently varying colours was significantly better than plotting with many frequently changing colours.

Anyhow, since you only have five different colours:

  1. Create an off-screen canvas into which you can draw five circles
  2. Use .drawImage() to blit the right colour circle into your destination canvas without having to recalculate the arc coordinates
  3. Assign points[i] to an local variable inside the loop to avoid dereferencing it over and over.

On my laptop this code is drawing 3000 circles on a 400x400 canvas in 7 milliseconds:

var colours = ['red', 'green', 'blue', 'yellow', 'magenta'];
var n = colours.length;
var r = 10;
var d = r * 2;

var off = document.createElement('canvas');
off.width = n * d;
off.height = d;
var ctx = off.getContext('2d');  

for (var i = 0; i < n; ++i) {
    ctx.fillStyle = colours[i];
    ctx.beginPath();
    ctx.arc(i * d + r, r, r, 0, 2 * Math.PI);
    ctx.closePath();
    ctx.fill();
}

var canvas = document.getElementById('canvas');
var ctx2 = canvas.getContext('2d');
var t0 = Date.now();
for (var i = 0; i < 3000; ++i) {
    var c = Math.floor(n * Math.random());
    var x = Math.floor(canvas.width * Math.random());
    var y = Math.floor(canvas.height * Math.random());
    ctx2.drawImage(off, c * d, d, d, x - r, y - r, d, d);
}
var t1 = Date.now();
alert((t1 - t0) + "ms");

​See http://jsfiddle.net/alnitak/Dpgts/

发布评论

评论列表(0)

  1. 暂无评论