Path: blob/aarch64-shenandoah-jdk8u272-b10/nashorn/test/script/jfx/spread.js
32281 views
/*1* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* Testing JavaFX canvas run by Nashorn.25*26* @test/nocompare27* @run28* @fork29*/3031TESTNAME = "spread";3233var WIDTH = 800;34var HEIGHT = 600;35var canvas = new Canvas(WIDTH, HEIGHT);36var context = canvas.graphicsContext2D;3738/* "Spread" tech demo of canvas by Tom Theisen39*40* This will animate a sequence of branch structures in a canvas element.41* Each frame, a new direction is calculated, similar to the last frame.42*/4344var start_width = 20; // starting width of each branch45var frame_time = 30; // milliseconds per frame46var straighten_factor = 0.95; // value from 0 to 1, factor applied to direction_offset every frame47var curviness = 0.2; // amount of random direction change each frame4849var color_speed = 0.03; // speed at which colors change when cycling is enabled50var branch_shrink = 0.95; // factor by which branches shrink every frame51var min_width = 1; // minimum WIDTH for branch, after which they are discontinued52var branch_opacity = 0.4; // opacity of lines drawn53var branch_count = 3; // branch count per tree54var branch_bud_size = 0.5; // ratio of original branch size at which branch will split55var branch_bud_angle = 1; // angle offset for split branch;5657var paper; // reference to graphics context58var branches = Object(); // linked list of active branches59var color_styles = []; // pre-computed list of colors as styles. format: (r,g,b,a)60var direction_offset = 0; // current direction offset in radians. this is applied to all branches.61var frame = 0; // frame counter62var timespent = 0; // total time spent so far, used to calculate average frame render duration63var frameratespan; // html span element for updating performance number6465// preferences object, contains an attribute for each user setting66var prefs = {67wrap: true, // causes branches reaching edge of viewable area to appear on opposite side68fade: false, // fade existing graphics on each frame69cycle: true, // gradually change colors each frame70new_branch_frames: 20 // number of frames elapsed between each auto-generated tree71};7273// create tree at the specified position with number of branches74function create_tree(branches, start_width, position, branch_count) {75var angle_offset = Math.PI * 2 / branch_count;76for (var i = 0; i < branch_count; ++i) {77branch_add(branches, new Branch(position, angle_offset * i, start_width));78}79}8081// add branch to collection82function branch_add(branches, branch) {83branch.next = branches.next;84branches.next = branch;85}8687// get the coordinates for the position of a new tree88// use the center of the canvas89function get_new_tree_center(width, height) {90return {91x: 0.5 * width,92y: 0.5 * height93};94}9596// Branch constructor97// position has x and y properties98// direction is in radians99function Branch(position, direction, width) {100this.x = position.x;101this.y = position.y;102this.width = width;103this.original_width = width;104this.direction = direction;105}106107// update position, direction and width of a particular branch108function branch_update(branches, branch, paper) {109paper.beginPath();110paper.lineWidth = branch.width;111paper.moveTo(branch.x, branch.y);112113branch.width *= branch_shrink;114branch.direction += direction_offset;115branch.x += Math.cos(branch.direction) * branch.width;116branch.y += Math.sin(branch.direction) * branch.width;117118paper.lineTo(branch.x, branch.y);119paper.stroke();120121if (prefs.wrap) wrap_branch(branch, WIDTH, HEIGHT);122123if (branch.width < branch.original_width * branch_bud_size) {124branch.original_width *= branch_bud_size;125branch_add(branches, new Branch(branch, branch.direction + 1, branch.original_width));126}127}128129function draw_frame() {130if (prefs.fade) {131paper.fillRect(0, 0, WIDTH, HEIGHT);132}133134if (prefs.cycle) {135paper.setStroke(Paint.valueOf(color_styles[frame % color_styles.length]));136}137138if (frame++ % prefs.new_branch_frames == 0) {139create_tree(branches, start_width, get_new_tree_center(WIDTH, HEIGHT), branch_count);140}141142direction_offset += (0.35 + (frame % 200) * 0.0015) * curviness - curviness / 2;143direction_offset *= straighten_factor;144145var branch = branches;146var prev_branch = branches;147while (branch = branch.next) {148branch_update(branches, branch, paper);149150if (branch.width < min_width) {151// remove branch from list152prev_branch.next = branch.next;153}154155prev_branch = branch;156}157}158159// constrain branch position to visible area by "wrapping" from edge to edge160function wrap_branch(branch, WIDTH, HEIGHT) {161branch.x = positive_mod(branch.x, WIDTH);162branch.y = positive_mod(branch.y, HEIGHT);163}164165// for a < 0, b > 0, javascript returns a negative number for a % b166// this is a variant of the % operator that adds b to the result in this case167function positive_mod(a, b) {168// ECMA 262 11.5.3: Applying the % Operator169// remainder operator does not convert operands to integers,170// although negative results are possible171172return ((a % b) + b) % b;173}174175// pre-compute color styles that will be used for color cycling176function populate_colors(color_speed, color_styles, branch_opacity) {177// used in calculation of RGB values178var two_thirds_pi = Math.PI * 2 / 3;179var four_thirds_pi = Math.PI * 4 / 3;180var two_pi = Math.PI * 2;181182// hue does represent hue, but not in the conventional HSL scheme183for(var hue = 0; hue < two_pi; hue += color_speed) {184var r = Math.floor(Math.sin(hue) * 128 + 128);185var g = Math.floor(Math.sin(hue + two_thirds_pi) * 128 + 128);186var b = Math.floor(Math.sin(hue + four_thirds_pi) * 128 + 128);187color = "rgba(" + [r, g, b, branch_opacity].join() + ")";188189color_styles.push(color);190}191}192193// apply initial settings to canvas object194function setup_canvas() {195paper = canvas.graphicsContext2D;196paper.setFill(Paint.valueOf('rgb(0, 0, 0)'));197paper.fillRect(0, 0, WIDTH, HEIGHT);198paper.setFill(Paint.valueOf("rgba(0, 0, 0, 0.005)"));199paper.setStroke(Paint.valueOf("rgba(128, 128, 64, " + String(branch_opacity) + ")"));200}201202populate_colors(color_speed, color_styles, branch_opacity);203setup_canvas();204205var stack = new StackPane();206var pane = new BorderPane();207pane.setCenter(canvas);208stack.getChildren().add(pane);209$STAGE.scene = new Scene(stack);210var timer = new AnimationTimerExtend() {211handle: function handle(now) {212if (frame < 200) {213draw_frame();214} else {215checkImageAndExit();216timer.stop();217}218}219};220timer.start();221222223224